9
\$\begingroup\$

I have been troubleshooting a prefab for several hours and am out of ideas. It concerns a method that I thought I was comfortable with, transform.LookAt(target). I have this prefab:

enter image description here

As you can see, I verified that the registration points for the eyes are at the center of mass; I also verified that they rotate correctly for the X, Y and Z axes. That yellow ball you see is the target object and IS NOT inside the prefab.

I have tried two means to get the eyes to look at the target. The first is this script, and it caused the eyes to dart 90 degrees counter-clockwise about the y axis (which is very wrong). I applied this script to both eyes. Check it out:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LookAt : MonoBehaviour
{
    public Transform target = null;

    // Update is called once per frame
    void Update()
    {
        transform.LookAt(target);            
    }
}

And please, before you think it: Yes, I remembered to set the target object in the editor. You can see the eyes pointing to the side instead of the target:

enter image description here

I found this other script on the Unity documentation that didn't work at first, but then I changed "Rotation" to "LocalRotation", saw that I was close, reversed the "relativePos" vector, and it worked--but only about the y axis:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LookAt : MonoBehaviour
{
    public Transform target = null;

    // Update is called once per frame
    void Update()
    {
        Vector3 relativePos = transform.position - target.position;

        // the second argument, upwards, defaults to Vector3.up
        Quaternion rotation = Quaternion.LookRotation(relativePos, Vector3.up;
        transform.localRotation = rotation;

    }
}

You can see here that it works in the XY plane at eye level, but take my word for it when I say the eyes cannot look up or down if I move the ball up or down:

enter image description here

How can I fix this so that the eyes always look at the target I need it to? Thank you sincerely for your time.

EDIT: I fixed it by this sloppy additional rotation, but there has to be a better way:

void Update()
    {
        //transform.LookAt(target);

        Vector3 relativePos =  target.position - transform.position;

        // the second argument, upwards, defaults to Vector3.up
        Quaternion rotation = Quaternion.LookRotation(relativePos, new Vector3(0,1,0));
        transform.rotation = rotation*Quaternion.Euler(0,90,0);            
    }

enter image description here

\$\endgroup\$

1 Answer 1

10
\$\begingroup\$

The Problem:
Your eyes default rotation makes them look to the negative X axis.
However, Transform.LookAt() rotates the transform, so that the Transform.forward looks at the target.
The Transform.forward always looks to the positive Z axis.
(All directions in local space).

Solution 1:
Rotate the texture or mesh, so that the eye's default look direction is along the positive Z axis.
Then LookAt will work as expected.

Solution 2:
After the call of Transform.LookAt, correct the rotation by the correct rotation.

transform.LookAt(target);
transform.rotation *= Quaternion.FromToRotation(Vector3.left, Vector3.forward);

Where Vector3.left represents the default forward direction of the eyes.

\$\endgroup\$
5
  • \$\begingroup\$ I tried rotating everything in the prefab so they were facing Z+ 10 min ago but that didn't do anything. Trying Solution 2...oh, lol! That's what I'm doing, isn't it! Good to know XD \$\endgroup\$ Commented Aug 19, 2019 at 11:24
  • 1
    \$\begingroup\$ If you rotate it in the prefab, transform.lookat rotates it back. As your eye has the lookat directly, the rotation gets overwritten. You could achieve it though, by creating a game object with the LookAt script, and the eye as child. Then the rotation defined by you won't be overwritten. \$\endgroup\$ Commented Aug 19, 2019 at 11:27
  • \$\begingroup\$ That makes sense because then I don't need to apply the script to every monster in the game, it just needs to be in the arena. Would the eye no longer be in the prefab though? What do you mean "the eye as a child"? \$\endgroup\$ Commented Aug 19, 2019 at 11:29
  • \$\begingroup\$ Well the parent game object with the LookAt is still part of the monster, as it is just put in between the monster and the eye. Or did I missunderstand something? \$\endgroup\$ Commented Aug 19, 2019 at 11:31
  • \$\begingroup\$ No, I was misunderstanding, I see what you mean now. I will try that. Thank you so much for your time and expertise! \$\endgroup\$ Commented Aug 19, 2019 at 11:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .