有限状态机[第3部分]

这是我们FSM的最终博客教程。我们将回顾第一部分讨论的内容,并实施我们之前所做的FSM系统。

只是回顾前面的部分:

sOSpPXe__WTretdttbvYesQ

这将是我们FSM的循环。首先,我们初始化FSM,创建状态,创建动作,并将它们全部映射在一起。在我们映射它们之后,我们现在将启动FSM并指示AI将开始的状态。现在,AI将更改为特定状态,FSM将初始化操作,更新它直到操作完成并发送指示操作已完成的事件。最后,FSM将返回并更改状态。

现在是时候实施它们了。

 

让我们创建一个TextAction,以便我们第一手看到FSM系统。

1FReRU4CWYFVPXTHKa65PQqfu7VQx6nJ3poP4_6A

让我们首先导入Common.FSM,以便我们可以使用我们的FSM系统,并让这个类继承FSMAction类。

现在让我们为这个特定的动作编写变量和构造函数。

textToShow是我们将在更新时在控制台中打印出来的字符串。持续时间是此操作的长度,而finishEvent是转换到另一个状态的调用。

让我们覆盖FSMAction的虚函数,以便FSM可以调用它们。

OnEnter将处理开始操作时我们想要做的所有事情。就像MonoBehaviour中的Start()一样,我们将在此阶段初始化我们的操作。更新将由FSM的动作处理器调用,该动作处理器由FSM的Update函数调用,并由我们的AI类调用。退出当然,将是我们完成一项行动后我们将要做的事情。就个人而言,我宁愿有一个完成功能,将发送事件。

 

现在我们已经采取了行动,让我们制作AI。

1vBWCxCqzAGoyCv4XThrLnrhqyVKfgTpDvPZN4Tk

让我们创建一个空的,它将保存我们的AI脚本。

1fHeGwtXW1jPMC7ezRqHJpHrrztNsHa7yKHwb3q4创建一个空的后,让我们创建一个脚本来实现我们的FSM系统和我们所做的动作。

让我们为AITest制作两个FSMStates和两个FSMAction。不要忘记导入Common.FSM,否则我们将无法使用我们制作的FSM系统。

同样,fsm将成为我们状态机的引擎,我们将有两种状态,PatrolState和IdleState。这取决于你如何命名它们。最后,我们将有两个文本操作,每个状态一个,PatrolAction和IdleAction。

现在让我们在Start()函数中创建FSM,States和Actions。

首先,我们将初始化FSM,然后添加新状态。请记住,FSM.AddState()返回FSMStates,以便我们不必声明新的FSMState,并将它们添加到FSM。

现在我们有状态和动作,现在让我们映射一切,并为每个转换添加事件ID。

当事件发送到状态时,我们将PatrolState映射到IdleState,反之亦然。我们现在初始化我们的行动。

第一个属性是字符串,将是我们操作的输出,第二个属性将确定操作的持续时间,最后一个属性将是操作完成后将发送的事件。

请记住,这里的所有内容都在启动功能中。现在让我们尝试通过调用FSM.Start()和FSM.Update()来使FSM工作;

同样,在Start()下的所有初始化之后调用fsm.Start()。现在让我们将AITest附加到我们之前创建的空游戏对象,然后在编辑器中按“播放”。

最后,看看自动化发生了!

1S-7f6nFEDuhmfFSXjaXAk0_Fh0Jyhs1P_N6EKsQAI将每2秒打印一次空闲,并且每3秒巡逻一次。

 

1VwqSEDvSaDRP50DJsCX2w-dso9Bch-lcqp0D9y8现在让我们把它带到另一个层面。让我们制作一个移动的对象,同时在控制台中打印出字符串。但是我们不会在一个行动中做到这一点。我们将创建另一个将添加到同一状态的操作。

让我们创建一个名为AITestTwo的脚本。

1 IU-GFRQu-tgoJLrMoM_GZ2SxE0rq6sMd5cfswRA让我们创建另一个名为MoveAction的动作。这将是移动物体的通用动作。

打开MoveAction.cs,让我们编写动作。

 

MoveAction.cs不同,我们必须引用对象的变换,以便动作可以移动它。

 

我们来讨论这些属性。如上所述,我们需要在此操作中引用对象的变换,因为我们希望此操作移动对象,而不是AI类。非常自我解释,Vector3来自和。同样,动作的持续时间和结束事件。

正如您所看到的,我们有两个未包含在Init()属性中的变量,即journeyLength和polledTime。稍后我们将它们用于Vector3.Lerp函数。轮询时间将包含在我们稍后的计算中。

现在我们为位置添加了一个辅助函数,它是SetPosition(),使我们更容易。同样,OnEnter()初始化动作,OnUpdate()将执行Lerp函数。这也是我们计算Lerp函数所需比率的地方。当操作完成时,我们将对象设置为所需的最终位置,并重置我们的变量。

 

现在,我们来设置第二个AI。

我们现在每个州都有两个行动。FSM现在将在一个状态下更新两个操作。我们在这里所做的与我们在TextAction.cs上所做的完全相同。我们创建了类的实例,将操作添加到状态,并添加了对这些状态的转换和调用,并初始化了操作。

现在让我们来玩,希望它能正常运行。

1KDFzVJldz17rgpUe8XPO884SAYqx5JYzd5D8jaA

1RmIMDg8oKBNpn_2JPWFTLf1FNPbdbYj0YmMe4Ic

如您所见,AI现在正在同时执行操作。您可以混合不同的操作并将其动态添加到所需的状态。

这有什么好处,你可以添加很多动作并将它们包含在一个状态中并同时执行它们。虽然如果你在移动设备上会导致一些性能问题。我建议的是,当你将它用于移动时,为了安全起见,只需同时做至少1或2个动作。我没有对移动设备进行过真正的测试。

就这样,我们已经完成了动态FSM教程。我希望这对你的游戏有所帮助。你可以在任何游戏中以任何方式使用它。无论您是在UI,GameObjects还是其他任何需要的地方使用它。如果您有任何疑问,请记得发表评论,我很乐意尽快回复!

FSM是一个非常重要的主题,分为三个部分,所以如果你想要更好地理解它,这里有一些与FSM相关的文章和实现。我相信这些将进一步解释FSM:

如果您想查看整个项目,是Unity包的链接。

是我们在整个过程中创建的脚本的链接。

猜你喜欢

转载自blog.csdn.net/qq_31967569/article/details/81063537