Files
beyond/Assets/Scripts/Biome/Animal.cs
2024-11-20 15:21:28 +01:00

147 lines
4.8 KiB
C#

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<Animator>();
m_Agent = GetComponent<NavMeshAgent>();
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;
}
}
}