第四周
解决Boss的问题
首先是理了一下Boss的逻辑,以动画状态机的形式呈现。
由于部分Any State 出去的子节点还需要完善和依照模型商榷,因此这个还是不完整版的动画状态机。
需要注意的是Walk&Relax节点是一个混合树,因此还写了一个RelaxRate接收随机数来控制休息的速率。
发现了自己对于多维混合树还是不太熟悉,还需要多看教程学习。
另外,由于没有找到特别好的带动画的模型资源,现在还是依照Unity 原有的模型资源来制作游戏,如图:
人物是敌人,攻击动画是滑动的动画。胶囊体是我们可操纵的主角。另外系统编写人员说壁障也将成为系统的一部分,因此在未了解大概是如何实现之前先没有写障碍的处理。
了解了一下FSM机制,以及我们的AI系统的FSM机制与传统的不同,首先现在主要了解的是它的概率机制和反馈机制。
以下是通过了解FSM机制后编写的一些简单的实现AnyState之后子节点的部分。
首先是注册该类敌人所拥有的函数:
此处需要注意的是,DemoWorld 类的实例只需要注册
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using FreedomAI;
using UnityECS;
public class BossRegist : MonoBehaviour
{
public GameObject AI;
public GameObject player;
public GameObject BossObject;
//public GameObject forward_Object;
Animator animator;//动画机
AnimationPlay walkAnim;
AnimationPlay idleAnim;
AnimationPlay AttackAnim;
StateRecorder mRecorder;
StateExecuter roundstate;
StateExecuter attackstate;
StateExit attackExit;
StateExecuter runawaystate;
//转化函数的注册
StateTranfer anytorunaway;
StateTranfer firetorun;
StateTranfer runtofire;
StateTranfer runtoround;
StateFeedbacker runIN;
StateFeedbacker runOUT;
StateFeedbacker hurtup;
HPComponent player_hp = new HPComponent();
AIEntity mAIEntity = new AIEntity();
UEntity mPlayer = new UEntity();
UEntity mPlayerLast = new UEntity ();
HPComponent playerLast_hp = new HPComponent ();
DemoWorld mWorld = new DemoWorld();
// Use this for initialization
void Start ()
{
mWorld.Init ();
mWorld.registerEntityAfterInit (mAIEntity);
// mAIEntity.mAllBitBunch.SetCount ((int)mWorld.mComponentCount);
mWorld.registerEntityAfterInit (mPlayer);
// mPlayer.mAllBitBunch.SetCount ((int)mWorld.mComponentCount);
runAnim = TestFSM.FSM_Run_Anim;
walkAnim = TestFSM.FSM_Walk_Anim;
idleAnim = TestFSM.FSM_Idle_Anim;
shootAnim = TestFSM.FSM_Shoot_Anim;
mRecorder = TestFSM.FSM_Test_Recorder;
runstate = TestFSM.FSM_Run;
roundstate = TestFSM.FSM_Round;
runExit = TestFSM.FSM_Run_Exit;
firestate = TestFSM.FSM_Fire;
fireExit = TestFSM.FSM_Fire_Exit;
runawaystate = TestFSM.FSM_Runaway;
anytorunaway = TestFSM.FSM_Any_TransferRunAway;
firetorun = TestFSM.FSM_Fire_Run;
runtofire = TestFSM.FSM_Run_Fire;
runtoround = TestFSM.FSM_Run_Round;
roundtorun = TestFSM.FSM_Round_Run;
runtogre = TestFSM.FSM_Run_Gre;
gretorun = TestFSM.FSM_Gre_Run;
runIN = TestFSM.FSM_RunIN;
runOUT = TestFSM.FSM_RunOUT;
hurtup = TestFSM.FSM_HurtUp;
// mAIEntity.forward_Object = forward_Object;
mAIEntity.mAI = AI;
mAIEntity.mPlayer = player;
mAIEntity.Init ();
mAIEntity.AddComponent<myAI> (new myAI());
mAIEntity.GetComponent<BaseAIComponent> ().mAIRT.SetActive (true);
mAIEntity.PlayerEntity = mPlayer;
mAIEntity.GetComponent<HPComponent> ().allHP = 500;
mAIEntity.GetComponent<HPComponent> ().tempHP = 500;
animator = mAIEntity.GetComponent<BaseAIComponent> ().mAIRT.GetComponent<Animator> ();
mAIEntity.GetComponent<AIAnimation> ().mAnimator = animator;
mAIEntity.GetComponent<AIAnimation> ().Add ("Run",runAnim);
mAIEntity.GetComponent<AIAnimation> ().Add ("Walk",walkAnim);
mAIEntity.GetComponent<AIAnimation> ().Add ("Idle",idleAnim);
mAIEntity.GetComponent<AIAnimation> ().Add ("Shoot",shootAnim);
mAIEntity.GetComponent<AIAnimation>().tempAnim = "Run";
mAIEntity.GetComponent<AIEmotion> ().InsertEmotion ("Happy");
mAIEntity.GetComponent<AIEmotion> ().InsertEmotion ("Fear");
mAIEntity.GetComponent<AIEmotion> ().InsertEmotion ("Tired");
mAIEntity.GetComponent<AIEmotion> ().InsertEdge ("Happy",happy);
mAIEntity.GetComponent<AIEmotion> ().InsertEdge ("Fear",fear);
mAIEntity.GetComponent<AIEmotion> ().InsertEdge ("Tired",tired);
int id_run=mAIEntity.GetComponent<AIState> ().AddExecuter (runstate,runExit,EmptyExitAndEnter.EmptyEnter);
int id_round=mAIEntity.GetComponent<AIState> ().AddExecuter (roundstate,EmptyExitAndEnter.EmptyExit,EmptyExitAndEnter.EmptyEnter);
int id_runaway=mAIEntity.GetComponent<AIState> ().AddExecuter (runawaystate,EmptyExitAndEnter.EmptyExit,EmptyExitAndEnter.EmptyEnter);
int id_fire=mAIEntity.GetComponent<AIState> ().AddExecuter (firestate,fireExit,EmptyExitAndEnter.EmptyEnter);
int id_gre= mAIEntity.GetComponent<AIState> ().AddExecuter (Grenatestate,GreExit,EmptyExitAndEnter.EmptyEnter);
mAIEntity.GetComponent<AIState> ().AddAnywayTranfer (anytorunaway,runOUT,id_runaway);
mAIEntity.GetComponent<AIState> ().AddEdge (firetoGre,hurtup,id_fire,id_gre);mAIEntity.GetComponent<AIState> ().AddEdge (Gretofire,hurtup,id_gre,id_fire);
mAIEntity.GetComponent<AIState> ().AddEdge (firetorun,runIN,id_fire,id_run);mAIEntity.GetComponent<AIState> ().AddEdge (runtofire,runIN,id_run,id_fire);
mAIEntity.GetComponent<AIState> ().AddEdge (runtoround,EmptyTranfer.Run,id_run,id_round);mAIEntity.GetComponent<AIState> ().AddEdge (roundtorun,runIN,id_round,id_run);
mAIEntity.GetComponent<AIState> ().AddEdge (gretorun,runIN,id_gre,id_run);mAIEntity.GetComponent<AIState> ().AddEdge (runtogre,hurtup,id_run,id_gre);
mAIEntity.GetComponent<AIState> ().AddAnimation (runstate,"Run");
mAIEntity.GetComponent<AIState> ().AddAnimation (roundstate,"Walk");
mAIEntity.GetComponent<AIState> ().AddAnimation (runawaystate,"Run");
mAIEntity.GetComponent<AIState> ().AddAnimation (firestate,"Shoot");
mAIEntity.GetComponent<AIState> ().AddAnimation (Grenatestate,"Idle");
mAIEntity.GetComponent<AIState> ().tempID = id_round;
mAIEntity.GetComponent<AIState> ().mStateRecorder = mRecorder;
mAIEntity.GetComponent<AIState> ().LastEntityData.AddComponent<HPComponent> (new HPComponent());
mAIEntity.GetComponent<AIState> ().LastEntityData.PlayerEntity = mPlayerLast;
mPlayerLast.AddComponent<HPComponent> (playerLast_hp);
mAIEntity.GetComponent<myAI> ().fireObject = shootObject;
mAIEntity.GetComponent<myAI> ().GrenateObject = GrenateObject;
}
// Update is called once per frame
void Update ()
{
mWorld.Update ();
}
}