有没有更好的方法来计算滚动球的方向以使相机跟随它?

Posted

技术标签:

【中文标题】有没有更好的方法来计算滚动球的方向以使相机跟随它?【英文标题】:Is there a better way to calculate the direction of a rolling ball in order to make the camera follow it? 【发布时间】:2021-12-27 03:02:03 【问题描述】:

目前我正在使用归一化的 rb 速度来获取 x 和 z 速度方向,以便将其与相机的 eulerAngles 进行比较,以便告诉相机以哪种方式旋转。但是我在一堆嵌套的 if 语句中这样做,它只是感觉......错了。 对于实际跟随球,我只是与 Player -> RotatorObject -> Camera 有父子关系,因此旋转 RotatorObject 会围绕玩家的中心旋转。

这是我目前正在做的一个例子。

// Velocity direction of the ball
Vector3 VelNormed = Vector3.Normalize(rb.velocity);
xVelNormed = VelNormed.x;
zVelNormed = VelNormed.z;

// Current CameraRotationObject angle
yEuler = transform.eulerAngles.y;
zEuler = transform.eulerAngles.z;

// If Moving forwards.
        if (zVelNormed >= 0.5)
        
            // If camera is within hoped for range. (270 is camera = perfectly forwards)
            if (yEuler >= 260 && yEuler <= 280)
            
                // Move camera to the right.
                if (yEuler >= 260 && yEuler <= 270)
                
                    // Rotate camera right
                    transform.Rotate(0, (speed * Time.deltaTime) * 1, 0);
                
                else if (yEuler <= 280 && yEuler >= 270)
                
                    // Rotate camera left
                    transform.Rotate(0, (speed * Time.deltaTime) * -1, 0);
                
                else
                

                
            
            
        
        // If Moving backwards.
        else if (zVelNormed <= -0.5)
        
                    //etc.
        

就像我之前说的,使用所有这些 if 语句让我感觉自己像个怪物! IE。我几乎可以肯定我正在以旧的傻瓜计算机编程方式进行此操作

【问题讨论】:

【参考方案1】:

首先eulerAngles 很少是您想要使用的

当您阅读 .eulerAngles 属性时,Unity 会将 四元数旋转到欧拉角的内部表示。 因为,有不止一种方法来表示任何给定的旋转 使用欧拉角,您读回的值可能相当 与您分配的值不同。这可能会引起混淆,如果 您正在尝试逐渐增加值以生成动画。

为什么你真的需要让相机旋转?在我看来,您的主要问题实际上源于相机嵌套在滚动球下方的某个地方。

您应该将相机提取到场景根级别并通过例如代码使其跟随球

public class CameraFollow : MonoBehaviour

    // Interpolation factors for the position and rotation
    [Range(0, 1)] public float moveInterpolationFactor = 5f;
    [Range(0, 1)] public float rotateInterpolationFactor = 5f;

    // The target this object shall follow 
    [SerializeField] Rigidbody targetObject;

    // Positional offset in the movement direction of the target object
    // e.g. (0,0, -1) will keep the camera 1 world space unit behind the move direction
    public Vector3 positionOffset = new Vector3(0, 0.25f, -1);

    private Vector3 targetPosition;
    private Quaternion targetRotation;

    private void Awake ()
    
        if(!targetObject) return;

        UpdateTargetValues();
    

    private void UpdateTargetValues ()
    
        targetPosition = targetObject.position + targetObject.rotation * positionOffset;
        targetRotation = Quaternion.LookRotation(targetObject.velocity);
    

    private void LateUpdate ()
    
        // If there is no target stay where you are
        if(!targetObject) return;

        // Get the move velocity since we want to follow based 
        // on the move direction, not the objects orientation
        var velocity = targetObject.velocity;

        // If not moving simply continue moving to the last set position
        // otherwise update the target values
        if(velocity.sqrMagnitude > 0)
        
            UpdateTargetValues ();
        

        transform.position = Vector3.Slerp(transform.position, targetPosition, moveInterpolationFactor * Time.deltaTime);
        transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, rotateInterpolationFactor * Time.deltaTime);
    

    public void SetTarget(Rigidbody target)
    
        targetObject = target;

        if(!targetObject) return;

        UpdateTargetValues ();
    

【讨论】:

targetRotation = Quaternion.LookDirection(targetObject.velocity); LookDirection 似乎不是一个函数。你的回答肯定让我走上了正轨,我感谢你。你问为什么我有嵌套的孩子而不是一个单独的相机对象。原因是我的球体实际上从未旋转,它只是施加了附加力。因此,使用您的示例,相机仍然跟随未嵌套的球,但是当我旋转相机时,它只是像人头一样向左或向右看,它不会留在球后面。 如果您将一个子对象嵌套到播放器对象然后旋转它,它将跟随父对象围绕该对象绕一圈,而不是仅仅在原地旋转。 应该是LookRotation ;) (在智能手机上输入,后来我拿它录制时忘记将更改移植回这里^^) example image - 这是我为什么嵌套的一个例子。这适用于您的方法。 @MarcusCampbell 您是否像答案建议的那样“将相机提取到场景根级别”?

以上是关于有没有更好的方法来计算滚动球的方向以使相机跟随它?的主要内容,如果未能解决你的问题,请参考以下文章

如何让物体跟随相机?

# Unity2D相机跟随的多种姿势

# Unity2D相机跟随的多种姿势

# Unity2D相机跟随的多种姿势

如何在vim中通过命令向下滚动而不用方向键?

在OpenGL中沿对象后面的方向旋转相机