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);