- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.AI;
- [RequireComponent(typeof(NavMeshAgent))]
- public class NPCController : MonoBehaviour
- {
- [SerializeField] private Waypoints waypoints;
- private Collider agentCollider;
- private NavMeshAgent agent;
- private Animator animator;
- private Vector2 Velocity;
- private Vector2 SmoothDeltaPosition;
- private FieldOfView agentFOV;
- private Awareness agentAwareness;
- private Dictionary<string, object> agentBeliefs;
- public Animator Animator => animator;
- public NavMeshAgent Agent => agent;
- public Collider AgentCollider => agentCollider;
- public Waypoints Waypoints => waypoints;
- public FieldOfView AgentFOV => agentFOV;
- public Awareness AgentAwareness => agentAwareness;
- public Dictionary<string, object> AgentBeliefs => agentBeliefs;
- void Awake()
- {
- agent = GetComponent<NavMeshAgent>();
- animator = GetComponent<Animator>();
- agentCollider = GetComponent<Collider>();
- agentFOV = GetComponentInChildren<FieldOfView>();
- agentAwareness = GetComponentInChildren<Awareness>();
- }
-
- void Start()
- {
- agent.stoppingDistance = 0.1f;
- agent.updatePosition = false;
- animator.applyRootMotion = true;
- agent.updateRotation = true;
- }
-
- void Update()
- {
- Debug.Log("IsMoving: " + animator.GetBool("IsMoving"));
- SynchronizeAnimatoraAndAgent();
- }
- private void OnAnimatorMove()
- {
- Vector3 rootPosition = animator.rootPosition;
- rootPosition.y = agent.nextPosition.y;
- transform.position = rootPosition;
- agent.nextPosition = rootPosition;
- }
-
- private void SynchronizeAnimatoraAndAgent()
- {
-
- Vector3 worldDeltaPosition = agent.nextPosition - transform.position;
- worldDeltaPosition.y = 0f;
- float dx = Vector3.Dot(transform.right, worldDeltaPosition);
- float dy = Vector3.Dot(transform.forward, worldDeltaPosition);
- Vector2 deltaPosition = new Vector2(dx, dy);
- 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 / agent.stoppingDistance);
- }
- bool shouldMove = Velocity.magnitude > 0.5f && agent.remainingDistance > agent.stoppingDistance;
- animator.SetBool("IsMoving", shouldMove);
- animator.SetFloat("Velocity", Velocity.magnitude);
- animator.SetFloat("VelX", Velocity.x);
- animator.SetFloat("VelY", Velocity.y);
- float deltaMagnitude = worldDeltaPosition.magnitude;
- if (deltaMagnitude > agent.radius / 2f)
- {
- transform.position = Vector3.Lerp(animator.rootPosition, agent.nextPosition, smooth);
- }
- }
- public void AddAgentBelief(string key, object value)
- {
-
- if (!agentBeliefs.ContainsKey(key))
- {
-
- agentBeliefs.Add(key, value);
- }
- else
- {
-
- agentBeliefs[key] = value;
- }
- }
- public object GetAgentBelief(string key)
- {
-
- if (agentBeliefs.ContainsKey(key))
- {
-
- return agentBeliefs[key];
- }
- else
- {
-
- Debug.LogWarning($"The {key} doesn't exist in {nameof(agentBeliefs)}");
- return null;
- }
- }
- }