【问题标题】:The Unity fly camera goes through ground and objects when acceleratingUnity 飞行相机在加速时穿过地面和物体
【发布时间】:2018-10-09 15:33:51
【问题描述】:

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

【问题讨论】:

  • 发布您的代码,如果答案有用,请点赞。

标签: unity3d camera collision fly


【解决方案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);

}

【讨论】:

  • 我在问题中添加了脚本......所以如果我理解你,我应该将“transform.position”更改为“rb.AddForce(transform.forward *推力);” ?
  • @Ivan,请参阅扩展示例。关闭运动学,并将摩擦力设置为最适合您想要的运动的任何值。
  • 效果很好。有默认值。但是,如果我将快速移动因子更改为例如 10,它会再次遍历对象
  • @Ivan,您可以尝试的另一件事是将盒子/胶囊对撞机换成网格对撞机并在其刚体上选择连续。它应该能够以更高的速度检测碰撞。
  • 这不是本意,但如果我得到解决方案,我会在这里发布。还是谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-17
  • 2018-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多