命令模式+NodeCanvas行为树实现Ai

个人以最粗浅的角度理解A i就是 AI自以为在第三层,我只在第一层,但其实我在第五层;

呵呵呵,就是他自以为知道在什么情况怎么做,只不过还是被我操控着;

什么情况“:用NodeCanvas行为树来区分。

怎么做”: 采取命令模式来告诉他怎么做。

命令模式实现

首先实现一个命令接口ICommand,不同的Ai命令类继承该接口

1
2
3
4
5
6
7
public interface ICommand

{

public void onExcute(IAiAction Ai);

}``

如后退命令类:

1
2
3
4
5
6
7
8
1.   public class MoveBackCmd : ICommand
2. {
3. public void onExcute(GameObject Ai)
4. {
5. Ai.transform.position...;
6. }
7. }
8.

但其实命令下达者只需要知道命令实施者的行为,而不需要知道实施者的属性等其他信息,并且行为是允许其多态实现的,行为不由命令来决定,而是由命令执行者来决定,我只是抽象的告诉你做什么,但到底怎么做还得是靠你自己。就好比大司马说过的一句话:

“如果我什么都告诉你的话,你就很难成长”;

1
2
3
4
5
6
7
1.   public class MoveBackCmd : ICommand
2. {
3. public void onExcute(IAiAction Ai)
4. {
5. Ai.MoveBack();
6. }
7. }

所以可以实现一个实施者的行为接口,如果某物需要被Ai控制,则需要其脚本继承实现该接口

1
2
3
4
5
6
7
8
9
10
11
12
13
1.   public interface IAiAction
2. {
3. public void RunForward();
4. public void RunBackward();
5. public void MoveForward();
6. public void MoveBack();
7. public void StopMove();
8. public void GuardUp();
9. public void GuardBottom();
10. public void StopGuard();
11. public void Dodge();
12. }
13.

Ai脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
1.   public class Ai :MonoBehaviour
2. {
3
4. public ICommand command;
5. public ICommand MoveForwardCmd;
6. public ICommand MoveBackCmd;
7. public ICommand StopMoveCmd;
8. public ICommand UpGuardCmd;
9. public ICommand DownGuardCmd;
10. public ICommand StopGuardCmd;
11. public ICommand DodgeCmd;
12. public ICommand RunFwdCmd;
13. public ICommand RunBwdCmd;
14. public ICommand[] AiCommands;
15. private void Start()
16. {
17.
18. MoveForwardCmd = new MoveForwardCmd();
19. MoveBackCmd = new MoveBackCmd();
20. StopMoveCmd=new StopMoveCmd();
21. UpGuardCmd=new UpGuardCmd();
22. DownGuardCmd = new GuardBottomCmd();
23. StopGuardCmd = new StopGuardCmd();
24. DodgeCmd=new DodgeCmd();
25. RunFwdCmd=new RunFwdCmd();
26. RunBwdCmd=new RunBwdCmd();
27. AiCommands = new ICommand[]{MoveForwardCmd,MoveBackCmd,StopGuardCmd,StopMoveCmd,UpGuardCmd,DownGuardCmd,DodgeCmd ,RunFwdCmd,RunBwdCmd};
28. }
29. public void RunForWard(IAiAction Puppet) => RunFwdCmd.onExcute(Puppet);
30. public void RunBackWard(IAiAction Puppet)=> RunBwdCmd.onExcute(Puppet);
31. public void MoveForward(IAiAction Puppet)=> MoveForwardCmd.onExcute(Puppet);
32. public void MoveBack(IAiAction Puppet) => MoveBackCmd.onExcute(Puppet);
33. public void StopMove(IAiAction Puppet)=>StopMoveCmd.onExcute(Puppet);
34. public void GuardUp(IAiAction Puppet)=> UpGuardCmd.onExcute(Puppet);
35. public void GuardDown(IAiAction Puppet) => DownGuardCmd.onExcute(Puppet);
36. public void StopGuard(IAiAction Puppet) => StopGuardCmd.onExcute(Puppet);
37. public void Dodge(IAiAction Puppet) => DodgeCmd.onExcute(Puppet);
38. }
39.

就可以通过行为树调用Ai脚本函数传入想控制的参数就行了;

img