首页 > 解决方案 > Unity 飞行相机在加速时穿过地面和物体

问题描述

我正在使用统一的extendedflycam.cs。我添加了一个球体对撞机和一个刚体。目的是避免相机穿过地面和建筑物。这仅在相机以正常速度飞行时实现,但当相机使用 shift 键加速时,如脚本所预期的那样,它会穿过地面和建筑物。这是通过脚本本身的速度倍增器来实现的。如何避免这种情况?即使在加速时,相机怎么会发生碰撞?

我有没有重力的刚体,质量、阻力和角度阻力为 1000。这是 ExtendedFlycam.cs:

using UnityEngine;

{
    public class ExtendedFlycam : MonoBehaviour
    {
        public float CameraSensitivity = 90;
        public float ClimbSpeed = 4;
        public float NormalMoveSpeed = 10;
        public float SlowMoveFactor = 0.25f;
        public float FastMoveFactor = 3;

        private float _rotationX;
        private float _rotationY;

        // ReSharper disable once UnusedMember.Local
        private void Start()
        {
            _rotationX = transform.eulerAngles.y;
        }

        // ReSharper disable once UnusedMember.Local
        private void Update()
        {
            if (Input.GetMouseButton(1))
            {
                _rotationX += Input.GetAxis("Mouse X") * CameraSensitivity * Time.deltaTime;
                _rotationY += Input.GetAxis("Mouse Y") * CameraSensitivity * Time.deltaTime;
                _rotationY = Mathf.Clamp(_rotationY, -90, 90);
            }

            Quaternion targetRotation = Quaternion.AngleAxis(_rotationX, Vector3.up);
            targetRotation *= Quaternion.AngleAxis(_rotationY, Vector3.left);
            transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 4f);

            float speedFactor = 1f;
            if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) speedFactor = FastMoveFactor;
            if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) speedFactor = SlowMoveFactor;

            transform.position += transform.forward * NormalMoveSpeed * speedFactor * Input.GetAxis("Vertical") *
                                  Time.deltaTime;
            transform.position += transform.right * NormalMoveSpeed * speedFactor * Input.GetAxis("Horizontal") *
                                  Time.deltaTime;
            float upAxis = 0;
            if (Input.GetKey(KeyCode.Q)) upAxis = -0.5f;
            if (Input.GetKey(KeyCode.E)) upAxis = 0.5f;
            transform.position += transform.up * NormalMoveSpeed * speedFactor * upAxis * Time.deltaTime;
        }
    }
}

标签: unity3dcameracollisionfly

解决方案


改用Rigidbody.AddForce

您显然是在使用Transform.Translate移动相机。如果您希望您的相机在完全碰撞的情况下移动,那么您不能使用平移(因为在下一次碰撞检测之前,平移可能会使您的相机完全穿过一个对象)。

如果你想拥有碰撞的全部容量,那么你必须使用Rigidbody.AddForce.

https://docs.unity3d.com/ScriptReference/Rigidbody.AddForce.html

您必须特别注意物体的重力、运动特性等。但是,您应该能够以与翻译类似的方式控制对象。例如:

rb.AddForce(transform.forward * thrust);

rb.AddForce(transform.forward * -thrust);

rb.AddForce(transform.right* thrust);

rb.AddForce(transform.right* -thrust);

向前转变,向前迈进。向后移动的负推力。您还可以在正确的方向和负的正确方向上施加推力。我仍然会使用翻译进行旋转,只是因为这对你来说可能更容易。

您可能希望在对象上设置高摩擦力,以便它像使用平移时一样快速停止。

扩展示例:

public float thrust = 5f;
public Rigidbody rb;

void Start()
{
    rb = GetComponent<Rigidbody>();
}

void FixedUpdate()
{
    // Movement code.
    if (Input.GetKey(KeyCode.UpArrow))
    {
       rb.AddForce(transform.forward * thrust);
    }
    if (Input.GetKey(KeyCode.DownArrow))
    {
       rb.AddForce(transform.forward * -thrust);
    }
    if (Input.GetKey(KeyCode.RightArrow))
    {
       rb.AddForce(transform.right* thrust);
    }
    if (Input.GetKey(KeyCode.LeftArrow))
    {
       rb.AddForce(transform.right* -thrust);
    }

    // Your rotation code
    if (Input.GetMouseButton(1))
    {
        _rotationX += Input.GetAxis("Mouse X") * CameraSensitivity * Time.deltaTime;
        _rotationY += Input.GetAxis("Mouse Y") * CameraSensitivity * Time.deltaTime;
        _rotationY = Mathf.Clamp(_rotationY, -90, 90);
    }

    Quaternion targetRotation = Quaternion.AngleAxis(_rotationX, Vector3.up);
    targetRotation *= Quaternion.AngleAxis(_rotationY, Vector3.left);
    transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * 4f);

}

推荐阅读