Indicator point to target object

Hello Unreal friends!

I’m more comfortable with the art side of the engine, so I always struggle with stuff like this - any help would be lovely!

I’m prototyping an arrow (mesh) that will appear above the players head and point to the objective. I have a working version of this, however, the problem is that the target that I would like the arrow to point toward can only be set in the level by making a selection:

The problem with this is:

  1. I’d like to nest this arrow in all player blueprints (seems easy) AND
  2. The object I’d like to target is our Game Ball - and our game ball is inside of a blueprint all it’s own.

Here’s my current blueprint for the indicator arrow:

So - I’d like to get the world location of my Game Ball mesh but that’s located in it’s very own blueprint. I have no clue how to retrieve it’s location and, even if what I’d like to do is possible?

Any thoughts on this? Thanks so much in advance!

1 Like

I will also say, this is a prototype that I’m not even sure I’ll end up using.

I have found little information about how to get an “interface” arrow to point to something offscreen…This is essentially what I’m looking to do.

Perhaps the most obvious and most intuitive ways to get a specific actor via Blueprint are these two nodes:
Get All Actors of Class
and
Get All Actors with Tag.

If using Get All Actors of Class, you would pick the specific class/blueprint that your Game Ball uses. If using Get All Actors with Tag, you would need to add an identifying tag to your Game Ball blueprint and type that in to direct the search.

Both of these nodes return an array of actor references, regardless of how many matches they find (even if it’s just one match). So you’ll have to loop over the array, or pick a specific item from it (probably index 0, the first match) to access the one specific Game Ball actor you want to point the indicator toward.

Also, whichever node you choose, I suggest calling it up during the BeginPlay event, and storing the found Game Ball actor in a new variable. This way, you only need to call up the search function once, which helps with efficiency. You’d then have an Actor variable that you can subsequently access anytime you need to update the indicator’s rotation to match the ball’s current (and presumably always-changing) location.

Finally, speaking of updating, in your attached screenshots, I think you’ve made a mistake by connecting the look-at logic to the “Construction Script” event node. This only gets fired once, when the object is constructed. It seems to me that this look-at update logic needs to happen every frame, so you’ll probably need to hook it up to the Tick event instead.

Hope that makes sense!

1 Like

Forgot to include a link to this really helpful article from the official docs that very clearly shows how to use the Get All Actors of Class node, along with some other valuable tips.

Best of luck!

Agreed, remove this from the construction script, put it in the event graph or a function you call frequently using a timer, or tick or a timeline etc. Have it find the look at rotation and update as desired. Get all actors of class node will work especially if you only have 1 ball in the level, alternatively if it is a ball that isn’t spawned into the level but placed and always exists you could give it a hard reference in the editor details panel by creating a variable of type “ball BP” and exposing it to be instance editable. This will allow you to select the object from within the level and create a reference that way.

HOW CAN I KISS YOU BOTH?!

Seriously, thanks so much for the response. I was able to figure it out!

Here’s my pointer BP, which is nested in each players BP:

I guess while we’re all here:

Is getting the arrow to align to screen edges much more complex? Having an arrow above the head is a little obstructive. Not sure if that’s a different system entirely, maybe some kind of interface/2D element instead.

If there’s a link on how to do something like that, or thoughts on how to accomplish it, I’m completely open to your wonderful insight!

<3,
-Jon

Here’s how I imagine that might be done.

  1. First, determine whether the Game Ball actor is directly in the view of the player (i.e. within the camera’s view frustum)
  2. If ball is in view, hide the “off-screen indicator” widget; if not, show the “off-screen indicator” widget
  3. If the “off-screen indicator” widget is shown, update its position in screen space to put it along the side of the screen that represents where the ball is; also do 2D rotation (since it’s an arrow, it needs to point further off-screen), plus 2D scaling (to optionally scale up or down the widget to help indicate how far off-screen the ball is), and maybe even change opacity (also optional for indicating how far off-screen the ball is)

I started to write a more complicated answer for how to solve the first step, but thankfully I realized there’s an easier way: the Project World to Screen node.

Using that node, you can get a FVector2D variable (the screen space coordinate) that you can do some checks on to find out whether the Game Ball is in view.

(That node also returns a bool, called simply “Return Value” whose purpose I couldn’t figure out, but it may be that it informs us whether the converted screen position is in-bounds or out-of-bounds. It will take some testing to find out.)

If you check the “Screen Position” value to make sure its X and Y coordinates are both >= 0 but smaller than the width/height of the viewport, you can determine whether the contained screen position is in-bounds.

If not in-bounds, that’s your trigger to reveal the 2D indicator widget. (When in-bounds, you can do the opposite and hide it.)

For further reading, including how someone solved (at least part of) the problem using C++, check out this forum thread.

I ran out of characters in the previous comment, but to handle placing the widget along the edges of the screen, you would just need to clamp the returned screen space coordinate to zero or the maximum X or Y resolution, respectively. This way, the screen position you actually use is never off the screen — it’s never below zero or greater than the view resolution.

Rotation for the widget can be handled similar to how you already did rotation in 3D. You could make a 2D vector that points from the screen center to the widget’s updated position (which is along the side of the screen) and convert that vector into a 2D rotation angle.

You’re incredible! Thank you for taking the time to help me out!

I’m trying to follow along with your post and have gotten somewhere with determining if my ball is on screen and then hiding:

I’m not 100% sure if “Was Recently Rendered” is working well? My arrow sometimes pops up slower when the ball is offscreen. I’m not sure if this is a shortcut and your mentioned “Project World to Screen” is better?

But, going into a branch seems to work to hide and unhide!

The projecting the arrow to the sides of the screen is proving to be more intense. I’m getting a bit lost in your explanation mainly because I’m not super savvy on this kind of work.

Getting a bit in the weeds with the Project to World Screen" part and your comment

“but to handle placing the widget along the edges of the screen, you would just need to clamp the returned screen space coordinate to zero or the maximum X or Y resolution, respectively. This way, the screen position you actually use is never off the screen — it’s never below zero or greater than the view resolution.”

I’m excited for you to laugh at my thought process here - clearly I tried another option that doesn’t work, I tried to create a variable 2D(?) and I tried to do something with a vector 2D off the screen position. This is all very bad and wrong.

Additionally, I found a YouTube video doing damage indicator stuff and this was the blueprint setup this person was using:

link text

I tried something similar but I’m not sure about the creation of the custom event and the variables?

I probably jumped into the deep end right as the lifeguard whistled for adult swim…

Sorry to leave you hanging with poorly explained ideas. I was running out the door earlier and didn’t have time to think things through or, better yet, open the editor and create some screenshot examples. But I’m back, and I had some more time, and I hope it makes better sense now. Here goes.

For starters, to do this properly with widgets, you’ll need to set up a Widget Blueprint that contains your “HUD stuff” if you haven’t already. I won’t dive into that too far, but luckily it’s very easy to describe:

  1. In the content browser, create a new widget blueprint for your “HUD”
  2. From your Player Controller blueprint or Pawn blueprint, drop in a [Create Widget][1] node and select your newly created “HUD” widget class
  3. Immediately after the Create Widget node, drop in an Add to Viewport node (the link shows this too)
  4. Open up your “HUD” widget and add whatever you want, in particular whatever you want to use as your indicator “arrow” or whatever (this indicator widget is the object whose position and rotation we’ll be updating)

With that set up, we can talk about how to accurately determine whether your Game Ball actor is in the player’s view, and what to do with that data. This next image shows what you can put in your Player Controller or Pawn blueprint to handle this part:

(You actually don’t have to use the Player Controller or Pawn, necessarily, but it seemed easier to me, so that’s why I suggest it for now.)

The overall idea for that image is, you determine whether the Game Ball actor is off screen, storing two public variables in the process: a boolean (is the actor off screen?) and the actual screen-space location for the Game Ball actor.

(More to follow in next comment)

2 Likes

Set up that way, your PC or Pawn blueprint will now contain those two variables, which, because they’re public, can be accessed by other blueprints. In your case, you’ll be accessing these variables from your “HUD” widget blueprint.

Speaking of, you’ll need something like this in your “HUD” widget blueprint to be able to easily access the PC or Pawn blueprint multiple times. I used the Event Construct event, which is fired once when the “HUD” widget is first created:

With that, you can access your PC or Pawn actor, and the two variables you’ll need, any time.

Still in the “HUD” widget blueprint, toss the following stuff into the Tick event:

That bundle of behavior does the following:

  1. Shows or hides the indicator widget depending on whether the IsOffScreen boolean is true or false
  2. If the indicator widget is shown, updates its position so it’s always on the edge of the screen toward the direction where the Game Ball actor currently is

(I forgot to comment it, but the subtraction and clamping involving the 30 pixels you see is there to give some “padding” around the edge of the view to make the indicator not appear too close to the edge. Adjust to your liking.)

There’s one more image. This one shows how to update the indicator widget’s rotation:

That behavior should cause the indicator to always point outward from the center of the screen, assuming whatever graphic you’re using points, by default, to the right. (I crudely used a > character for my testing, and it worked great.)

You could also venture into affecting opacity or scale of your indicator, but I’ll leave that discussion for another day.

I know this is a lot, but I hope it does the trick!

2 Likes

Hey @the_batch

I haven’t even started digging into your posts and images yet (I’m about to)…

Do you have a Patreon or anything like that? I’d love to buy you a coffee or something. You’ve taken a lot of time to help and whether or not I figure this out :P, it’s extremely kind of you.

Let me know…

I’m honestly delighted by that offer. But no, thank you, and there’s no need. I simply and sincerely enjoy sharing my wonder for UE4 and game development with others — especially grateful and interested folks like yourself.

Besides, I’ve already had plenty of caffeine today. Any more might be physiologically detrimental. :wink:

Another reason I like helping out: the answer I created above turned out, unexpectedly, to be an improvement on a technique I used a while back for a very similar UI feature. So, by helping you, I also helped myself, because now I have a much better solution for this idea than I did previously, if I ever need to implement it again. So yeah, bonus.

Anyway, I hope what I’ve posted so far makes sense and it proves useful to you. Of course, if it’s not, or if it could use some more explanation, I’m happy to continue discussing it.

I ended up using your wonderful answers and images to modify the logic for onscreen vs. offscreen calculation of the indicator. I decided (currently) to not mess with a HUD widget as I’m not sure what the final design will end up being.

I also offset the arrow from the central pivot point a bit in Maya and now the arrow moves around the character in a more appealing manner as apposed to just being stationary above the head.

This works very well with a new material for prototype purposes.

I can’t thank you enough. You’ve helped save me weeks of time, truly. Are you on Twitter or Social media at all? Would love to support you with a follow or something.

Excellent! So glad I could help. Honestly, I’m stoked to have saved you some time and boosted your project. Your game is looking great, by the way!

I wish I could say something like, “Yeah! Follow me on Twitter where I post about lots of fascinating UE4 stuff!” But, truth is, I don’t do anything like that. Very boring. Maybe I should start.