简体   繁体   中英

Unity: Can't get object's z axis to lock when facing camera

I want a sprite to always face the camera, except in the Z-Axis. My sprites keep tipping left or right when I move the camera, and I can't have that.

I have been googling this for hours. I've tried transform.LookAt or Quaternion.LookRotation and manually setting the z to 0, but for whatever reason the z keeps adjusting. I've seen and tried so many solutions that feel like they should work but just don't. If it matters, my sprite is a child of another object, but trying localRotation doesn't work either. Freezing rigidbody constraints also has no effect.

The most accurate I can get it is this:

public class Billboard : MonoBehaviour
{
    GameObject cam;
    float minDist;
    // Start is called before the first frame update
    void Start()
    {
        cam = GameObject.Find("Main Camera");
    }

    // Update is called once per frame
    void LateUpdate()
    {
        //Scale
        minDist = cam.GetComponent<CameraOrbit>().distanceMin;
        transform.localScale = new Vector3(1f, 1f, 1f) * (cam.GetComponent<CameraOrbit>().distance - minDist) * 1.01f / 3;

        //Direction
        transform.LookAt(cam.transform.position);
        Vector3 rot = transform.rotation.eulerAngles;
        transform.rotation = Quaternion.Euler(rot.x, rot.y, 0);

    }
}

With this I can get the sprite to face the camera, but the z axis refuses to stay at zero.

Special thanks to StarManta for answering this question on the Unity Forums.

"OK, I think I see what's happening. Them looking like they're rotated is, I think, an illusion; I think they really are accurately pointing at the camera and right-side-up. But, you're treating the camera as if it has a round/fisheye projection, when it really has a rectilinear projection. Usually this doesn't matter but in this case it does. It's hard to explain exactly how this affects this, but the upshot is that, when things that are on either side of the center of the screen are set to "look towards" the camera, they actually appear to be rotated around their Y axes.

The solution to this is actually annoyingly simple: don't set the rotation to look at the camera, set it to be the same as the camera."

transform.rotation = cam.transform.rotation;

I had a similar problem, where I wanted some 3d text to always look up, but rotated to the camera.
What worked for me was setting the undesired euler components to zero after applying the lookat rotation.
In your case, it would be something like this.

transform.LookAt(cam.transform.position);
var rot = transform.rotation.eulerAngles;
transform.rotation = Quaternion.Euler(rot.x, rot.y, 0);

In case you need another z value, just replace the 0.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM