摄像机控制器
public void FollowTarget(float delta)
{
Vector3 targetPosition = Vector3.Lerp(myTransform.position, targetTransform.position, delta / followSpeed);
myTransform.position = targetPosition;
}
public void HandleCameraRotation(float delta, float mouseXInut, float mouseYInput)
{
lookAngle += (mouseXInut * lookSpeed) / delta;
pivotAngle -= (mouseYInput * pivotSpeed) / delta;
pivotAngle = Mathf.Clamp(pivotAngle, minimumPivot, maximumPivot);
Vector3 rotation = Vector3.zero;
rotation.y = lookAngle;
Quaternion targetRotation = Quaternion.Euler(rotation);
myTransform.rotation = targetRotation;
rotation = Vector3.zero;
rotation.x = pivotAngle;
targetRotation = Quaternion.Euler(rotation);
cameraPivotTransform.localRotation = targetRotation;
}
主要是这么几个东西。首先myTransform是该物体的位置,还有一个pivotTransform和一个cameraTransform。targetTransform就是摄像机要跟随的对象,也即玩家。
pivotTransform是要使用pitch,也即俯仰角的变换,将物体绕X轴旋转。
myTransform使用yaw,即航向,将物体绕Y轴旋转。
这里把摄像机的旋转分离开来更灵活,但是不知道为什么这里的代码会导致旋转摄像机抖得厉害(更新已放在FixedUpdate里了)
抖动解决
public void HandleCameraRotation(float delta, float mouseXInut, float mouseYInput)
{
lookAngle += (mouseXInut * lookSpeed) * delta;
pivotAngle -= (mouseYInput * pivotSpeed) * delta;
pivotAngle = Mathf.Clamp(pivotAngle, minimumPivot, maximumPivot);
Vector3 rotation = Vector3.zero;
rotation.y = lookAngle;
Quaternion targetRotation = Quaternion.Euler(rotation);
myTransform.rotation = targetRotation;
rotation = Vector3.zero;
rotation.x = pivotAngle;
targetRotation = Quaternion.Euler(rotation);
cameraPivotTransform.localRotation = targetRotation;
}
将上述 lookAngle += (mouseXInut * lookSpeed) * delta;
pivotAngle -= (mouseYInput * pivotSpeed) * delta;从除delta换成乘delta
public void FollowTarget(float delta)
{
Vector3 targetPosition = Vector3.SmoothDamp(myTransform.position, targetTransform.position, ref cameraFollowVelocity, delta * followSpeed);
myTransform.position = targetPosition;
HandleCameraCollisions(delta);
}
相机跟随也换成乘delta,把lookSpeed和pivotSpeed调大就可以得到平滑的摄像机效果。最好把这两个函数都放在LateUpdate里。
第二次改进
上述方式也还是存在不同程度的旋转时抖动问题,第二次改进改为使用Lerp的方式。
public void HandleCameraRotation(float delta, float mouseXInut, float mouseYInput)
{
lookAngle += (mouseXInut * lookSpeed);
pivotAngle -= (mouseYInput * pivotSpeed);
pivotAngle = Mathf.Clamp(pivotAngle, minimumPivot, maximumPivot);
Vector3 rotation = Vector3.zero;
rotation.y = lookAngle;
Quaternion targetRotation = Quaternion.Euler(rotation);
myTransform.rotation = Quaternion.Slerp(myTransform.rotation, targetRotation, delta);
rotation = Vector3.zero;
rotation.x = pivotAngle;
targetRotation = Quaternion.Euler(rotation);
cameraPivotTransform.localRotation = Quaternion.Slerp(cameraPivotTransform.localRotation, targetRotation, delta);
}
第三次改进
改为Lerp后感觉效果还是差点意思,没有特别丝滑的感觉。参考了一些实现后发现使用SmoothDamp效果更好。最终代码如下
public void HandleCameraRotation(float delta, float mouseXInut, float mouseYInput)
{
lookAngle += (mouseXInut * lookSpeed);
pivotAngle -= (mouseYInput * pivotSpeed);
pivotAngle = Mathf.Clamp(pivotAngle, minimumPivot, maximumPivot);
/* Vector3 rotation = Vector3.zero;
rotation.y = lookAngle;
Quaternion targetRotation = Quaternion.Euler(rotation);
myTransform.rotation = Quaternion.Slerp(myTransform.rotation, targetRotation, 0.2f);
rotation = Vector3.zero;
rotation.x = pivotAngle;
targetRotation = Quaternion.Euler(rotation);
cameraPivotTransform.localRotation = Quaternion.Slerp(cameraPivotTransform.localRotation, targetRotation, 0.2f);*/
currentRotation = Vector3.SmoothDamp(currentRotation, new Vector3(pivotAngle, lookAngle), ref rotationSmoothVelocity, 0.2f);
myTransform.eulerAngles = currentRotation;
}