Сочетание навигации и анимации в единстве - PullRequest
0 голосов
/ 22 октября 2018

Итак, я реализовал этот урок: https://docs.unity3d.com/Manual/nav-CouplingAnimationAndNavigation.html почти до буквы.Почти означает, что я использую тип 2d freeform directional blend вместо simple directional, который они используют.Проблема в том, что значения для velx и vely (в основном это) колеблются.Так, например, когда vely растет, он в какой-то момент достигнет 1, но до этого он пойдет так:

..., 0,5, 0,6, 0,5, 0,7, 0,4, 0,6, 0,8

Надеюсь, вы поняли мою точку зрения - тенденция растет, но иногда снижается.Это заставляет мою анимацию дрожать, потому что дерево смешивания очень быстро перемещается между состояниями.После некоторого времени экспериментов я обнаружил, что в моем случае в качестве делителя в выражении, вычисляющем переменную smooth, используется число 7, вот так:

var smooth = Mathf.Min(1.0f, Time.deltaTime / 7f);

Kinda работает.Это означает, что он дрожит только 70% времени, а не всегда.Кто-нибудь знает лучший способ достижения того же эффекта?

1 Ответ

0 голосов
/ 03 ноября 2018

Ооочень ... Для тех, кто заинтересован: я не смог решить дрожание без каких-либо изменений сценария из документации, и мои изменения следующие:

using UnityEngine;
using UnityEngine.AI;

[RequireComponent (typeof (NavMeshAgent))]
[RequireComponent (typeof (Animator))]
public class LocomotionSimpleAgent : MonoBehaviour {

    private const float SmoothingCoefficient = .15f;

    [SerializeField] private float _velocityDenominatorMultiplier = .5f;
    [SerializeField] private float _minVelx = -2.240229f;
    [SerializeField] private float _maxVelx = 2.205063f;
    [SerializeField] private float _minVely = -2.33254f;
    [SerializeField] private float _maxVely = 3.70712f;

    public Vector3 Goal {
        get { return _agent.destination; }
        set {
            _agent.destination = value;
            _smoothDeltaPosition = Vector2.zero;
        }
    }

    private NavMeshAgent _agent;
    private Animator _animator;
    private Vector2 _smoothDeltaPosition;

    public void Start() {
        _animator = GetComponent<Animator>();
        _agent = GetComponent<NavMeshAgent>();
        _agent.updatePosition = false;
        _smoothDeltaPosition = default(Vector2);
        Goal = transform.position;
    }

    public void FixedUpdate() {
        var worldDeltaPosition = _agent.nextPosition - transform.position;
        var dx = Vector3.Dot(transform.right, worldDeltaPosition);
        var dy = Vector3.Dot(transform.forward, worldDeltaPosition);
        var deltaPosition = new Vector2(dx, dy);
        var smooth = Time.fixedDeltaTime / SmoothingCoefficient;

        _smoothDeltaPosition = Vector2.Lerp(_smoothDeltaPosition, deltaPosition, smooth);

        var velocity = _smoothDeltaPosition / (Time.fixedDeltaTime * _velocityDenominatorMultiplier);
        var shouldMove = _agent.remainingDistance > .1f;
        var x = Mathf.Clamp(Mathf.Round(velocity.x * 1000) / 1000, _minVelx, _maxVelx);
        var y = Mathf.Clamp(Mathf.Round(velocity.y * 1000) / 1000, _minVely, _maxVely);

        _animator.SetBool("move", shouldMove);
        _animator.SetFloat("velx", x);
        _animator.SetFloat("vely", y);

        if (worldDeltaPosition.magnitude > _agent.radius / 16 && shouldMove) {
            _agent.nextPosition = transform.position + 0.1f * worldDeltaPosition;
        }
    }

    public void OnAnimatorMove() {
        var position = _animator.rootPosition;

        position.y = _agent.nextPosition.y;
        transform.position = position;
    }
}

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

...