Unity fly camera проходит сквозь землю и объекты при ускорении - PullRequest
0 голосов
/ 09 октября 2018

Я использую 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;
        }
    }
}

1 Ответ

0 голосов
/ 09 октября 2018

Используйте 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);

}
...