2Dプラットフォーマーに接地されている:キャラクターがそれだけの価値があるかどうかをどのように知るのですか?

簡単に説明します。 彼はこのタスクに長い間苦労していたため、ソリューションを共有することにしました。 エンジンはUnity3Dです。

問題の声明


キャラクターがあり、プラットフォームがあります。 もちろん、コライダーと剛体のキャラクターでは、すべてがドウェードです。 コライダーもプラットフォーム上にあります。 プラットフォーム上-エフェクター、プラットフォーム上では上部のみがしっかりしている必要があります。 つまり、キャラクターがプラットフォームに落ちた場合、彼はその上に立ちます。 しかし、キャラクターがプラットフォームを通過したり、その下にジャンプした場合、キャラクターは自由に通過します。

キャラクターは、プラットフォーム上に立っている場合にのみジャンプできます。 価値があるかどうかを知る必要があります。

条件:

1)プラットフォームの形状は任意です。
2)キャラクターはプラットフォームの端に立つことができます。
3)プラットフォームを傾けることができます。
4)プラットフォームは移動できます。

一般的なソリューションと適合しない理由


アセットストアの標準的な例では、キャラクターの下に追加のゲームプロジェクトを使用し、キャラクターからレイキャストをゲームプロジェクトに投げ込み、地面との交差があるかどうかを監視することが提案されています。

1)キャラクターが立っていない場合でも、「通り過ぎ」または「ジャンプオン」すると、熊手は「地面」を完全にキャッチします。
2)Reykastは、エリアではなく特定のポイントで機能します。 したがって、プラットフォームがレイクキャストポイントの下に正確に配置されていない場合-たとえば、プラットフォームの端や小さな小石の上にいる場合-チェックはそれに気付きません。

解決策


解決策は論理的には得られず、経験的にのみ得られます。 なぜなら、それは物理エンジンの機能に由来するからです。 必要なもの:
System.Linqを使用することは一般に便利なことです。まだ慣れていない場合は、慣れることをお勧めします。 コレクションを検索するために使用し、ネストされたifesを持つforsychesの90%を破壊します。
GetComponent()。Bounds.min.y-コライダーの下部、つまり最小縦座標
OnCollisionStay2D docs.unity3d.com/ScriptReference/Collider2D.OnCollisionStay2D.html
OnCollisionExit2D
CollisionContacts docs.unity3d.com/ScriptReference/Collision-contacts.html docs.unity3d.com/ScriptReference/ContactPoint-point.html

OnCollisionStay2Dは、キャラクターとプラットフォームが相対的に移動するとトリガーされます。 キャラクターがプラットフォームにヒットしたとき、つまり OnCollisionEnter2Dでは、上記のイベントも機能します。

したがって、キャラクターがプラットフォーム上に立っている場合、幾何学的に彼のコライダーとプラットフォームコライダーは交差しません。 そのため、「キャラクターの底」は接触点のすぐ上になければなりません。 すべて!

1)リストを作成します。

List<Collider2D> GroundColliders = new List<Collider2D>(); 

2)OnCollisionStay2Dイベントで、確認し、必要に応じてコライダーを追加します。

 void OnCollisionStay2D(Collision2D coll) { if (!GroundColliders.Contains(coll.collider)) foreach (var p in coll.contacts) if (p.point.y < myCollider.bounds.min.y) { GroundColliders.Add(coll.collider); break; } } 

3)プラットフォームと交差しなくなった場合は、リストから削除します:

 void OnCollisionExit2D(Collision2D coll) { if (GroundColliders.Contains(coll.collider)) GroundColliders.Remove(coll.collider); } 

4)チェック対象を推測します。

 bool IsGrounded { get { return GroundColliders.Count > 0; } } 

タグ、raykast、追加のゲームオブジェクトなしで、シンプルでわかりやすく、非常に普遍的です。 健康に使用してください。

Source: https://habr.com/ru/post/J279407/


All Articles