2023-10-18 02:36:56 +00:00
|
|
|
using System.Collections;
|
|
|
|
using Unity.VisualScripting;
|
|
|
|
using UnityEngine;
|
2023-10-26 08:52:06 +00:00
|
|
|
using UnityEngine.AI;
|
2023-10-18 02:36:56 +00:00
|
|
|
|
|
|
|
// ReSharper disable once CheckNamespace
|
|
|
|
namespace BlueWaterProject
|
|
|
|
{
|
|
|
|
public class NpcStateMachine : MonoBehaviour
|
|
|
|
{
|
2024-01-18 09:01:04 +00:00
|
|
|
public NavMeshAgent Agent { get; set; }
|
2023-10-18 02:36:56 +00:00
|
|
|
public INpcState CurrentState { get; private set; }
|
|
|
|
public NpcStateContext Context { get; private set; } = new NpcStateContext();
|
2023-10-26 08:52:06 +00:00
|
|
|
private Coroutine coroutine;
|
2023-10-18 02:36:56 +00:00
|
|
|
|
|
|
|
public void ChangeState(INpcState newState)
|
|
|
|
{
|
2023-10-30 15:45:05 +00:00
|
|
|
ClonePreviousState();
|
2023-10-26 08:52:06 +00:00
|
|
|
StopCoroutines();
|
2023-10-18 02:36:56 +00:00
|
|
|
CurrentState?.OnExit(this);
|
|
|
|
CurrentState = newState;
|
|
|
|
CurrentState.OnEnter(this);
|
|
|
|
}
|
2023-10-26 08:52:06 +00:00
|
|
|
|
2023-10-18 02:36:56 +00:00
|
|
|
public void Update()
|
|
|
|
{
|
|
|
|
CurrentState?.OnUpdate(this);
|
|
|
|
}
|
|
|
|
|
2023-10-26 08:52:06 +00:00
|
|
|
public void RestorePreviousState()
|
|
|
|
{
|
|
|
|
if (Context.PreviousState != null)
|
|
|
|
{
|
|
|
|
ChangeState(Context.PreviousState.Clone());
|
|
|
|
|
|
|
|
if (Context.PreviousDestination.HasValue)
|
|
|
|
{
|
2024-01-18 09:01:04 +00:00
|
|
|
Agent.destination = Context.PreviousDestination.Value; // 이전 목적지로 설정
|
2023-10-26 08:52:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2023-11-24 02:15:02 +00:00
|
|
|
// 목적지가 없는 경우, 다른 처리를 수행하거나 그대로 둠
|
2023-10-26 08:52:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// 이전 상태가 없거나 복제할 수 없는 경우, 기본 상태로 돌아가거나 다른 처리
|
|
|
|
Debug.LogWarning("No previous state to restore.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-18 02:36:56 +00:00
|
|
|
public void StartWaitCoroutine(float waitTime, UsuallyPointState state)
|
|
|
|
{
|
2023-10-26 08:52:06 +00:00
|
|
|
coroutine = StartCoroutine(WaitCoroutine(waitTime, state));
|
2023-10-18 02:36:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private IEnumerator WaitCoroutine(float waitTime, UsuallyPointState state)
|
|
|
|
{
|
|
|
|
yield return new WaitForSeconds(waitTime);
|
|
|
|
state.EndWait();
|
|
|
|
}
|
2023-10-26 08:52:06 +00:00
|
|
|
|
|
|
|
private void StopCoroutines()
|
2023-10-18 02:36:56 +00:00
|
|
|
{
|
2023-10-26 08:52:06 +00:00
|
|
|
if (coroutine != null)
|
|
|
|
{
|
|
|
|
StopCoroutine(coroutine);
|
|
|
|
coroutine = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-30 15:45:05 +00:00
|
|
|
private void ClonePreviousState()
|
2023-10-26 08:52:06 +00:00
|
|
|
{
|
|
|
|
if (CurrentState != null)
|
|
|
|
{
|
|
|
|
var clonedState = CurrentState.Clone();
|
|
|
|
if (clonedState != null)
|
|
|
|
{
|
|
|
|
Context.PreviousState = clonedState;
|
2024-01-18 09:01:04 +00:00
|
|
|
Context.PreviousDestination = Agent?.destination;
|
2023-10-26 08:52:06 +00:00
|
|
|
}
|
|
|
|
}
|
2023-10-18 02:36:56 +00:00
|
|
|
}
|
2023-10-30 15:45:05 +00:00
|
|
|
|
|
|
|
public void InstantiateObject(GameObject prefab, Vector3 position)
|
|
|
|
{
|
|
|
|
Instantiate(prefab, position, Quaternion.identity);
|
|
|
|
}
|
2024-01-02 08:17:10 +00:00
|
|
|
|
|
|
|
public void InstantiateUi(GameObject prefab, Transform parent)
|
|
|
|
{
|
|
|
|
Instantiate(prefab, parent);
|
|
|
|
}
|
2023-10-18 02:36:56 +00:00
|
|
|
}
|
|
|
|
}
|