【问题标题】:Unity3d - Camera rotation smoothing 'bug'Unity3d - 相机旋转平滑“错误”
【发布时间】:2018-05-12 11:58:06
【问题描述】:

我做了一个简单的赛车游戏。相机跟随汽车(玩家),它的位置和旋转基于汽车的 Y 旋转。我想平滑相机旋转,但是当它越过 0 度点时,它会旋转 360 度。 代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Camera : MonoBehaviour {
    public Transform camera, player;


    void Update() {
        Vector3 cameraPosition = camera.transform.position;
        float cameraRotation = camera.eulerAngles.y;
        float playerRotation = player.eulerAngles.y;
        Vector3 playerPosition = player.transform.position;
        cameraPosition.x = (Mathf.Sin((playerRotation / 180) * Mathf.PI) * -6 + player.position.x);
        cameraPosition.y = playerPosition.y + 2.5f;
        cameraPosition.z = (Mathf.Cos((playerRotation / 180) * Mathf.PI) * -6 + player.position.z);
        camera.transform.position = cameraPosition;
        cameraRotation = cameraRotation + (playerRotation-cameraRotation)/2;
        camera.localRotation = Quaternion.Euler(20f, cameraRotation, 0f);
    }
}

我发现这种旋转是由平滑脚本引起的:

 cameraRotation = cameraRotation + (playerRotation-cameraRotation)/2;

如何防止这种不必要的旋转?

【问题讨论】:

  • 旋转基于什么样的公式?你想让相机看车吗?另外,为什么不把摄像头放在车上,这样你就不用搞乱Sin和Cos了?
  • 相机的行为几乎像个孩子,但我想添加这种平滑以使它看起来更好一点。是的,我想让相机看汽车。 Sin 和 Cos 没有问题,但平滑脚本。它看起来像这样:video
  • 另外,您可以使用cameraRotation = cameraRotation + (playerRotation-cameraRotation)/10; 使其更慢且更显眼。
  • 我知道 Sin 和 Cos 没有问题。在我看来这只是不必要的,因为您只需将相机作为汽车的孩子即可获得类似的效果

标签: c# unity3d


【解决方案1】:

我会这样做:

public int smoothSpeed = 1f; // Change accordingly to increase/decrease smooth speed.

然后在更新中:

Vector3 directionToCar = player.position - camera.position;
Quaternion desiredRotation = Quaternion.LookRotation(directionToCar);
camera.rotation = Quaternion.Slerp(camera.rotation, desiredRotation, Time.deltaTime * smoothSpeed);

在侧节点上,如果此相机脚本附加到相机,则不必创建引用相机变换的字段。你可以简单地使用transform.position 而不是camera.transform.position

【讨论】:

    【解决方案2】:

    使用 Slerp 的一个更简单的解决方案是使用 Mathf.SmoothDamp,它有一个名为 Mathf.SmoothDampAngle 的变体,可以正确处理循环。我也成功地手工完成了环绕,但这并不是一次非常有益的体验

    using UnityEngine;
    public class RotFollow : MonoBehaviour
    {
        [SerializeField] Transform carTransform;
        [SerializeField] float smoothTime = .4f; 
    
        float currentYAngle;
        float targetYAngle;
        float angleVel;
        void Update()
        {
            targetYAngle = carTransform.rotation.eulerAngles.y;
            currentYAngle =  Mathf.SmoothDampAngle(currentYAngle, targetYAngle, ref angleVel, smoothTime);
            transform.rotation = Quaternion.Euler(
                                            transform.rotation.eulerAngles.x,
                                            currentYAngle, 
                                            transform.rotation.eulerAngles.z);
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-12
      • 2020-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多