- Home /
How to make a moving enemy's eye to follow player?
I'm making a game where there are spinning spike spheres which have one eye on the middle as you see in the picture down below. And I want the eye look at the player all the time. I already have some code in c# which makes the eye work when the enemy isn't moving, but when the enemy moves the eye does't follow because I don't know how make the eye follow along with the enemy. And yes the eye is a child object of the enemy.
It looks like that should work regardless of how the player is moving. Have you tried using the transform itself ins$$anonymous$$d of that Vector3
for pupil position? If your spike guy is moving, that would throw off your math.
Vector3 lookDir = (Player.position - Pupul.position).normalized;
Also, is it possible that the player is moving around on its Z-axis? That looks like 2D art for what is probably a 2D game, did you maybe do something with their distances in Z that might throw off your unit-length vector lookDir
?
Sorry I'm a bit noob so how would I use the transform ins$$anonymous$$d of vector3? And yes the game is 2D and the player isn't moving on Z-axis but when I press play the pupil is moving in Z-axis, but I think it's because the pupil is the characters child object and when the character moves right or left the pupil moves on the Z-axis. Thx for the response!
Answer by LCStark · Sep 25, 2018 at 07:09 AM
Use Pupil.localPosition
instead of Pupil.position
. position
sets object's position in the world space, while localPosition
sets the position inside its parent object. You are calculating the eye position inside your enemy object, so you want the localPosition
here.
EDIT
To make the answer clearer - the original code remembers the world position of the "Pupil" (with no relation to its parent "Eye"), and in the Update
method that stored position is used to calculate where the "Pupil" should look. This works fine, as long as the "Eye" remains stationary. When the "Eye" moves, the stored world position of the "Pupil" is no longer valid - it remains in the original place, when the "Eye" has moved on.
In Unity, when one object is a child of another and the parent object is moved, the child object is moved with it to keep its position. This is why child objects have a transform.localPosition
property - so we can modify the relative position of the child object while letting Unity still update its world position when the parent object moves.
If we change the code above to the localPosition
version:
void Start() {
mPupilCenterPos = Pupil.localPosition;
}
void Update() {
Vector3 lookDir = (Player.position - mPupilCenterPos).normalized;
Pupil.localPosition = mPupilCenterPos + lookDir * eyeRadius;
}
the child object will still follow the parent object, but now the
lookDir
calculation is broken - we are comparing
Player.position
, which is the world position of the player, with a local position of the enemy. We need to change that and convert the local pupil center to its world space value. To do that, we simply add it to its parent's world position:
Vector3 lookDir = (Player.position - (transform.parent.position + mPupilCenter)).normalized;
The pupil now follows the player but when I press play the pupil jumps in different spot than it's in the scene. Thx for responding!
That's your Start
method changing the "center" position of the eye: mPupilCenterPos = Pupil.position
. Did you change that to localPosition
too?
EDIT
Also, you'll need to change the lookDir
calculation - you must use global position in there. Since your eye is located in the center of your enemy object, you can use its position: Vector3 lookDir = (Player.position - transform.position).normalized;
should be fine.
Ok now it jumps to a different spot?
Here's my script atm
EDIT: It was just problem with the radius. Thank you very much for help!
I don't think assigning local position makes sense as-is. The original eye position, player position, and their differences are all in world space. The assignment of the pupil's world position is being offset by its world position, so you aren't going to get a sensible value because you're using two different reference frames.
If you wanted to simplify this with local position, you'd do something like:
void Start()
{
// Empty
}
void Update()
{
// Assigning local position without world offset
Pupil.localPosition = EyeRadius * (Player.position - Pupul.position).normalized;
}
That works with me when the eye is in the middle of the character, but I have another where it isn't and the eye jump to the middle. I'm having a new problem where when the character turns left the eye turns too and it points in the other direction of the player. How can I make that the eye isn't affected of the parent character? Thx for your response :)
Using it's normal position with an offset like you were doing before. You mentioned that a radius issue was causing it to misbehave, which is sensible as the rest was fine geometrically.
In my experience, using and manipulating local position is rare, especially when you're dealing with two object whose parents differ.
but I have another where it isn't and the eye jump to the middle.
So that is information that you'll want to include in your original question. The assumption here is that these "Pupil" objects have some parent object anchoring them to whatever their center is supposed to be. Can you not just set that up for the "other" eyes?
Both the player and the enemy positions are in world space, because they need to be - you are comparing the positions of two distinct objects. Also, since you're only using them to get a direction vector, it doesn't matter they're world space coordinates.
Since a Pupil
is a part of an Eye
(its child object) and we want to move the Pupil
in relation to the Eye
, local position makes all the sense. The pupil moves with the eye - it is its integral part and not some separate object.
Your original response didn't seem clear on where OP should use localPosition ins$$anonymous$$d of position. There were two places where position was used, that was the clarification I made.
Your answer
![](https://koobas.hobune.stream/wayback/20220612175201im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
C#2d Attacking multiple enemies rather than one 2 Answers
my enemy is broken 1 Answer
2d c# boss follow code 0 Answers
Enemy bounce from screen edges 0 Answers
Distribute terrain in zones 3 Answers