C# 如何编写状态机,使我不';你不必用99%的相似代码复制州吗?
我正在制作一个城市管理游戏,工人完全由国家机器控制。我有一个“问题”,我发现我自己重写了很多99%相似的州。通常情况下,某些状态的唯一区别是完成时应转到哪个状态 例如,下面的状态用于交付资源,这是所有职业都会做的事情,但我有一个为每个职业编写一个特定的状态,因为它们在完成时都会导致不同的状态C# 如何编写状态机,使我不';你不必用99%的相似代码复制州吗?,c#,unity3d,logic,state-machine,C#,Unity3d,Logic,State Machine,我正在制作一个城市管理游戏,工人完全由国家机器控制。我有一个“问题”,我发现我自己重写了很多99%相似的州。通常情况下,某些状态的唯一区别是完成时应转到哪个状态 例如,下面的状态用于交付资源,这是所有职业都会做的事情,但我有一个为每个职业编写一个特定的状态,因为它们在完成时都会导致不同的状态 public class BakerDeliverGrainState : BaseWorkerState, IState { public void Enter() { /
public class BakerDeliverGrainState : BaseWorkerState, IState
{
public void Enter()
{
//Go to storage
SetDestination(storage.position);
}
public void Execute()
{
if (unit.ReachedDestination())
{
//Reached destination, state completed
storage.Store(unit.TakeResource());
unit.stateMachine.ChangeState(new BakerWorkState(unit)); //This is the line that seperates the states. For example a blacksmith will go to "BlacksmithWorkState", and so on.
}
}
public void Exit()
{
}
}
是否有某种方法可以在构造函数中传递要更改的状态?或者,我可以通过其他方式调整我的设计,而不需要重新编写这么多代码。将匿名函数传递到构造函数中以创建新状态如何
public class BaseWorkerState
{
protected Func<Unit, IState> createCompletedState;
// Use this constructor for states where you don't need to customize the
// next state
public BaseWorkerState()
{
}
// Use this constructor for states where you do need to customize the
// next state
public BaseWorkerState(Func<Unit, IState> createCompletedState)
{
this.createCompletedState = createCompletedState;
}
}
public class BakerDeliverGrainState : BaseWorkerState, IState
{
public BakerDeliverGrainState(Func<Unit, IState> createCompletedState)
: base(createCompletedState)
{
}
public void Execute()
{
if (unit.ReachedDestination())
{
// Reached destination, state completed
storage.Store(unit.TakeResource());
unit.stateMachine.ChangeState(this.createCompletedState(unit));
}
}
}
当然,如果子状态(
BakerIdleState
)也需要自定义,那么您必须做同样的事情来设置该状态的下一个状态,这将变得更加复杂。真的很有趣,我明天将对此进行一点试验,可能会奏效!)
// When the baker is done delivering grain, he'll go into this state
public class BakerIdleState: IState
{
public BakerIdleState(Unit unit) : base(unit)
{
}
}
public class Baker : Unit
{
public void DeliverGrain()
{
var newState = new BakerDeliverGrainState(unit =>
{
return new BakerIdleState(unit);
});
this.stateMachine.ChangeState(newState);
}
}