You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
147 lines
3.3 KiB
147 lines
3.3 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public abstract class State<T>
|
|
{
|
|
public StateHandler<T> Owner { get; private set; }
|
|
|
|
public void Initialize(StateHandler<T> owner)
|
|
{
|
|
Owner = owner;
|
|
OnInitialize();
|
|
}
|
|
|
|
protected virtual void OnInitialize() { }
|
|
|
|
public virtual void Enter() { }
|
|
public virtual void Excute() { }
|
|
public virtual void Exit() { }
|
|
}
|
|
|
|
public abstract class StateHandler<T> : MonoBehaviour
|
|
{
|
|
public T Excutor { get; private set; }
|
|
|
|
Dictionary<Type, State<T>> globalStates = new();
|
|
Dictionary<Type, State<T>> states = new();
|
|
|
|
public State<T> CurrentGlobalState { get; private set;}
|
|
public State<T> CurrentState { get; private set; }
|
|
|
|
public void Initialize(T excutor)
|
|
{
|
|
Excutor = excutor;
|
|
OnInitialize();
|
|
|
|
foreach (var state in globalStates.Values)
|
|
{
|
|
state.Initialize(this);
|
|
}
|
|
|
|
foreach (var state in states.Values)
|
|
{
|
|
state.Initialize(this);
|
|
}
|
|
|
|
if(CurrentGlobalState != null)
|
|
{
|
|
CurrentGlobalState.Enter();
|
|
}
|
|
|
|
if(CurrentState != null)
|
|
{
|
|
CurrentState.Enter();
|
|
}
|
|
}
|
|
|
|
protected abstract void OnInitialize();
|
|
|
|
private void Update()
|
|
{
|
|
CurrentGlobalState?.Excute();
|
|
CurrentState?.Excute();
|
|
}
|
|
|
|
public void AddGlobalState<TState>() where TState : State<T>
|
|
{
|
|
var state = Activator.CreateInstance<TState>();
|
|
|
|
globalStates.Add(typeof(TState), state);
|
|
if(CurrentGlobalState == null)
|
|
{
|
|
CurrentGlobalState = state;
|
|
}
|
|
}
|
|
|
|
public void AddState<TState>() where TState : State<T>
|
|
{
|
|
var state = Activator.CreateInstance<TState>();
|
|
|
|
states.Add(typeof(TState), state);
|
|
if(CurrentState == null)
|
|
{
|
|
CurrentState = state;
|
|
}
|
|
}
|
|
|
|
public bool TryGetGlobalState(Type type, out State<T> state)
|
|
{
|
|
return globalStates.TryGetValue(type, out state);
|
|
}
|
|
|
|
public bool TryGetGlobalState<TState>(out TState state) where TState : State<T>
|
|
{
|
|
state = null;
|
|
|
|
if(TryGetGlobalState(typeof(TState), out var baseState))
|
|
state = baseState as TState;
|
|
|
|
return state != null;
|
|
}
|
|
|
|
public bool TryGetState(Type type, out State<T> state)
|
|
{
|
|
return states.TryGetValue(type, out state);
|
|
}
|
|
|
|
public bool TryGetState<TState>(out TState state) where TState : State<T>
|
|
{
|
|
state = null;
|
|
|
|
if(TryGetState(typeof(TState), out var baseState))
|
|
state = baseState as TState;
|
|
|
|
return state != null;
|
|
}
|
|
|
|
public void ChangeGlobalState<TState>() where TState : State<T>
|
|
{
|
|
if(CurrentGlobalState != null)
|
|
{
|
|
CurrentGlobalState.Exit();
|
|
}
|
|
|
|
CurrentGlobalState = globalStates[typeof(TState)];
|
|
|
|
if(CurrentGlobalState != null)
|
|
{
|
|
CurrentGlobalState.Enter();
|
|
}
|
|
}
|
|
|
|
public void ChangeState<TState>() where TState : State<T>
|
|
{
|
|
if(CurrentState != null)
|
|
{
|
|
CurrentState.Exit();
|
|
}
|
|
|
|
CurrentState = states[typeof(TState)];
|
|
|
|
if(CurrentState != null)
|
|
{
|
|
CurrentState.Enter();
|
|
}
|
|
}
|
|
}
|