统一耦合导航和动画

时间:2018-10-22 19:35:04

标签: c# unity3d unity3d-mecanim

因此,我已经实现了本教程:https://docs.unity3d.com/Manual/nav-CouplingAnimationAndNavigation.html简而言之。几乎意味着我使用的是2d freeform directional混合类型,而不是他们使用的simple directional。问题是velxvely(大多数是此值)的值在波动。因此,举例来说,当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);

金田作品。这意味着它仅抖动70%的时间,而不是始终抖动。有谁知道实现相同效果的更好方法?

1 个答案:

答案 0 :(得分:0)

好...对感兴趣的人: 在不对文档中的脚本进行一些修改的情况下,我不是无法解决抖动问题的,我的更改如下:

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;
    }
}

还有一些错误,例如如果您允许速度不断升高或降低,则在单击飞机后的某个时刻,代理会开始表现出怪异行为,并且上面的问题已将其修复。 至于最上面的值-它们与我在示例项目中可以找到的值匹配,因此,如果您遇到类似的问题,但动画不同,则可能必须在此处调整数字。