172 lines
3.4 KiB
C#
172 lines
3.4 KiB
C#
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<CharacterController>();
|
|
_animator = GetComponent<Animator>();
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
} |