I am making a game that has a feature whereby 2D and 3D elements are placed in a world together. here you have an idea of the kind of mix that can be seen in my game.
I acheive this by placing my camera inside a gameObject called cameraHolder and simply rotating the cameraHolder along its z axis. This way the camera, which is attached to the holder, is always at a 41 degree angle pointing at the ground. Now you can imagine that I need to rotate the sprite to match 2 values. first) the z axis of the cameraHolder and second, I must place an angle on the sprite in oder for it to not be "lying" on the ground but rather facing the camera at all times. This is where the problems arrise.
Here you have an example of the rotation of the camera (The sprite of the chracter rotates on the z axis to match the cameraHolder and maintains it's rotation on the x axis so it always faces the camera.)
Now you'd think everything is great as this is actually the look and feel that I want. However, sporadically, and I cannot fathom what causes it, all the sprites will revert to being lying down along the floor and thus breaking the illusion. When trying to fix this I can realise that I dont really understand why it was working in the first place and perhaps if I understand that I can fix this in a permanent way.
the script that organises the rotation of the sprite is as follows.
public class FaceCamera : MonoBehaviour {
public Transform target;
void Start()
{
target = GameObject.Find("MainCamera").GetComponent<Transform>();
}
void Update()
{
if (target != null)
{
this.transform.rotation = target.rotation;
}
}
}
I am aware that for optimizations sake I should add a Mathf.Approximately and compare the two values and only do it if it has a changed value. But this is for testing purposes.
So my question is. Why does setting my sprites rotation to be equal to the cameras rotation work in the first place. The cameras rotation in eulerangles is (-41,0,0)?
Things I tried:
- Using rotation/position constraints components
- Setting a script that detects when it fails and fixes the issue (ugly I know but wanted to see if it works, doesnt)
- Tried applying eulerangle rotations directly, this causes weird behaviour when rotating the screen, think it could be gimbal lock.
references:
https://answers.unity.com/questions/48609/whats-the-difference-between-rotation-eulerangles.html
UPDATE 1
Transform cam;
[SerializeField] float threshold;
public static bool FastApproximately(float a, float b, float threshold)
{
return ((a - b) < 0 ? ((a - b) * -1) : (a - b)) <= threshold;
}
void Start()
{
cam = Camera.main.transform;
transform.rotation = cam.rotation;
}
void OnWillRenderObject()
{
if (!FastApproximately(cam.rotation.x, transform.rotation.x, 0.0001f))
{
transform.rotation = cam.rotation;
}
}