図1204a
F = M × A
//-------------------------------------------------------------------------------------- // 配置されるオブジェクトの親 //-------------------------------------------------------------------------------------- class BaseChara : public GameObject { //ステートマシーン unique_ptr< StateMachine<BaseChara> > m_StateMachine; Vec3 m_StartPos; float m_StateChangeSize; //フォース Vec3 m_Force; //速度 Vec3 m_Velocity; void ApplyForce(); protected: //構築と破棄 BaseChara(const shared_ptr<Stage>& StagePtr, const Vec3& StartPos); virtual ~BaseChara(); public: //アクセサ const unique_ptr<StateMachine<BaseChara>>& GetStateMachine() { return m_StateMachine; } Vec3 GetStartPos() const { return m_StartPos; } float GetStateChangeSize() const { return m_StateChangeSize; } const Vec3& GetForce()const { return m_Force; } void SetForce(const Vec3& f) { m_Force = f; } void AddForce(const Vec3& f) { m_Force += f; } const Vec3& GetVelocity()const { return m_Velocity; } void SetVelocity(const Vec3& v) { m_Velocity = v; } shared_ptr<GameObject> GetTarget()const; virtual void NearBehavior() = 0; virtual void FarBehavior() = 0; virtual void OnCreate() override; virtual void OnUpdate() override; };
void BaseChara::OnCreate() { //オブジェクトのグループを得る auto Group = GetStage()->GetSharedObjectGroup(L"ObjGroup"); //グループに自分自身を追加 Group->IntoGroup(GetThis<BaseChara>()); //分離行動をつける auto PtrSep = GetBehavior<SeparationSteering>(); PtrSep->SetGameObjectGroup(Group); //壁回避行動を付ける auto PtrWall = GetBehavior<WallAvoidanceSteering>(); vector<PLANE> PlaneVec = { { Vec3(20,0,0), Vec3(20,1.0,0), Vec3(20,0,-1.0), }, { Vec3(0,0,-20), Vec3(0,1.0,-20), Vec3(-1.0,0,-20), }, { Vec3(-20,0,0), Vec3(-20,1.0,0), Vec3(-20,0,1.0), }, { Vec3(0,0,20), Vec3(0,1.0,20), Vec3(1.0,0,20), }, }; PtrWall->SetPlaneVec(PlaneVec); //障害物回避行動を付ける vector<shared_ptr<GameObject>> SpObjVec; GetStage()->GetUsedTagObjectVec(L"FixedSphere", SpObjVec); vector<SPHERE> SpVec; for (auto& v : SpObjVec) { auto TransPtr = v->GetComponent<Transform>(); SPHERE sp; sp.m_Center = TransPtr->GetPosition(); sp.m_Radius = TransPtr->GetScale().x * 0.5f; SpVec.push_back(sp); } auto PtrAvoidance = GetBehavior<ObstacleAvoidanceSteering>(); PtrAvoidance->SetObstacleSphereVec(SpVec); //ステートマシンの構築 m_StateMachine.reset(new StateMachine<BaseChara>(GetThis<BaseChara>())); //最初のステートをSeekFarStateに設定 m_StateMachine->ChangeState(FarState::Instance()); }
1、SeparationSteering(分離行動) 2、WallAvoidanceSteering(壁回避行動) 3、ObstacleAvoidanceSteering(障害物回避行動)
void BaseChara::OnUpdate() {
m_Force = Vec3(0);
//共通のステアリング1
auto PtrWall = GetBehavior<WallAvoidanceSteering>();
m_Force += PtrWall->Execute(m_Force, GetVelocity());
//ステートマシンのUpdateを行う
//この中でステートの切り替えが行われる
m_StateMachine->Update();
//共通のステアリング2
auto PtrSep = GetBehavior<SeparationSteering>();
m_Force += PtrSep->Execute(m_Force);
auto PtrAvoidance = GetBehavior<ObstacleAvoidanceSteering>();
m_Force += PtrAvoidance->Execute(m_Force, GetVelocity());
ApplyForce();
auto PtrUtil = GetBehavior<UtilBehavior>();
PtrUtil->RotToHead(1.0f);
}
shared_ptr<FarState> FarState::Instance() { static shared_ptr<FarState> instance(new FarState); return instance; } void FarState::Enter(const shared_ptr<BaseChara>& Obj) { } void FarState::Execute(const shared_ptr<BaseChara>& Obj) { Obj->FarBehavior(); } void FarState::Exit(const shared_ptr<BaseChara>& Obj) { } //-------------------------------------------------------------------------------------- // プレイヤーから近いときの移動 //-------------------------------------------------------------------------------------- shared_ptr<NearState> NearState::Instance() { static shared_ptr<NearState> instance(new NearState); return instance; } void NearState::Enter(const shared_ptr<BaseChara>& Obj) { } void NearState::Execute(const shared_ptr<BaseChara>& Obj) { Obj->NearBehavior(); } void NearState::Exit(const shared_ptr<BaseChara>& Obj) { }