How to rotate child entity to face the camera?

Hey all!

I have a parent entity with a child entity. The parent entity is what moves around, while the child entity is what displays the sprite. I’d like to have the child entity always facing up towards the camera, but I’m not sure how to achieve that. Below is my attempt at putting something together, but it doesn’t work properly. The sprites will face the right direction at times, but they also flip around/rotate at times.

Any help would be much appreciated!

var rotation = rotationLookup[entity];
var translation = translationLookup[entity];
var parentTranslation = translationLookup[parent.Value];

parentTranslation.Value.z += 10;
var relativePosition = parentTranslation.Value - translation.Value;
rotation.Value = quaternion.LookRotationSafe(relativePosition, math.up());

What is this value? Just the same as Vector3.up? That could be your issue… typically you would provide an “up” direction that is orthogonal to the plane of rotation you care about. If you are rotating in the usual 2D X/Y plane for a flat sprite, then an orthogonal direction would be either Vector3.forward or Vector3.back.

Yeah, it’s the same as Vector3.up. I tried changing it to forward, but the issue persists.

After thinking through it a bit more, I feel like what I need to do is calculate the difference in rotation between the parent’s current rotation and its rotation if it was facing up, then give the child this difference in rotation. From my understanding, “subtracting” quaternions is done by multiplying by the inverse of the value you want to remove.

I’ve got something working, but I’m getting “Invalid AABB a” errors now and the sprite shows up really big and distorted when it is first created. I feel like it might have something to do with math.inverse. One of the threads I came across mentioned that there isn’t always a valid inverse and that Unity’s Transform normalizes quaternions so there is. Maybe the DOTS Rotation component doesn’t do this?

var rotation = rotationLookup[entity];
var parentRotation = rotationLookup[parent.Value];
var parentTranslation = translationLookup[parent.Value].Value;

var upTranslation = parentTranslation;
upTranslation.z += 10;
var endRotation = quaternion.LookRotationSafe(upTranslation - parentTranslation, math.up());
rotation.Value = math.mul(endRotation, math.inverse(parentRotation.Value));

Assuming the child sprite is “naturally” aligned with the camera (eg, if you put one in front of the other, same Quaternion.identity rotation, the sprite looks normal), couldn’t you get the effect you want by copying the camera’s rotation to that child object’s rotation?

You would need to be sure of order of operation though:

  • rotate the player (and hence the child)
  • rotate the camera
  • copy the camera rotation directly to the child transform.

For anyone coming across this in the future, here’s the right way to do this:

rotation.Value = math.inverse(math.normalizesafe(parentRotation.Value));