How i can create Off screen target indicator?

Hello,

I have player and entity position. I want to show arrow indicator on screen when enemy is off screen…

image
As you can see this image how i can implement off screen target indicator in playcanvas?

1 Like

You could try and use the lookAt API on the arrow, pointing it towards your enemy entity using the aforementioned entity position.
From the API reference -

// Look at another entity, using the (default) positive y-axis for up
var position = otherEntity.getPosition();
this.entity.lookAt(position);

// Look at another entity, using the negative world y-axis for up
var position = otherEntity.getPosition();
this.entity.lookAt(position, pc.Vec3.DOWN);
1 Like

Thanks @DevilZ for trying to help.

But my concern is not look at…

How i can keep that blue arrow indicator at the edge of screen as shown in image, only visible if target enemy is off screen…

1 Like

So lookAt should get your arrow pointing the right way at least. You’ll then need to detect whether the enemy is in a particular x and y range of the player. If it’s not, then it’s safe to assume that the enemy is off the screen, and you could move the arrow as close to the enemy as possible while also remaining in said range of player so as to ensure that the arrow remains in screen.

1 Like

Thanks to this script, checks entity is visible to camera or not

But i am still looking for way to implement blue indicator within the screen space…
Anyone can help?

Edit:
My issue is solved…

Thanks to this as well…
https://forum.playcanvas.com/t/solved-how-to-get-top-vec3-point-and-bottom-vec3-point-of-users-screen/

Added added blue indicator as well by following way…
I added four entities as child in camera, According to Camera View Edge…
e.g. topPointEntity, rightPointEntity, bottomPointEntity, leftPointEntity

Get position of target then clamped it using topPointEntity, rightPointEntity, bottomPointEntity, leftPointEntity and then set it on blue indicator.

Which helped me to keep the blue indicator within screen space…

4 Likes

Interesting question and thanks for explaining your solution! I Maybe you can share a small example project because it’s not fully clear to me and I like to use this in my game too! :see_no_evil:

1 Like

@Albertos
Here is a quick example project… And not optimized… :no_mouth:
https://playcanvas.com/editor/scene/1095642
As my game camera is in fixed direction. So it worked for my 2d style game…

Here you can control green box (Player) with WSAD keys.(Try to move out of screen, you will see indicator.)
Blue box some are static and one blue box with tween animation.
Four white dot indicate screen space area…which help to keep indicator inside…

I dont think it will work for any 3d… 360 degree view game… :disappointed:

2 Likes

Hi @Ketan_ATA! Thanks a lot to make this sample project.
I will see if I can make something similar for a 3D game.

2 Likes

I try to make a custom target indicator so that it’s working for a 3D scene. I write therefore the code below. This works good until I implant the script in my own game where the player can rotate the camera. Then the 2D screen position from the target in 3D space is setting from a negative value to a positive value. The result is that the target indicator flips to the wrong side of the screen. I know it is difficult, but I hope someone understand what I’m doing and see whats wrong.

    // Target leaving the screen on top
    if (screenPos.y < this.entity.element.height) {
        posY = (device.height - this.entity.element.height) / scale;
    } 
    
    // Target leaving the screen on bottom
    else if (screenPos.y > device.height) {
        posY = this.entity.element.height - scale;
    } 
    
    // Target is on screen
    else {
        posY = (device.height - screenPos.y) / scale;
        visibleY = true; 
    }
    
    // Target leaving the screen on left side
    if (screenPos.x < this.entity.element.width) {
        posX = this.entity.element.width - scale;
    } 
    
    // Target leaving the screen on right side
    else if (screenPos.x > device.width) {
        posX = (device.width - this.entity.element.width) / scale;
    } 
    
    // Target is on screen
    else {
        posX = screenPos.x / scale;
        visibleX = true;
    }

Point where the indicator flips to the wrong side of the screen when rotating the camera:

image
console.log(screenPos.x);

1 Like

You should try to implement the math without going to screen space … as screenspace only works for objects in front of the camera, but not behind. Use world space, and only final position try to convert to screen space.

1 Like

@Albertos Maybe lexxik’s project can help…
https://playcanvas.com/project/771954/overview/world-to-ui-screen-space-2

I’ve seen the project but unfortunately it doesn’t solve this case. Thanks anyway!