2

我正在使用 C# 的无状态状态机,但我过去在使用其他状态机实现时遇到过这个问题。这个问题主要是理论上的,但如果需要,我可以添加一些虚拟代码。

我有一种情况,我很不确定如何解决。假设您有 2 种状态(步行和奔跑),它们都可以转换到第三种状态(跳跃)。一旦第三个状态完成,我希望回到调用者状态。在某种程度上,我必须能够影响被调用者触发器,但这只会传递给OnEntry诸如此类,而不是状态本身。

usingEntryFrom似乎不起作用,因为没有办法影响“跳转”状态本身,只有OnEntry功能。使用PermitDynamic似乎也不起作用,因为一旦处于“跳跃”状态,我不知道我来自哪里。

我可以使用一个OnEntry函数有 2 个跳转状态(jumpfromrun、jumpfromwalk),以尽量减少一些重复代码。这是我目前使用的。

我可以将先前的状态保存在一个外部变量中,并将其传递给我的状态更新。我不想这样做(根本)。

是否有已知的技术或方法来处理此类问题?有一个共享状态,应该转换回调用者?谢谢!

4

1 回答 1

2

从阅读文档来看,这似乎是子状态的一个很好的用例。

你可以有一个跳转状态:

stateMachine.Configure(State.Jumping)
    .OnEntry(() => StartJump())
    .OnExit(() => EndJump());

和两个跳跃子状态。一种用于步行,一种用于跑步:

stateMachine.Configure(State.WalkJumping)
    .SubstateOf(State.Jumping)
    .Permit(Trigger.DoneJumping, State.Walking);

stateMachine.Configure(State.RunJumping)
    .SubstateOf(State.Jumping)
    .Permit(Trigger.DoneJumping, State.Running);

然后,您分别制作到 WalkJumping 和 RunJumping 的步行和跑步路线。

stateMachine.Configure(State.Walking)
    .OnEntry(() => StartWalking())
    .OnExit(() => EndWalking());
    .Permit(Trigger.Jump, State.WalkJumping);


stateMachine.Configure(State.Running)
    .OnEntry(() => StartRunning())
    .OnExit(() => EndRunning());
    .Permit(Trigger.Jump, State.RunJumping);

使用像这样的底物,而不是仅仅使用常规状态,还有一个额外的好处,即State.Jumping可以定义相同的OnEntry并且OnExit将被WalkJumping和继承EndJumping

此外,它还为您提供了一种更简单的方法来检查您是否在跳跃中。代替:

var state = stateMachine.state;
var isJumping = state == State.WalkJumping || state == RunJumping;

你可以简单地做:

var isJumping = stateMachine.IsInState(State.Jumping);

这将正确考虑当前WalkJumping和的所有子状态RunJumping。但是如果你以后添加一个新的跳转子状态,例如DoubleJumping,那么isJumping谓词也会自动覆盖这种情况,而无需记住修复它。

于 2017-12-07T16:09:05.543 回答