Skip to content

Collision ​

名前空間はcol2dです。単に重なりを調べる処理、押し戻す処理、接触イベントを区別します。

ColliderManager ​

モジュール:Collider.ColliderManager。

公開関数引数・戻り値
CreateCollider<T>(ColliderDef* def, const uint32_t& ownerID, Args&&... args)定義・所有者カテゴリ・形状固有引数から生成。ColliderIDを返す
CreateRectCollider(def, const Vector2f& size, ownerID = 0)矩形のサイズ。ColliderIDを返す
CreateCircleCollider(def, float radius, ownerID = 0)円の半径。ColliderIDを返す
CreateTileCollider(def, const MapInfo& info, std::string fileName, ownerID = 0)マップ定義とCSV名。ColliderIDを返す
CreateTileCollider(def, std::shared_future<MapInfo> info, std::string fileName, ownerID = 0)マップ構築結果を待つ版。ColliderIDを返す
Collider* GetCollider(const ColliderID& id) const借用ポインタ。無効・旧世代IDはnullptr
void Destroy(const ColliderID& id)コライダー破棄。無効・旧世代IDは無視
void AddMask(id, const uint32_t& shape, const uint32_t& ownerID)判定対象カテゴリを追加
void AddEvent(id, const uint64_t& key, ContactListener event)カテゴリのイベントを追加
void Step()マスクで対象を選び、衝突と移動を実行

defは非nullで渡し、ColliderDef def{};のように値初期化します。Collider内部で定義をコピーします。IDはindexとgenerationを持ち、生成元の管理インスタンスでのみ使います。異なるシーンのIDを混ぜないでください。

Colliderと定義 ​

ColliderはGetColliderDef()、GetFilter()、SetVelocity(const Vector2f&)、GetVelocity()、AddVelocity()、Accept(ColliderVisitor&)、CollideWith(Collider&)、GenerateCategory(uint32_t)、AddEvent(key, event)、TriggerEvent(key, info)、DeleteEvent(key)を公開します。

取得関数は内部の定義ポインタ/Filter参照/移動量の値を返し、操作関数はvoidです。GetColliderDef()は可変ポインタですが、形状側の内部情報もあるため、定義の書換えだけで全形状状態が追従するとは限りません。

ColliderDefにはtype、worldPos、localPos、shouldCCD、isTrigger、isActiveがあります。ContactInfoには法線normalと接触点pointがあります。ContactListenerはbool(const ContactInfo&)のwhenと、void()のeventです。

形状と解決 ​

RectCollider・CircleColliderは相手形状や点とのIsColliding、形状取得、移動を実装します。Rectにはswept矩形の計算があり、Visitorはサブステップも使います。これは全速度に対するすり抜け防止保証ではありません。

TileColliderはチャンク化したタイルを持ち、IsColliding(const shape::Rect&)がboolを返します。TakeHitTileKeys()は検出キーのqueueを取り出して内部queueを空にします。GetTileInfo(key, index)は借用constポインタで、範囲外ならnullptr。GetTileSize()はconst参照です。

TileColliderVisitorは矩形に対応し、円へのVisitは空です。TileCollider自身のAcceptも空なので、地形側から矩形へ訪問する方向を使います。TileTypeはSOLIDとONE_WAY_TOP。Resolverが押し戻しと接触情報を扱います。

Rect/Circle/Tileの各Resolverは形状ごとのResolveを持ちます。返り値がoptional<ContactInfo>の版は接触情報なしをnulloptで表します。正確な各オーバーロードは宣言一覧で確認してください。

フィルタ・イベント例 ​

MakeKey(shape, ownerID)でカテゴリを作ります。Filterのマスクはカテゴリ単位です。オブジェクト個体の識別子ではないので、同じタグの複数個体を別々に指定する仕組みではありません。

cpp
// GameObject派生のInit内
col2d::ColliderDef def{};
def.isActive = true;
def.localPos = m_pos;
auto id = ColMgr().CreateRectCollider(&def, {32.0f, 32.0f}, MyObjectTag());
ColMgr().AddMask(id, col2d::CIRCLE, object::ObjectTag::ENEMY);

実際にはidをメンバーへ保存し、破棄時にDestroyします。衝突実習を参照してください。トリガーの条件式とコメントの不一致、カテゴリ単位の削除副作用などは制約にまとめています。

コード確認基準:08f9fa53 · C++実機検証は別途実施