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

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();
}
}
}