Untitled
unknown
csharp
a year ago
3.4 kB
4
Indexable
using UnityEngine.AI; using UnityEngine; using System.Collections; [DisallowMultipleComponent] [RequireComponent(typeof(NavMeshAgent), typeof(Animator))] public class Navigation : MonoBehaviour { private NavMeshTriangulation Triangulation; private NavMeshAgent Agent; private Animator Animator; [SerializeField] [Range(0f, 10f)] private float WaitDelay = 1f; private Vector2 Velocity; private Vector2 SmoothDeltaPosition; private void Awake() { Agent = GetComponent<NavMeshAgent>(); Animator = GetComponent<Animator>(); Triangulation = NavMesh.CalculateTriangulation(); Animator.applyRootMotion = true; Agent.updatePosition = false; Agent.updateRotation = true; } private void Start() { GoToRandomPoint(); } public void GoToRandomPoint() { StartCoroutine(DoMoveToRandomPoint()); } private void OnAnimatorMove() { Vector3 rootPosition = Animator.rootPosition; rootPosition.y = Agent.nextPosition.y; transform.position = rootPosition; Agent.nextPosition = rootPosition; } private void Update() { SynchronizeAnimatorAndAgent(); } private void SynchronizeAnimatorAndAgent() { Vector3 worldDeltaPosition = Agent.nextPosition - transform.position; worldDeltaPosition.y = 0; // Map 'worldDeltaPosition' to local space float dx = Vector3.Dot(transform.right, worldDeltaPosition); float dy = Vector3.Dot(transform.forward, worldDeltaPosition); Vector2 deltaPosition = new Vector2(dx, dy); // Low-pass filter the deltaMove float smooth = Mathf.Min(1, Time.deltaTime / 0.1f); SmoothDeltaPosition = Vector2.Lerp(SmoothDeltaPosition, deltaPosition, smooth); Velocity = SmoothDeltaPosition / Time.deltaTime; if (Agent.remainingDistance <= Agent.stoppingDistance) { Velocity = Vector2.Lerp(Vector2.zero, Velocity, Agent.remainingDistance); } bool shouldMove = Velocity.magnitude > 0.5f && Agent.remainingDistance > Agent.stoppingDistance; Animator.SetBool("move", shouldMove); Animator.SetFloat("locomotion", shouldMove ? 1 : 0); //float deltaMagnitude = worldDeltaPosition.magnitude; //if (deltaMagnitude > Agent.radius / 2) //{ // transform.position = Vector3.Lerp(Animator.rootPosition, Agent.nextPosition, smooth); //} } public void StopMoving() { Agent.isStopped = true; StopAllCoroutines(); } private IEnumerator DoMoveToRandomPoint() { Agent.enabled = true; Agent.isStopped = false; WaitForSeconds Wait = new WaitForSeconds(WaitDelay); while (true) { int index = Random.Range(1, Triangulation.vertices.Length - 1); Agent.SetDestination(Vector3.Lerp( Triangulation.vertices[index], Triangulation.vertices[index + (Random.value > 0.5f ? -1 : 1)], Random.value) ); yield return null; yield return new WaitUntil(() => Agent.remainingDistance <= Agent.stoppingDistance); yield return Wait; } } }
Editor is loading...
Leave a Comment