c#

时间:2018-08-23 16:23:45

标签: fsm

我正在努力争取正确的FSM实现(要在视频游戏中使用(Unity3d + c#))在线上有很多信息,还有太多选择,使您有些不知所措。我正在尝试为学习而设计自己的。 我想以状态可重用的方式实现它,所以我的想法如下: Class diagram

一个FSM类,负责更新状态。 一个运行某种逻辑并具有枚举的State类,该枚举表示使其进入下一个状态的条件。 在实例化fsm时,将定义状态转换。 在代码中,就像这样:

FSM aFsm = new FSM();
State idle = new IdleState(aFsm);
State working = new WorkingState(aFsm);
State resting = new RestingState(aFsm);
idle.AddTransition(idle.Condition.NEWJOB, working);
working.AddTransition(working.Condition.WEEKEND, resting);
working.AddTransition(working.Condition.FIRED, idle);
resting.AddTransition(resting.Condition.MONDAY, working);
aFsm.currentState(idle);

然后我们可以通过设置不同的输出状态来重用状态:

FSM anotherFsm = new FSM();
State idle = new IdleState(anotherFsm);
State working = new WorkingState(anotherFsm);
State partying = new PartyingState(anotherFsm);
idle.AddTransition(idle.Condition.NEWJOB, working);
working.AddTransition(working.Condition.WEEKEND, partying);
working.AddTransition(working.Condition.FIRED, idle);
partying.AddTransition(resting.Condition.MONDAY, working);
anotherFsm.currentState(idle);

然后我意识到我无法在抽象类State中定义方法AddTranstition(Condition condition,State state),因为每个枚举Condition对于每个具体状态都是不同的,并且不可能扩展枚举。

这些是我可以想到的一些解决方法:

1。在具体类中实现AddTransition方法,这似乎在复制代码:

public class IdleState: State
{
    public enum Condition { NEWJOB };
    public Dictionary<Condition, State> transitions;
    public void AddTranstition(Condition c, State s)
    { 
        transitions.Add(c,s) 
    }
//overrides for enter, tick y exit
}
...
idle.AddTransition(IdleState.Condition.NEWJOB, working);
...

2。使用所有状态的所有可能情况定义一个通用枚举,并创建一个从State派生并实现AddTransitions的类(GeneralEnum,State)。然后从那个中产阶级中得出状态。

public class WorkerState : State
    {
    public enum Condition { NEWJOB, WEEKEND, MONDAY, .... };
    public Dictionary< Condition, State > transitions;
    public void addTranstition( Condition c, State s) 
    { 
        transitions.Add(c,s);
    }
}
public class IdleState : WorkerState
{
//overrides for enter, tick y exit
}
...
idle.AddTransition(IdleState.Condition.NEWJOB, working);
...

3。使用Integers而不是enums,并且在具体的State类中具有公共只读值:在抽象类中,我将声明方法AddTransition(int condition,State state)。这些状态具有公共属性,例如public int WEEKEND = 0,星期一= 1,依此类推。

public abstract class State 
{
    public Dictionary< int, State > transitions;
    public void addTranstition( int c, State s) 
    { 
        transitions.Add(c,s) 
    }
// Declare Exit,Tick,Enter methods.
}

public class IdleState : State
{
    realdonly int NEWJOB = 0;
...
}

..
IdleState idle = new IdleState(fsm);
idle.AddTransition(idle.NEWJOB, workingState);
..

所有这些解决方案对我来说都像黑客一样,所以我想我缺少了一些东西,但是我不知道如何解决而不增加复杂性。

任何帮助将不胜感激!

0 个答案:

没有答案