Как использовать Input.GetAxis («Mouse X / Y») для поворота камеры?

13

Я хочу сделать камеру от первого лица, которая вращается с помощью мыши.

Я посмотрел на страницу API сценариев Input.GetAxis и нашел пример кода, который я включил в конец своего поста. Попробовав это, я понял, что, хотя он и обладает теми же базовыми функциями, на которые я надеялся, он не удерживает камеру параллельно плоскости xz, особенно при перемещении мыши по кругу. Через некоторое время камера окажется под нечетным углом, и игрок будет полностью сбит с толку!

Существует ли быстрое исправление этого кода, которое каким-то образом ограничит движение камеры, или есть лучший способ повернуть камеру?

 using UnityEngine;
 using System.Collections;

     public class ExampleClass : MonoBehaviour {
         public float horizontalSpeed = 2.0F;
         public float verticalSpeed = 2.0F;
         void Update() {
             float h = horizontalSpeed * Input.GetAxis("Mouse X");
             float v = verticalSpeed * Input.GetAxis("Mouse Y");
             transform.Rotate(v, h, 0);
         }
     }
reincarnationofstackexchange
источник
То, что вы испытываете, звучит как карданный замок. Это происходит, когда вы используете углы Эйлера для вращения. Я должен был бы сделать некоторое тестирование, чтобы предложить решение. В основном вам нужно использовать кватернионы. Они не страдают от блокировки карданного подвеса.
Нечеткая логика
Как бы я использовал кватернион для вращения? Я попытался transform.rotation = Quaternion.Slerp (-Input.GetAxis ("Мышь X"), Input.GetAxis ("Мышь X"), Time.deltaTime * freeLookTurningSpeed); , но это дало мне ошибки.
реинкарнация
Хорошо, я сделал тест. К счастью, это не карданный замок. Я опубликую решение как ответ для вас.
Нечеткая логика

Ответы:

18

Проблема в том, что вы обновляете существующее вращение, а не отслеживаете его и заменяете каждое обновление.

Когда вы обновляете вращение, оно объединяет ваше новое вращение со старым, что приводит к неожиданному поведению.

Решение состоит в том, чтобы отслеживать накопленное вращение и полностью сбрасывать вращение при каждом обновлении с новыми значениями.

Отдайте должное, я нашел ответ здесь: Ответы Unity: как заблокировать или установить камеры, вращение до нуля

Рабочий код:

using UnityEngine;
using System.Collections;

public class FirstPersonCam : MonoBehaviour {

    public float speedH = 2.0f;
    public float speedV = 2.0f;

    private float yaw = 0.0f;
    private float pitch = 0.0f;

    void Update () {
        yaw += speedH * Input.GetAxis("Mouse X");
        pitch -= speedV * Input.GetAxis("Mouse Y");

        transform.eulerAngles = new Vector3(pitch, yaw, 0.0f);
    }
}

Ключевые отличия:

  • Храните рыскание и тангаж как члены класса, а не как локальные переменные метода, чтобы вы могли отслеживать накопленные значения.
  • Используйте + = и / или - = для накопления каждого обновления.
  • Используйте eulerAngles (перезаписывать значение поворота при каждом обновлении) вместо Rotate (который применяет ваш новый поворот к старому).
Нечеткая логика
источник
Пожалуйста. Если это решение, которое я опубликовал, решило исходную проблему, с которой вы столкнулись, вы должны принять ее в качестве ответа. Если вы хотите получить помощь в решении вашей новой проблемы, вам следует опубликовать новый вопрос, чтобы держать вещи в порядке и с большей вероятностью, чтобы другие могли помочь вам или найти ваш вопрос, если у них возникла аналогичная проблема. Области комментариев не предназначены для расширенного диалога. Приветствия.
Нечеткая логика
0

Что делать, если вы сделаете камеру дочерним элементом пустого игрового объекта. Затем с помощью одного сценария вы управляете вращением пустого игрового объекта относительно вектора UP. (MouseX) С помощью другого сценария, прикрепленного к игровому объекту камеры, вы управляете вращением относительно правого вектора (MouseY).

dnk drone.vs.drones
источник