using System.Collections; using System.Collections.Generic; using UnityEngine; public class AnimalChase : MonoBehaviour { public enum AnimalType { Cat, Dog } public AnimalType animalType; public AnimalChase otherAnimal; public PlayZone zone; public float walkSpeed = 2f; public float runSpeed = 4f; public float catchDistance = 1.5f; public float restTime = 1f; private CharacterController _controller; private Animator _animator; private bool _isChasing; private bool _isResting; private bool _isRunningAway; private Vector3 _targetPoint; private float _gravity = -9.8f; private float _verticalVelocity; private void Awake() { _controller = GetComponent(); _animator = GetComponent(); } private void Start() { if (animalType == AnimalType.Dog) StartChasing(); } private void Update() { if (zone == null || otherAnimal == null) return; ApplyGravity(); if (_isResting) { UpdateAnimator(0f, 0f); return; } if (_isChasing) { ChaseTarget(); } else if (_isRunningAway) { RunToPoint(); } else { UpdateAnimator(0f, 0f); } } private void ChaseTarget() { MoveTo(otherAnimal.transform.position, runSpeed); float dist = Vector3.Distance(transform.position, otherAnimal.transform.position); if (dist <= catchDistance) { StartCoroutine(RestAndSwitch()); } } private void RunToPoint() { MoveTo(_targetPoint, walkSpeed); if (Vector3.Distance(transform.position, _targetPoint) < 0.5f) { _isRunningAway = false; } } private void MoveTo(Vector3 worldTarget, float speed) { worldTarget = zone.ClampToZone(worldTarget); Vector3 dir = worldTarget - transform.position; dir.y = 0f; float distance = dir.magnitude; if (distance < 0.1f) { UpdateAnimator(0f, 0f); return; } dir.Normalize(); Vector3 move = dir * speed; move.y = _verticalVelocity; _controller.Move(move * Time.deltaTime); transform.rotation = Quaternion.LookRotation(dir); if (speed >= runSpeed * 0.9f) { UpdateAnimator(1f, 1f); } else { UpdateAnimator(1f, 0f); } } private IEnumerator RestAndSwitch() { _isChasing = false; _isResting = true; UpdateAnimator(0f, 0f); yield return new WaitForSeconds(restTime); _isResting = false; _targetPoint = zone.GetRandomPoint(); _isRunningAway = true; otherAnimal.StartChasing(); } public void StartChasing() { _isChasing = true; _isRunningAway = false; _isResting = false; } private void UpdateAnimator(float vert, float state) { _animator.SetFloat("Vert", vert); _animator.SetFloat("State", state); } private void ApplyGravity() { if (_controller.isGrounded) { _verticalVelocity = -1f; } else { _verticalVelocity += _gravity * Time.deltaTime; } } }