using System.Collections; using System.Collections.Generic; //using UnityEditor.Presets; using UnityEngine; using UnityEngine.AI; namespace Beyond { [RequireComponent(typeof(NavMeshAgent))] [RequireComponent(typeof(Animator))] public class Animal : MonoBehaviour { enum State { IDLE, WALK, RUN }; State m_state; UnityEngine.AI.NavMeshAgent m_Agent; Vector3 startPosition; Vector3 destination; Animator m_Animator; public float StoppingDistance = 2f; float m_timer = 0f; float m_targetTime = 0f; public float m_wanderRange = 40f; public float m_minPlayerDistance = 10f; int m_maxTrials = 15; GameObject m_Player; // Start is called before the first frame update void Start() { m_Animator = GetComponent(); m_Agent = GetComponent(); startPosition = transform.position; m_Agent.acceleration = 50; m_Agent.angularSpeed = 1000; m_Agent.stoppingDistance = StoppingDistance; SetState(State.IDLE); m_Player = GameObject.FindGameObjectWithTag("Player"); } void SetState(State state) { m_Animator.SetInteger("Random", Random.Range(0, 2)); switch (state) { case State.IDLE: m_Animator.SetBool("IDLE", true); m_Animator.SetBool("WALK", false); m_Animator.SetBool("RUN", false); m_targetTime = Random.Range(5f, 10f); break; case State.WALK: m_Animator.SetBool("IDLE", false); m_Animator.SetBool("WALK", true); m_Animator.SetBool("RUN", false); if (!FindAPath(m_wanderRange, false)) { Debug.LogError("Animal AI: didn't find a path"); } break; case State.RUN: m_Agent.speed = 12f; m_Animator.SetBool("IDLE", false); m_Animator.SetBool("WALK", false); m_Animator.SetBool("RUN", true); if (!FindAPath(m_wanderRange, true)) { Debug.LogError("Animal AI: didn't find a path"); } break; } m_timer = 0f; m_state = state; } void OnAnimatorMove() { m_Agent.velocity = m_Animator.deltaPosition / Time.deltaTime; } bool FindAPath(float range, bool awayFromPlayer = true) { for (int i = 0; i < m_maxTrials; i++) { Vector3 dest; if (awayFromPlayer) { dest = transform.position + (transform.position - m_Player.transform.position).normalized * range; } else { dest = startPosition; } dest += new Vector3(Random.Range(-range * .5f - 2f, range * .5f + 2f), 0, Random.Range(-range * .5f - 2f, range * .5f + 2f)); NavMeshPath path = new NavMeshPath(); m_Agent.CalculatePath(dest, path); if (path.status != NavMeshPathStatus.PathInvalid) { m_Agent.SetPath(path); destination = dest; return true; } } return false; } // Update is called once per frame void Update() { switch (m_state) { case State.IDLE: if (m_timer > m_targetTime) { SetState(State.WALK); } break; case State.WALK: if (m_Agent.remainingDistance < StoppingDistance) { SetState(State.IDLE); } break; case State.RUN: if (m_Agent.remainingDistance < StoppingDistance) { SetState(State.RUN); } break; } if (m_state != State.RUN) { float dist = (m_Player.transform.position - transform.position).magnitude; if (dist < m_minPlayerDistance) { if (!FindAPath(m_wanderRange, true)) { Debug.LogError("Animal AI: didn't find a path"); } } } m_timer += Time.deltaTime; } } }