I'm trying to create a "billboard" effect where a quad/gameObject always faces a target object (the camera) around the Y axis. This is working fine as per the code below, but I want to add an optional offset to the pivot point on the X axis. So rather than rotating around the center point (default behaviour), I want the quad to rotate around a new point thats n units off of the center point, while still facing the target object.
This will run in Update().
Currently Working Code Without Offset
transform.LookAt(camera.transform, Vector3.up);
transform.localEulerAngles = new Vector3(0, transform.localEulerAngles.y, 0); // Only affects Y Axis.
The offset I need is calculated by the function below. It is tested to be correct by moving a child GameObject by this value.
Both the leftObj and rightObj are children of the GameObject I want to be rotating.
public float GetCenterPos()
{
Vector3 left = leftObj.transform.localPosition;
Vector3 right = rightObj.transform.localPosition;
Vector3 center = (left + right) / 2f;
return center.x;
}
I have tried combinations of RotateAround, but I can't figure out how to get it to face the correct object and what the pivot should be relative to the offset. I have also googled around, and I can't find a solution to this problem that I feel is relatively simple.
To recap: I don't need a rotational offset, and I don't want to add an extra parent to change the pivot like many other answers suggest. The offset gets calculated dynamically in Update.
Thank you for any help.
I've been tinkering with it for a while, and I came up with this solution. It's not ideal because it requires storing a reference to the starting position, which breaks some of the other movement functionality I need, but it does answer my original question.
Before beginning the code above (either in start or before a bool flag is set, whatever) store a reference to the object's localPosition (startPos
)
Then before calling LookAt
, adjust the position to take into account the offset.
transform.localPosition = new Vector3(startPos.x + offset, transform.localPosition.y, transform.localPosition.z);
transform.LookAt(camController.transform, Vector3.up);
transform.localEulerAngles = new Vector3(0, transform.localEulerAngles.y, 0);
To clarify, the reason why I need a reference to startPos
is because otherwise I would be adding the offset every frame, resulting in the object just moving constantly, rather than using a consistent value.
I just set the startPos before and after toggling the "billboard" functionality to keep it updated. Not ideal, but it does work.