Home > OS >  Can't rotate camera with clamped X to specific target
Can't rotate camera with clamped X to specific target

Time:01-24

In a project i have a player with clamped head movement around vertical axis [-85, 85] I need to rotate head to specific direction, but the head keeps facing down all the time, what I'm doing wrong?

I apply rotation to head using separate vector axisViewCamera:
cameraBody.localRotation = Quaternion.Euler(axisViewCamera);

Clamping: axisViewCamera.x = Mathf.Clamp(axisViewCamera.x, -85f, 85f);

Then i take direction from Transform.forward or calculating it from two Transforms and applying it like this, with help of the DOTween:

var euler = Quaternion.LookRotation(direction, Vector3.up).eulerAngles;
var original = Quaternion.LookRotation(axisViewCamera, Vector3.up).eulerAngles;
blockViewChange = true;
DOTween.To(SetAxis, 0f, 1f, 1).SetTarget(playerCamera)
      .OnComplete(() => blockViewChange = false).SetUpdate(true);

void SetAxis(float t) => axisViewCamera = Vector3.Lerp(orig, euler, t);

CodePudding user response:

Upon solid 10hrs of sleep and some more extra googling and debugging i figured out that my axisViewCamera was not clamped properly, and it was good only until i tried to lerp it after some rotation applied to camera;

So i figured out that this clamping method should be applied to each axis of axisViewCamera every time i change it as is the euler var i get from direction.

shoutout to: https://stackoverflow.com/a/2323034/15787374

private float SmartClampAngle(float angle)
{
    var remainder = angle                      % 360f;
    var positiveRemainder = (remainder   360f) % 360f;
    if (positiveRemainder > 180) positiveRemainder -= 360f;
    return positiveRemainder;
}

Result:

axisViewCamera Update:

private void UpdateCameraRotation(Vector2 viewAxis)
{
    axisViewCamera.x -= viewAxis.y;
    axisViewCamera.y  = viewAxis.x;
    axisViewCamera.x = SmartClampAngle(axisViewCamera.x);  //Previously i just applied   and - without any clamp       
    axisViewCamera.y = SmartClampAngle(axisViewCamera.y);
}

Direction Change:

var euler = Quaternion.LookRotation(direction, Vector3.up).eulerAngles;
euler.x = SmartClampAngle(euler.x); 
euler.y = SmartClampAngle(euler.y); 

var orig = Quaternion.LookRotation(axisViewCamera, Vector3.up).eulerAngles;
blockViewChange = true;
DOTween.To(SetAxis, 0f, 1f, 1).SetTarget(playerCamera)
      .OnComplete(() => blockViewChange = false).SetUpdate(true);

void SetAxis(float t) => axisViewCamera = Vector3.Lerp(orig, euler, t);
  • Related