我需要在另一个子类AIContext中引用一个特定的接口IState的子类AIState,该子类与IState中的通用类型使用相同的接口类。我在正确解析方面遇到了问题。
我正在构建一个基于上下文的Statemachine,这意味着每个状态+SM存在一次。意味着每个状态+SM只存在一次,使用SM的人只需调用类中的Function,并以context作为Parameter。
我有接口
public interface IStateContext
{
IState<IStateContext> CurrentState { get; }
}
Interface IState <T> where T:IStateContext {
Execute(T context);
}
我为AI行为实现我的状态,用一个 颜色 来实现可视化。
public class AIState : IState <AIContext> {
Color stateColor;
Execute(AIState) { //behavior}
}
好,现在问题开始了 我只能创建这样的AIContext。
[System.Serializable]
public class AIContext : IStateContext
{
public AI ai;
public Animator animator;
public NavMeshAgent agent;
private IState<IStateContext> activeState;
public IState<IStateContext> ActiveState
{
get => activeState;
set => activeState = value;
}
}
我需要活动状态是一个AIState,但它不允许子类... ... 我希望能够访问 (AIContext) context.ActiveState.color ! 但只要它是一个IState,它就没有 "color "这个信息。
尝试& 错误1:我未能解析它。它就是不让我这样做。
Try & Error 2:我不能在IStateContext里面使用一个是IState的通用类型,因为那样的话它只是一个通用类型声明的循环......。 AIState : IState<AIContext<AIState<AI .....>>>
恐怕是结构问题?希望有人能看到。
编辑:问题不只是颜色,我以后可能要实现其他变量。是解析的问题。我的StateMAchine只是使用Generalisations (IState --> Executes them with IStateContext)。我只是没有看到一个选项可以让我在上下文中保留当前的活动状态。
IStateContext有一个IState CurrentState,其中T:IStateContext,而在AIState中我需要一个AIContext CurrentState。我就是无法解析它!
方法A
如果你可以强迫任何实现了 IState
介面,以便有一个 StateColor
,你可以直接添加一个属性 StateColor
到您的界面。
public interface IState<T> where T : IStateContext
{
Color StateColor { get; set; }
void Execute(T context);
}
public class AIState : IState<AIContext>
{
public Color StateColor { get; set; }
public void Execute(AIContext context) { }
}
[Serializable]
public class AIContext : IStateContext
{
private IState<IStateContext> activeState;
public IState<IStateContext> ActiveState
{
get => activeState;
set => activeState = value;
}
public IState<IStateContext> CurrentState => throw new NotImplementedException();
}
这将允许您访问 StateColor
你的 AIContext
的财产 ActiveState
:
var aiContext = new AIContext();
var stateColor = aiContext.ActiveState.StateColor;
办法B
如果你不想修改 IState
接口,另一种选择是创建一个新的接口,如 IAIState
的接口,实现 IState
接口。
public interface IAIState<T> : IState<T> where T : IStateContext
{
Color StateColor { get; set; }
}
public interface IState<T> where T : IStateContext
{
void Execute(T context);
}
那么你只需要改变一下 activeState
领域和 ActiveState
属性为 IAIState
...
[Serializable]
public class AIContext : IStateContext
{
private IAIState<IStateContext> activeState;
public IAIState<IStateContext> ActiveState
{
get => activeState;
set => activeState = value;
}
IState<IStateContext> IStateContext.CurrentState { get; }
}
...访问 StateColor
的 ActiveState
就像上面提到的那样。
var aiContext = new AIContext();
var stateColor = aiContext.ActiveState.StateColor;