- Home /
How to have an arrow point in the direction my character is aiming pivoting around my characters location
I am creating a 2D platformer, and would like an arrow indicator to show the direction my character is aiming in using all 360 degrees around the player. The arrow graphic would stay fixed to the player's local location.
Answer by jackmw94 · Jun 09, 2021 at 11:07 AM
Make a canvas a child of your character object, have the canvas's render mode as world space. Since it's a child of your character (and is a world space canvas), it will always "follow" your character. Note that world space canvases are massive by default and you probably want to scale these down to around 0.001, then keep its position and rotation at 0 to have it on top of your character.
Add an image to the canvas and set the image's y-pivot to 0, this means it will rotate around at point at the bottom of the image - you can see this by adjusting the z-rotation.
Now you can set the arrow as the sprite for this image and we can think about setting the rotation. I expect you'll have your character's aim rotation at some point in your code, in which case you can pass this into your aiming-arrow script and apply this value to its rotation.
If for some reason you need to get this from an x and y vector then you can get the vector's angle by float angle = Vector2.SignedAngle(Vector2.up, inputVector);
and then apply it to your arrows rotation by using this angle as the z-component of it's euler angles: transform.rotation = Quaternion.Euler(0f, 0f, angle);
. Note that where I use Vector2.up in the angle equation, this assumes that the arrow sprite is facing upwards - more on this later.
At this point your arrow should be rotating in the direction you're aiming, however since it rotates around a fixed point, it might overlap your character and not look very nice. If your vision for this behaviour is the same as mine then you'll want this arrow to rotate at a given radius around the character. If this is not the case and this behaviour is fine as it is then you can stop here.
To achieve this, instead of having the image as the direct child of your canvas you can have an offset object. This will now be the object that you rotate, with your arrow image being a child of this one. Now you can adjust your child's local position to create this radius of rotation.
So at this point the hierarchy looks like this:
Character -> Canvas (world space) -> Offset -> Arrow (image)
The offset object is the one you rotate in code to match the aim direction and the arrow is the one whose position you change in editor to ensure it rotates at a distance to the player.
Finally, where I mentioned that angle calculation has assumed that the arrow is pointing upwards, since you now have an offset object that you rotate, you can rotate your image object to adjust the arrow's rotation. i.e. if you arrow sprite points right at 0 rotation and you don't want to rotate the sprite itself, you can rotate your image object so that it points upwards at 0 rotation. This isn't possible when the image is a direct child of the canvas since you'd be changing the same rotation that you then set in code. If you don't want the radius but need to rotate your sprite then follow the extra steps but keep your image's position at 0,0,0.
Let me know if you have any questions about this!
Thank you @jackmw94 for the detailed insight. I am going to try and create what you said and will write back if it is still not working as intended.
Your answer
Follow this Question
Related Questions
2D renderer with particles on UI 1 Answer
2D Collider larger than specified 0 Answers
Button OnClick() Missing Code Error, How do I fix this? 1 Answer
Drawing a straight line between two points with 2D UI 1 Answer
Need help writing script 1 Answer