[Unity] Попытка реализовать контроллер от третьего лица (второе, мобильное управление ①)

[Unity] Попытка реализовать контроллер от третьего лица (второе, мобильное управление ①)


[Заявление] Этот контроллер от третьего лица является репродукцией контроллера от третьего лица в активе Unity Star. При необходимости вы можете напрямую загрузить актив и изучить его. Мне лично не нравится, когда я заново изобретаю велосипед, но у официального контроллера есть некоторые неудовлетворительные ошибки, когда я его использую. Тем не менее, контроллер выглядит довольно хорошо для меня, и хотя бесшовная анимация невозможна, персональные проекты должны сначала выяснить, как заставить ее двигаться.
[Версия] Этот проект основан на версии Unity [2021.3lts].

Выберите, как двигаться

На данный момент есть два основных: 1.rig+collider.2.CharactorController
Здесь, чтобы изучить и учесть, что тип самоделки не требует слишком частого физического моделирования, я выбрал второй.

Использовать Контроллер Персонажей

[Примечание] Вот мой код, постепенно разумный мыслительный процесс, если вы хотите, чтобы код сразу перетащили в конец.

двигаться вверх

Сначала смонтируйте часть ввода, которую мы подготовили ранее для персонажа, который будет использоваться позже.
Затем создайте MoveController и прикрепите созданный скрипт к персонажу.
Чтобы смонтировать CharacterController для персонажа,
мы используем метод Move для CharacterController:

Vector3 targetDir = Vector3.forward;
_characterController.Move(targetDir);

Вернувшись в игровой тест, персонаж движется вперед.

направление управления

var _currentInput = new Vector3(_inputsMassage.move.x, 0, _inputsMassage.move.y);
Vector3 targetDir = currentInput;
_characterController.Move(targetDir * Time.deltaTime);

Я могу двигаться вперед-назад, влево-вправо, с тестом проблем нет, тогда мне нужно о чем-то подумать

думаю о поведении персонажа

В любой момент, пока мы нажимаем вперед, персонаж должен идти впереди нас. Нам нужно только извлечь размер движения.Сначала
определите скорость ходьбы, а затем оцените, есть ли ввод:

public float walkSpeed = 1.5f;
private float _currentSpeed;
//首先将移动速度赋予临时变量,考虑到有可能在其他地方使用,我们将其存储起来
_currentSpeed = walkSpeed;
//判断是否进行移动输入
if (_inputsMassage.move == Vector2.zero) _currentSpeed = 0;

Мы разделим персонажа на несколько состояний, и сначала займемся ходьбой.

_characterController.Move(targetDir * _currentSpeed * Time.deltaTime);

В фиксированном состоянии его скорость движения фиксирована, поэтому мы думаем, что входное движение предназначено только для направления, а размер определяется состоянием.
Мы нормализуем _currentInput выше, чтобы получить его единичный вектор (на самом деле он похож на единичный вектор, мы просто подтверждаем это)

var _currentInput = new Vector3(_inputsMassage.move.x, 0, _inputsMassage.move.y).normalized;

Итак, теперь рассмотрим случай нажатия влево и вправо:
при нажатии влево или вправо наш персонаж должен совершать поворот,

if (_inputsMassage.move!=Vector2.zero)
{
    
    
		_targetRotation = Mathf.Atan2(currentInput.x, currentInput.z) * Mathf.Rad2Deg;
}

Тогда targetDir выше должен соответствовать этому углу:

 Vector3 targetDir = Quaternion.Euler(0.0f, _targetRotation, 0.0f) * Vector3.forward;

Здесь угол Эйлера используется для поворота вперед на требуемый угол.
Мы протестировали и обнаружили, что между этими и предыдущими эффектами нет никакой разницы, зачем делать столько бессмысленных вещей?
Это подготовлено для того, чтобы камера позже контролировала направление, конечно же, в текущем коде такого контента нет;
ладно, до сих пор мы только определяли направление движения персонажа. Но наш персонаж не меняет своего направления. Давайте займемся этим дальше.
Мы используем Mathf.SmoothDampAngle для поворота

[Tooltip("角色光滑旋转时间")]
private float RotationSmoothTime = 0.12f;
[Tooltip("在角色光滑旋转过程中的速度")]
private float _rotationVelocity;

if (_inputsMassage.move!=Vector2.zero)
{
    
    
		_targetRotation = Mathf.Atan2(currentInput.x, currentInput.z) * Mathf.Rad2Deg;
		float rotation = Mathf.SmoothDampAngle(transform.eulerAngles.y, _targetRotation, ref _rotationVelocity,RotationSmoothTime);
		transform.rotation = Quaternion.Euler(0.0f, rotation, 0.0f);
        }

На этом заканчивается первая подвижная часть. Не волнуйтесь, в мобильной версии еще много нерешенных проблем, и мы будем решать их шаг за шагом.

код

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class ThirdPlayerMoveController : MonoBehaviour
{
    
    
    CharacterController _characterController;

    PlayerInputsMassage _inputsMassage;

    [Header("设置")]
    [Tooltip("这将决定普通行走时的速度")]
    public float walkSpeed = 1.5f;

    private float _currentSpeed;
    private float _targetRotation = 0.0f;
    [Tooltip("角色光滑旋转时间")]
    private float RotationSmoothTime = 0.12f;
    [Tooltip("在角色光滑旋转过程中的速度")]
    private float _rotationVelocity;

    // Start is called before the first frame update
    void Start()
    {
    
    
        _characterController = GetComponent<CharacterController>();
        _inputsMassage = GetComponent<PlayerInputsMassage>();
    }

    private void FixedUpdate()
    {
    
    
        Move();
    }
    private void Move()
    {
    
    
        //首先将移动速度赋予临时变量,考虑到有可能在其他地方使用,我们将其存储起来
        _currentSpeed = walkSpeed;
        //判断是否进行移动输入
        if (_inputsMassage.move == Vector2.zero) _currentSpeed = 0;

        var currentInput = new Vector3(_inputsMassage.move.x, 0, _inputsMassage.move.y).normalized;

        if (_inputsMassage.move!=Vector2.zero)
        {
    
    
            _targetRotation = Mathf.Atan2(currentInput.x, currentInput.z) * Mathf.Rad2Deg;
            float rotation = Mathf.SmoothDampAngle(transform.eulerAngles.y, _targetRotation, ref _rotationVelocity,
                RotationSmoothTime);
            transform.rotation = Quaternion.Euler(0.0f, rotation, 0.0f);
        }

        Vector3 targetDir = Quaternion.Euler(0.0f, _targetRotation, 0.0f) * Vector3.forward;

        _characterController.Move(targetDir.normalized * _currentSpeed * Time.deltaTime);
        //TODO:这里的Move可以执行垂直方向的速度,直接加上垂直的Vector就可以
    }
}

Guess you like

Origin blog.csdn.net/weixin_52540105/article/details/127702805