ARTICLES
Altseed2で衝突判定を簡単に扱うパッケージの紹介
By wraikny
はじめに
Altseed2.TypeBasedCollision というAltseed2拡張パッケージを以前作成したので紹介します。
当たり判定色々と使いますよね。 Altseed2のチュートリアル第6章で教えてくれますが、正直このコードはあまり良くないです。 (2022/02/05現在。今後そっちも修正しようとは思います)
良くない点
- 継承ベースということ
- 本来なら
SpriteNode
でもRectangleNode
でも衝突判定したいよね?
- 本来なら
CollidableObject
全てに対して衝突チェックする。- 無駄が多い!!
PlayerBullet
とPlayer
の衝突をチェックする必要は無い!
ということで、この辺を解決するパッケージの紹介記事となります。
使い方
本パッケージでは、CollisionNode<T>
というクラスを提供しています。
Altseed2.Collider
を利用して当たり判定の処理を行うためのクラスです。
とりあえず例を見てみましょう。
シューティングゲームで、Player
がEnemyBullet
との衝突処理を行いたいとします。
まずはCollisionNode<T>
を作成しています。
// ゲームプレイヤーを表すノード
sealed class Player : Node, ICollisionMarker
{
private readonly CollisionNode<Player> collision;
public Player()
{
// 当たり判定の形状(Collider)を作成する。
var collider = new CircleCollider();
collider.Radius = 50f;
// 当たり判定を登録する。
collision = new CollisionNode<Player>(this, collider);
AddChildNode(collision);
}
protected override void OnUpdate()
{
/* 衝突判定処理 */
}
}
ポイント
Player
クラスを衝突判定で利用するために、ICollisionMarker
インターフェースを実装する。CollisionNode<T>
のコンストラクタでは、T
型のキーとなる値とAltseed2.Collider
のインスタンスを受け取る。CollisionNode<T>
は、当たり判定の機能を実装したいノードの子ノードとして追加する。
これはEnemyBullet
クラスでも同様の記述を行うものとします。
次に、衝突判定処理を記述します。 1,2,3はすべて同じ処理なので、好きなものを使ってください。
EnumerateCollisions<U>()
を利用する場合。
// 対象と衝突判定を列挙する。
var bullets = collision.EnumerateCollisions<EnemyBullet>();
// 処理を行う。
foreach (var (b, isCollided) in bullets)
{
// 衝突している場合
if (isCollided)
{
/* 衝突時の処理 */
}
}
CheckCollision(Action<U, bool>)
を利用する場合。
// 対象と衝突判定のコレクションに対して指定した処理を行う。
collision.CheckCollision<EnemyBullet>((b, isCollided) => {
if (isCollided)
{
/* 衝突時の処理 */
}
});
CheckCollision(Action<U>)
を利用する場合。
// 衝突している対象のコレクションに指定した処理を行う。
collision.CheckCollision<EnemyBullet>(b => {
/* 衝突時の処理 */
});
型をキーとして管理する
CollisionNode<T>
のT
のこと、気になりますね。
Altseed2.TypeBasedCollisionでは、衝突判定を型に紐づけて管理しています。 (辞書のようなものですね)
CollisionNode<T>.CheckCollision<U>
メソッドは、「T
型に紐付けられたCollisionNode<T>
」が、「U
型に紐付けられたCollisioNode<U>
のコレクション」に対して衝突判定処理を行います。
注意ですが、ここでキーとして指定する型は完全一致している必要があります。
Linq
のOfType<T>
とかと違って、継承しているクラスで指定はできません。
これは、型ごとに異なるコレクションで管理しているからです。
その分、余計なオブジェクトについて処理する必要がないのでパフォーマンス的に嬉しいです。
おわりに
質問あれば、Slackでも、Discordでも、Twitter @wraiknyでも、GitHubのIssueでも大丈夫なので気軽に聞いてください~。
SHARE THIS POST
Tweet