図0025a
class ChildObject : public GameObject,public MatrixInterface { //中略 //親オブジェクト weak_ptr<GameObject> m_ParentPtr; //このオブジェクトのプレイヤーから見たローカル行列 Mat4x4 m_PlayerLocalMatrix; //プレイヤーの直後(先頭)の場合の補間係数 float m_LerpToParent; //このオブジェクトのチャイルドオブジェクトから見たローカル行列 Mat4x4 m_ChildLocalMatrix; //チャイルド後の場合の補間係数 float m_LerpToChild; //Attack1の場合の目標となる回転 float m_Attack1ToRot; //ステートマシーン unique_ptr<StateMachine<ChildObject>> m_StateMachine; public: //-------------------------------------------------------------------------------------- /*! @brief コンストラクタ @param[in] StagePtr ステージのポインタ @param[in] ParentPtr 親のポインタ @param[in] TextureResName テクスチャリソース名 @param[in] Scale スケーリング @param[in] Qt 初期回転 @param[in] Pos 位置 @param[in] OwnShadowActive 影描画するかどうか */ //-------------------------------------------------------------------------------------- ChildObject(const shared_ptr<Stage>& StagePtr, const shared_ptr<GameObject>& ParentPtr, const wstring& TextureResName, const Vec3& Scale, const Quat& Qt, const Vec3& Pos, bool OwnShadowActive); //中略 //-------------------------------------------------------------------------------------- /*! @brief ステートマシンを得る @return ステートマシン */ //-------------------------------------------------------------------------------------- unique_ptr< StateMachine<ChildObject> >& GetStateMachine() { return m_StateMachine; } //-------------------------------------------------------------------------------------- /*! @brief ワールド行列の取得 @return ワールド行列 */ //-------------------------------------------------------------------------------------- virtual void GetWorldMatrix(Mat4x4& m) const override; //-------------------------------------------------------------------------------------- /*! @brief 追従する行動の開始 @return なし */ //-------------------------------------------------------------------------------------- void ComplianceStartBehavior(); //-------------------------------------------------------------------------------------- /*! @brief 攻撃1行動の開始 @return なし */ //-------------------------------------------------------------------------------------- void Attack1StartBehavior(); //-------------------------------------------------------------------------------------- /*! @brief 攻撃1行動の継続 @return 行動が終了したらtrue */ //-------------------------------------------------------------------------------------- bool Attack1ExcuteBehavior(); //-------------------------------------------------------------------------------------- /*! @brief ステート共通処理 @return なし */ //-------------------------------------------------------------------------------------- void UpdateBehavior(); };
class MatrixInterface { protected: MatrixInterface() {} virtual ~MatrixInterface() {} public: //-------------------------------------------------------------------------------------- /*! @brief ワールド行列の取得(純粋仮想関数) @return ワールド行列 */ //-------------------------------------------------------------------------------------- virtual void GetWorldMatrix(Mat4x4& m) const = 0; };
virtual void GetWorldMatrix(Mat4x4& m) const = 0;
ChildObject(const shared_ptr<Stage>& StagePtr,
const shared_ptr<GameObject>& ParentPtr,
const wstring& TextureResName, const Vec3& Scale, const Quat& Qt, const Vec3& Pos,
bool OwnShadowActive);
//プレイヤーの作成 shared_ptr<GameObject> Par = AddGameObject<Player>( L"TRACE_TX", true, Vec3(0.0f, 0.125f, 0.0f) ); for (int i = 0; i < 10; i++) { float x = (float)(i + 1); Par = AddGameObject<ChildObject>( Par, L"SKY_TX", Vec3(0.25f, 0.25f, 0.25f), Quat(), Vec3(x, 0.125f, 0.0f), false); }
void ChildObject::UpdateBehavior(){
//前回のターンからの経過時間を求める
float ElapsedTime = App::GetApp()->GetElapsedTime();
auto shptr = m_ParentPtr.lock();
//親のワールド行列を取得する変数
Mat4x4 ParMat;
if (shptr) {
ParentFlg flg = ParentFlg::NoParent;
//行列取得用のインターフェイスを持ってるかどうか
auto matintptr = dynamic_pointer_cast<MatrixInterface>(shptr);
if (matintptr) {
matintptr->GetWorldMatrix(ParMat);
if (shptr->FindTag(L"Player")) {
flg = ParentFlg::Player;
}
else if (shptr->FindTag(L"ChildObject")) {
flg = ParentFlg::Child;
}
}
Mat4x4 World;
World.identity();
float LerpNum = 0.2f;
switch (flg) {
case ParentFlg::Player:
//行列の定義
World = m_PlayerLocalMatrix;
LerpNum = m_LerpToParent;
break;
case ParentFlg::Child:
//行列の定義
World = m_ChildLocalMatrix;
LerpNum = m_LerpToChild;
break;
default:
break;
}
if (flg != ParentFlg::NoParent) {
//スケーリングを1.0にした行列に変換
ParMat.scaleIdentity();
//行列の反映
World *= ParMat;
//この時点でWorldは目標となる位置
Vec3 toPos = World.transInMatrix();
//補間処理で移動位置を決定
auto CalcPos = Lerp::CalculateLerp(m_Rigidbody->m_BeforePos, toPos, 0, 1.0f, LerpNum, Lerp::rate::Linear);
Vec3 DammiPos;
World.decompose(m_Rigidbody->m_Scale, m_Rigidbody->m_Quat, DammiPos);
Vec3 Velo = CalcPos - m_Rigidbody->m_BeforePos;
Velo /= ElapsedTime;
m_Rigidbody->m_Velocity = Velo;
}
}
}
ParMat.scaleIdentity();
//行列の反映 World *= ParMat;
void ChildObject::ComplianceStartBehavior() { //ローカル行列の定義 m_PlayerLocalMatrix.affineTransformation( m_Rigidbody->m_Scale, Vec3(0, 0, 0), Quat(), Vec3(0, 0, -0.25f) ); //このステートではチャイルドの場合も同じ m_ChildLocalMatrix = m_PlayerLocalMatrix; m_LerpToParent = m_LerpToChild = 0.2f; }