今日の作業内容
・ボックスの当たり判定をまとめて処理
・Unityと似た当たり判定の実装
今日は上記の2点を完成させることが出来た。
ボックスしか出来なかったのはもともとボックスしかやっていなかったのでその延長線で改造を行ったため。
明日はすべてのColliderに対応できるようにする。
次にUnityと同じEnter、Stay、Exitでの当たり判定が出来るようになった。
これは映像だと分かりずらいので実際にコードを添付します。
〜
void PhysWorld::SweepAndPruneXYZ()
{
// まずX軸でソート
std::sort(mBoxesXAxis.begin(), mBoxesXAxis.end(),
[](BoxCollider* a, BoxCollider* b) {
return a->GetWorldBox().mMin.x < b->GetWorldBox().mMin.x;
});
// Y、Zも同じくソート
// 各軸の判定
mHitBoxesXAxis.clear();
mHitBoxesYAxis.clear();
mHitBoxesZAxis.clear();
SortColliderXAxis();
SortColliderYAxis();
SortColliderZAxis();
mCurrentHitPairs.clear();
// 共通ペアの検出
//X軸の配列
for (const auto& pair : mHitBoxesXAxis)
{
//Y、Z軸の配列からX軸の配列と同じペアがあるか調べる
if (mHitBoxesYAxis.count(pair) && mHitBoxesZAxis.count(pair))
{
//当たっている者同士の情報を取得
auto actorA = pair.first->GetOwner();
auto actorB = pair.second->GetOwner();
//ソートしたペアの情報を代入
std::pair<ActorObject*, ActorObject*> sortedPair = 〇〇〇
//現在のペア連想配列に追加
mCurrentHitPairs.emplace(sortedPair);
//当たり続けているか
if (mPrevHitPairs.count(sortedPair))
{
// Stay
actorA->OnCollisionStay(actorB);
actorB->OnCollisionStay(actorA);
}
//当たった瞬間なのか
else
{
// Enter
actorA->OnCollisionEnter(actorB);
actorB->OnCollisionEnter(actorA);
}
}
}
// Exitチェック
for (const auto& pair : mPrevHitPairs)
{
if (mCurrentHitPairs.count(pair) == 0)
{
auto actorA = pair.first;
auto actorB = pair.second;
actorA->OnCollisionExit(actorB);
actorB->OnCollisionExit(actorA);
}
}
// 状態更新
mPrevHitPairs = mCurrentHitPairs;
}
〜
上記は当たり判定をまとめて行って部分です。
簡単に解説するとスイープ&プレーンのアルゴリズムで行っており、XYZの3軸で別々に当たっている者同士を連想配列で取得し、3つの連想配列から比較して当たっているもの選び処理を行うようにしています。StayとExitはmCurrentHitPairsとmPrevHitPairs
の情報から判定を行うようにしています。
問題点
今回改めて当たり判定を行って出た問題がいくつかあります。
1:オブジェクトの回転した影響が当たり判定に反映されていない
2:プレーンの当たり判定がうまく出来ていない
ゲーム内にあるサイコロのオブジェクトをY軸に45度傾けて判定したところ当たってもいないのに当たった判定になった。その他壁や床のプレーンがプレイヤーに一部
当たっていないことも確認できた。
このことからまだまだやるべき要素は多いけどこれからもやっていく。
明日は残りの問題点の修正と整理をメインにやっていく
以上
今日の成果物
映像では表せないのでなし