Unity飞行相机在加速时会穿过地面和物体

时间:2018-10-09 15:33:52

标签: unity3d camera collision fly

我正在使用统一的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;
        }
    }
}

1 个答案:

答案 0 :(得分:1)

改为使用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);

}