Unity C#: управление камерой с помощью автоматического позиционирования и мыши

Я обычно не пишу здесь, но мне потребовались часы, чтобы понять это, и я уже искал в сети, но не смог найти ответ. Я желаю, чтобы кто-то мог помочь мне здесь. Я новичок, и я впервые пытаюсь объединить два типа управления камерой от третьего лица, которые следуют за движением игроков в Unity C#:

  1. Камера перемещается в предопределенную позицию и поворачивается при движении игрока (без мышки)
  2. Мышь Look активируется, когда удерживается кнопка мыши, и поэтому камера вращается в соответствии с движением мыши, независимо от того, изменяется позиция игрока или нет

Это почти работает, за исключением того, что я не могу сбросить Mouse Look к его первому предустановленному значению. После того, как проигрыватель отпускает кнопку мыши, начинает действовать код для #1, и камера, похоже, возвращается к своему виду по умолчанию. Но, продолжая смотреть с помощью мыши, я заметил, что камера всегда возвращается в последнюю позицию и вращение было отключено. Мне нужно, чтобы он вернулся в исходное заранее заданное положение и вращение еще до того, как Игрок активирует свой первый Мышь, так что это не слишком дезориентирует Игрока.

Я попробовал несколько кодов, но не смог заставить его работать, поэтому я удалил нерабочие строки и просто разместил те, которые, я думаю, применимы. Пожалуйста, обратитесь к моему коду ниже. Был бы признателен, если кто-то может мне помочь. Заранее спасибо!

Изменить: Обновил код, чтобы иметь два метода управления камерой и добавил предложенный код для сброса текущих значений X и Y. Комментарий / раскомментируйте каждый вызов метода для проверки. Но у меня все еще есть проблема с невозможностью сгладить масштабирование мышки.

Окончательное редактирование: я снова обновил приведенный ниже код, очистил его и включил предложенные изменения. Код должен теперь быть полностью работоспособным и не иметь дрожания. Спасибо за помощь!:-)

Последнее финальное редактирование: добавлено "Масштабирование поля зрения" с помощью колеса мыши, после чего код завершен.

using UnityEngine;
using System.Collections;

public class PlayerViewController : MonoBehaviour {

    // General Vars
    public Transform targetFollow;
    private bool lookAround = false;

    // For SmoothDampFollow
    public Vector3 followDefaultDistance = new Vector3 (0f, 12.0f, -20f);
    public float followDistanceDamp = 0.2f;
    public Vector3 followVelocity = Vector3.one;

    // For Camera Orbit
    public float orbitDistance = 20.0f;
    public float orbitDamp = 5.0f;
    private const float angleMinY = 7.0f;
    private const float angleMaxY = 50.0f;    
    private float currentX = 7.0f;
    private float currentY = 50.0f;

    // For Zooming Field Of View
    public float FOVmin = 50.0f;
    public float FOVmax = 100.0f;
    public float mouseWheelSpeed = 5.0f;

    void Update () {

        if (Input.GetMouseButtonDown (1)) {

            currentX = transform.eulerAngles.y;
            currentY = transform.eulerAngles.x;

        }

        if (Input.GetMouseButton (1)) {

            lookAround = true;

        } else {

            lookAround = false;

        }

        ZoomFOV ();

    }

    void FixedUpdate () {

        if (lookAround) {

            CameraOrbit ();

        } else {

            SmoothDampFollow ();

        }

    }

    void ZoomFOV () {

        if (Input.GetAxis ("Mouse ScrollWheel") > 0) {

            GetComponent<Camera> ().fieldOfView =  GetComponent<Camera> ().fieldOfView - mouseWheelSpeed;

            if (GetComponent<Camera> ().fieldOfView <= FOVmin) { GetComponent<Camera> ().fieldOfView = FOVmin; }

        } else if (Input.GetAxis ("Mouse ScrollWheel") < 0) {

            GetComponent<Camera> ().fieldOfView = GetComponent<Camera> ().fieldOfView + mouseWheelSpeed;

            if (GetComponent<Camera> ().fieldOfView >= FOVmax) { GetComponent<Camera> ().fieldOfView = FOVmax; }

        }

    }

    void SmoothDampFollow () {

        if (!targetFollow) {

            return;

        } else {

            Vector3 wantedPosition = targetFollow.position + (targetFollow.rotation * followDefaultDistance);
            transform.position = Vector3.SmoothDamp (transform.position, wantedPosition, ref followVelocity, followDistanceDamp);
            transform.LookAt (targetFollow, targetFollow.up);

        }

    }

    void CameraOrbit () {

        if (!targetFollow) {

            return;

        } else {

            currentX += Input.GetAxis ("Mouse X");
            currentY += Input.GetAxis ("Mouse Y");
            currentY = Mathf.Clamp (currentY, angleMinY, angleMaxY);
            Vector3 dir = new Vector3 (0, 0, -orbitDistance);
            Quaternion rotation = Quaternion.Euler (currentY, currentX, 0);
            Vector3 wantedPosition = targetFollow.position + rotation * dir;
            transform.position = Vector3.Lerp (transform.position, wantedPosition, Time.deltaTime * orbitDamp);
            transform.LookAt (targetFollow.position);

        }

    }

}

1 ответ

Решение

Обновлено: попробуйте это

void LateUpdate()
{

    if (lookAround)
    {

        currentX += Input.GetAxisRaw("Mouse X");
        currentY += Input.GetAxisRaw("Mouse Y");
        currentY = Mathf.Clamp(currentY, angleMinY, angleMaxY);
        Vector3 dir = new Vector3(0, 0, -distance);
        Quaternion rotation = Quaternion.Euler(currentY, currentX, 0);

        Vector3 wantedPosition = target.position + rotation * dir;
        transform.position = Vector3.Lerp(transform.position, wantedPosition, Time.deltaTime * damping);

        camTransform.LookAt(target.position);

    }
        ...

А также

void Update()
{
    // Here
    if (Input.GetMouseButtonDown(1))
    {
        currentX = transform.eulerAngles.y;
        currentY = transform.eulerAngles.x;
    }
    if (Input.GetMouseButton(1))
    { 
        ...

То, что я сделал, я сбросил currentX и currentY к их текущим значениям eulerangle при нажатии мыши в Update(). И я добавил позицию Lerp в нужную позицию lookAround в LateUpdate()

РЕДАКТИРОВАТЬ:

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

Попробуйте это изменение

void CameraOrbit()
{
    currentX += Input.GetAxisRaw("Mouse X");
    currentY += Input.GetAxisRaw("Mouse Y");
    currentY = Mathf.Clamp(currentY, angleMinY, angleMaxY);
    Vector3 dir = new Vector3(0, 0, -distance);
    Quaternion rotation = Quaternion.Euler(currentY, currentX, 0);

    // -->
    Vector3 wantedPosition = target.position + rotation * dir;
    transform.position = Vector3.Lerp(transform.position, wantedPosition, Time.deltaTime * damping);
    // <--

    camTransform.LookAt(target.position);
}
Другие вопросы по тегам