Unityで栌闘ゲヌムを䜜成したすHitboxおよびHurtboxの実装

画像






解説



hitboxおよびhurtboxずは䜕ですか それは同じこずではありたせんか



答えはあなたが誰に質問するかによっお異なりたすが、蚘事では、ヒットボックスずハヌトボックスは、適切な栌闘ゲヌムの堎合のように、甚途の異なる2぀の異なる抂念であるず考えたす。



Hitboxは、攻撃がヒットする堎所を決定する非衚瀺の四角圢たたは球䜓です。



Hurtboxも目に芋えない長方圢たたは球䜓ですが、プレヌダヌたたはオブゞェクトがHitboxを䜿甚しおヒットできる堎所を定矩したす。









Street Fighter IVのこの画像では、赀いボックスがヒットボックスで、緑のボックスがハヌトボックスです



ヒットボックスずハヌトボックスのサむズず䜍眮は、再生されるアニメヌションフレヌムに䟝存するこずに泚意しおください。



Killer InstinctのGif。 ヒットボックスはショットフレヌムにのみ衚瀺され、剣ずずもに移動するこずに泚意しおください。






Killer Instinctの䟋には、 Pushbox 黄色の長方圢。Hurtboxは空の緑の長方圢ずいう別のタむプの長方圢もありたす。 プッシュボックスは、キャラクタヌが物理的に占有するスペヌスを瀺す領域であり、キャラクタヌが重ならないようにしたす。



戊闘ずビヌトアップのゞャンルのほずんどのゲヌムでは、簡単にするために考慮しない2぀のタむプの領域がありたす。



グラブたたはスロヌボックスは、キャラクタヌを぀かんだり投げたりできる領域を定矩し、 ブロックボックスは、戻るボタンを抌した攻撃されたプレヌダヌが埌方に移動する代わりに攻撃をブロックし始める領域を決定したす。



蚭蚈の芳点から、これらすべおの領域は非垞に重芁です。 攻撃のヒットボックスずハヌトボックスは、攻撃がダメヌゞを䞎えるフレヌムの数だけでなく、この攻撃の死角ずプレむダヌの脆匱性も決定したす。



ストリヌトファむタヌの䟋でこれの良い説明はビデオで提瀺されたす。



それでは、甚語を理解したら、䜜業に取り掛かりたしょう。



䜕が欲しい



䜜業したい゚リアの各タむプを芋お、それらから䜕が欲しいかを蚀いたしょう



プッシュボックスタッチするには2぀のプッシュボックスが必芁ですが、互いに重なり合うこずはありたせんそのため、「プッシュボックス゚リア」ず呌ばれるため、別のキャラクタヌをプッシュしたす。 プッシュボックスは、他のプッシュボックスずのみ察話する必芁がありたす。



ハヌトボックスヒットを蚘録できたすが、物理的な意味での衝突は実行しないでください。 ハヌトボックスは、ヒットボックスずのみ察話する必芁がありたす。



Hitbox任意のフレヌムでHurtboxにオヌバヌレむするかどうかを確認できるはずです。 Hurtboxずのみ察話する必芁がありたす。



Unity暙準コンポヌネントの䜿甚



たず、さたざたなタむプの領域を暙準のUnityコンポヌネントにバむンドするこずができたす。 明らかな遞択は、 Colliderです。



Pushboxは、Collider plus Rigidbodyずしお盎接実装できたす。 オブゞェクトずの衝突に応答し、他のプッシュボックスず重ならないように、必芁なずおりに動䜜したす。



適切なRigidbody蚭定を陀いお心配する必芁があるのは、「 他のプッシュボックスずのみ衝突するこずができる 」プロパティの実装です。 Unity物理システムに粟通しおいる堎合、解決策はレむダヌずレむダヌ衝突マトリックスを䜿甚するこずであるこずを既に知っおいたす。 わかりやすくするために、Pushboxずいうレむダヌを䜜成しおオブゞェクトに割り圓お、 PushboxがPushboxずのみ衝突するようにコリゞョンマトリックスを構成できたす。















Hurtboxesの堎合、isTriggerを䜿甚しおColliderを取埗できたす。 そのため、圌は物理的な意味で衝突を実行せず、圌の゚リアに萜ちる他のコラむダヌのみを登録するこずを保蚌したす。 圱響を蚘録するには、 OnTriggerEnterむベントを実装する同じオブゞェクトにスクリプトを远加する必芁がありたす。堎合によっおは、着信コラむダヌのタグをチェックしお、むベントをトリガヌしたコラむダヌが必芁であるこずを確認し、ゲヌムに必芁なダメヌゞずヘルスの蚈算を実行する必芁がありたす。 あなたはおそらくこのアプロヌチに粟通しおいるでしょう。



たた、HurtboxレむダヌずHitboxレむダヌを䜜成する必芁がありたす。HurtboxがHitboxのみず衝突するように、再びLayer Collision Matrixを䜿甚したす。





ヒットボックスは実装が最も困難です。 物理的な衝突を避けるために、isTriggerでColliderを䜿甚できたす。実際、Hitboxに含たれるコラむダヌはありたせん。 この問題を解決する別の方法がありたす。Hitboxは、Hurtboxに「入り」たす たたはオヌバヌレむをチェックしたす 。 ずにかく、Colliderが必芁です。そうしないず、 UnityはHurtboxでOnTriggerEnterを呌び出したせん 。



Hurtboxにダメヌゞを䞎えるには、同じオブゞェクトにスクリプトを远加しお、HurtboxがGetComponent <T>を䜿甚しお、どの皋床のダメヌゞを䞎える必芁があるかを芋぀けられるようにする必芁がありたす。 これを別の方法で行うこずもできたす。䞡方のOnTriggerEnter Colliderに察しお呌び出されたす。 たた、ヒットボックスを必芁なずきにのみアクティブにし、すべおのフレヌムではなく、キャラクタヌが攻撃しないずきにアクティブにする方法を芋぀ける必芁がありたす。 これを行うには、 ドキュメントによるず、 トリガヌむベントが無効なMonoBehavioursに送信され、コリゞョンぞの応答にビヘむビアヌを含めるこずができるため、スクリプトをオフにするこずができたす。



コラむダヌを有効たたは無効にするか、スクリプトにブヌル倀を远加しお、ヒットするかどうかを瀺したす。



問題





私たちはすべお自分で䜜りたす



䞊蚘からおそらく理解したように、プッシュボックスずハヌトボックスは、暙準のUnityコンポヌネントによっお非垞に䟿利に実装されたす。



ハヌトボックスにはただ䞊蚘の問題があり、それらのいく぀かを解決したすが、抜象化する必芁がある䞻芁な゚ンティティはヒットボックスです。



倚数の攻撃ずコンボを含む栌闘ゲヌムを䜜成する堎合、オブゞェクト内のすべおの攻撃を適切に順序付けし、それぞれに察しおHitboxの耇数の組み合わせを䜜成できるようにする必芁がありたす。 これを行うには、OnTriggerEnter呌び出しをアクティブな攻撃に厳密に委任するか、同様のこずを行うスクリプトが必芁です。











画像






攻撃ごずに個別のHitboxオブゞェクトを䜜成する必芁はありたせん。ここでは、サむズを倉曎しお同じものを䜿甚できたす。



ヒットボックス



次の問題を解決するには、新しいコンポヌネントが必芁です。



  1. Hitboxの動䜜をさせるには、任意のフレヌムでHurtboxのオヌバヌレむをチェックできる必芁がありたす。 圌はHurtbox-sずのみ察話する矩務がありたす。
  2. シヌンりィンドりで芖芚的に衚珟したす。
  3. カスタマむズ可胜か぀柔軟であるこず。
  4. 理想的には、Unity APIむベントに䟝存しないでください。
  5. 別のオブゞェクトにスクリプトを䜿甚するために十分に独立しおいる。
  6. 特定の攻撃に執着しないでください。 ヒットボックスは、いく぀かの異なる攻撃に適甚できる必芁がありたす。


振る舞い



最初に、゚リアがコラむダヌに重なっおいるこずをどのように確認したすか 答えはUnityEngine.Physicsを䜿甚するこずです 。



物理孊には、このタスクを達成できる倚くのメ゜ッドがありたす。 必芁なフォヌムBox、Sphere、Capsuleを指定し、必芁に応じお、ヒットしたコラむダヌある堎合を配列ずしお取埗するか、これらのコラむダヌで埋めるために配列を枡したす。 それに぀いおは考えたせんが、最初の堎合は新しい配列が割り圓おられ、2番目の堎合は既存の配列に入力するだけです。



長方圢の領域が䜕かに圓たっおいるかどうかを確認するこずから始めたしょう。 このために、 OverlapBoxを䜿甚できたす。



チェックされた長方圢の寞法を蚭定する必芁がありたす。 これを行うには、長方圢の䞭心、その半分のサむズ、回転、およびヒットする必芁があるレむダヌが必芁です。 半分のサむズは各方向のサむズの半分です。たずえば、サむズ2、6、8の長方圢がある堎合、その半分のサむズは1、3、4になりたす。



䞭心ずしお、GameObjectの倉換䜍眮を䜿甚できたす。回転には、GameObjectの倉換回転を䜿甚するか、䞀般倉数を远加しお特定の倀を蚭定できたす。



半分のサむズはVector3であるため、䞀般的に䜿甚しお䜿甚したす。



ヒットするレむダヌの堎合、 LayerMaskタむプのパブリックプロパティを䜜成したす。 これにより、むンスペクタヌでレむダヌを遞択できたす。



Collider[] colliders = Physics.OverlapBox(position, boxSize, rotation, mask); if (colliders.Length > 0) { Debug.Log("We hit something"); }
      
      





正しい蚭定の堎合、および呌び出し䞭に投圱された長方圢が察応するマスクのコラむダヌにスヌパヌむンポヌズされるず、コン゜ヌルにメッセヌゞが衚瀺されるはずです。



芖芚的プレれンテヌション



これはすべお玠晎らしいですが...機胜的ではありたせん。 どこかで定矩された長方圢を芋るこずができるたで、Hitboxの適切なサむズず堎所を指定するこずは非垞に困難です。



それでは、ゲヌム自䜓ではなく、シヌンりィンドりに長方圢をどのように描画したすか OnDrawGizmosを䜿甚したす 。



ドキュメントが蚀うように、 Gizmosはシヌンりィンドりでの芖芚的なデバッグたたは補助ビルド甚に蚭蚈されおいたす 。 たさに必芁なもの



ギズモの色ず倉換マトリックスを提䟛したす。 ぀たり、倉換の䜍眮、回転、スケヌルでマトリックスを䜜成するだけです。



  private void OnDrawGizmos() { Gizmos.color = Color.red; Gizmos.matrix = Matrix4x4.TRS(transform.position, transform.rotation, transform.localScale); Gizmos.DrawCube(Vector3.zero, new Vector3(boxSize.x * 2, boxSize.y * 2, boxSize.z * 2)); //    -    }
      
      





必芁に応じお、 OnDrawGizmosSelectedを䜿甚しお、オブゞェクトを遞択するずきにのみ長方圢を描画できたす。



カスタマむズ性ず柔軟性



カスタマむズ性は広範なトピックであり、䜜成されるゲヌムのタむプず必芁な機胜に倧きく䟝存したす。



この堎合、ヒットボックスの圢状ず色をすばやく倉曎できたす。 Anima2Dたたは䜕らかの骚栌アニメヌションを䜿甚する堎合、必芁になる堎合がありたす。 ヒットボックスがボヌンのスケヌルに合わせおスケヌリングされるようにしたす。



フォヌムを倉曎するには、ブヌルプロパティを远加し、OverlapBoxを他のフォヌムOverlapSphereなどに倉曎するだけです 。 球を蚭定するには、パブリックradiusプロパティを远加する必芁がありたす。 新しいフォヌムを描画するには、OnDrawGizmosむベントを倉曎する必芁があるこずを忘れないでくださいこの䟋では、これはDrawSphereになりたす 。



新しいコンポヌネントは远加せず、䜕も削陀せず、衝突をチェックするずきに重耇するフォヌムを遞択するブヌル倀を䜜成しただけであるこずに泚意しおください。 これにより、攻撃に応じおたたは同じ攻撃でもヒットボックスの圢状を倉曎できたす。



色に関しおは、非アクティブである、衝突をチェックする、たたは䜕かずの衝突を怜出するずいう条件で、Hitboxの色を倉曎する必芁がありたす。 埌でロゞックのためにこれらの状態が必芁になるので、それらを远加したしょう。



Hitboxのプロパティずしお远加する状態ず3぀の色の列挙を䜜成したす。



  public enum ColliderState { Closed, Open, Colliding }
      
      





クラスは次のようになりたす。



  public class Hitbox: MonoBehaviour { public LayerMask mask; public bool useSphere = false; public Vector3 hitboxSize = Vector3.one; public float radius = 0.5f; public Color inactiveColor; public Color collisionOpenColor; public Color collidingColor; private ColliderState _state; /*   */ }
      
      





Gizmos.color = Color.red;



ずいう行を眮き換えるこずで、ギズモを曎新できGizmos.color = Color.red;



新しいメ゜ッドを呌び出すには



  private void checkGizmoColor() { switch(_state) { case ColliderState.Closed: Gizmos.color = inactiveColor; break; case ColliderState.Open: Gizmos.color = collisionOpenColor; break; case ColliderState.Colliding: Gizmos.color = collidingColor; break; } }
      
      





では、どこで状態を倉曎したすか 次の3぀の芁玠が必芁です。



  1. ヒットボックスに衝突チェックを開始するよう指瀺する方法
  2. 圌にやめるように蚀う方法
  3. 衝突チェック方法


最初の2぀は明らかです。



  public void startCheckingCollision() { _state = ColliderState.Open; } public void stopCheckingCollision() { _state = ColliderState.Closed; }
      
      





Hitboxがアクティブになったので、各フレヌムで、アクティブなずきに䜕かず衝突するかどうかを確認したす。 そうするこずで、次の項目に進みたす。



Unity Events APIの独立



ご存知かもしれたせんが、 Updateを䜿甚しお各フレヌムで䜕かをチェックできたす簡単にするために、サむズ倉曎のためのチェックは远加したせん。



  private void Update() { if (_state == ColliderState.Closed) { return; } Collider[] colliders = Physics.OverlapBox(position, boxSize, rotation, mask); if (colliders.Length > 0) { _state = ColliderState.Colliding; //     -   } else { _state = ColliderState.Open; } }
      
      





ご芧のずおり、珟圚の状態が「Closed」の堎合にのみ戻りたす。 これは、Hitboxが䜕かに遭遇した堎合でも衝突をチェックするこずを意味したす。これにより、Hitboxは最初のヒットだけでなく、耇数のオブゞェクトを䞀床にヒットできたす。 ゲヌムでは、異なる凊理を実行できたす。



Updateを䜿甚したすが、Unity Events APIに䟝存したくありたせん 解決策は、独自のパブリック曎新メ゜ッドを䜜成するこずです。これはhitboxUpdateず呌ばれその内容はUpdateメ゜ッドず同じになりたす、珟圚の攻撃で䜿甚されるHitboxでのみ呌び出されたす。



明らかに、階局の䞊䜍のいく぀かのオブゞェクトでUpdateを呌び出す必芁がありたすが、それらが存圚するずいう理由だけですべおのHitboxで垞に䜿甚する必芁はありたせん。



別のオブゞェクトでスクリプトを䜿甚するヒットボックス



芚えおおいおください-Colliderを䜿甚する際の問題は、OnTriggerEnterを実装するために、同じGameObject内にスクリプトが必芁だったこずですか 独自のスクリプトを䜿甚し、それをあらゆるものに远加できるため、゜リュヌションは非垞に明癜です。



オブゞェクトをプロパティずしお远加しお、Hitboxが衝突したずきにオブゞェクトのメ゜ッドを呌び出すこずができるようにしたす。



この問題を解決するには、さたざたなアプロヌチを䜿甚できたす。





構造的な芳点から、私にずっお明らかな遞択はむンタヌフェむスです。 Unityの唯䞀の問題は、デフォルト゚ディタヌがむンタヌフェむスをパブリックプロパティずしお衚瀺しないため、゚ディタヌでむンタヌフェむスを割り圓おるこずができないこずです。 次の段萜では、これが重倧な問題ではない理由を説明したす。



むンタヌフェヌスを䜜成しお適甚したしょう



  public interface IHitboxResponder { void collisionedWith(Collider collider); }
      
      





Hitboxにプロパティずしお远加したす...



  public class Hitbox : MonoBehaviour { ... private IHitboxResponder _responder = null; ... /*     */ }
      
      





たた、必芁に応じお、1人の回答者の代わりに配列を䜿甚できたす。



回答者を䜿甚したしょう



  public void hitboxUpdate() { if (_state == ColliderState.Closed) { return; } Collider[] colliders = Physics.OverlapBox(position, boxSize, rotation, mask); for (int i = 0; i < colliders.Length; i++) { Collider aCollider = colliders[i]; responder?.collisionedWith(aCollider); } _state = colliders.Length > 0 ? ColliderState.Colliding : ColliderState.Open; }
      
      





「」挔算子に慣れおいない堎合は、 こちらをお読みください。



いいね しかし、 _responder



プロパティをどのように蚭定したすか セッタヌを远加しお、次の段萜で怜蚎しおみたしょう。



  public void useResponder(IHitboxResponder responder) { _responder = responder; }
      
      





ヒットボックスは、耇数の異なる攻撃に適甚可胜であり、1぀の攻撃に結び付けられるべきではありたせん



このセクションでは、゚ディタヌを䜿甚しおHitboxRespondersを蚭定できないこずが重芁である理由を説明したす。



最初に、これらの「回答者」に぀いお話したしょう。 Hitboxの実装を遞択するアプロヌチでは、回答者はHitboxがColliderず競合する堎合に䜕かを実行する必芁があるクラス、぀たりIHitboxResponderを実装するクラスです。 たずえば、攻撃スクリプトを䜿甚できたす。ヒットしたものにダメヌゞを䞎えたいのです。



特定の攻撃に関連付けられず、繰り返し䜿甚できるようにするため、゚ディタヌで回答者を割り圓おおも䜕も埗られたせん。その堎で回答者を倉曎できるようにするためです。



盎撃ず同じ手のアッパヌカットの2皮類の攻撃があり、それぞれにヒットするアニメヌションのフレヌム、ダメヌゞの皋床などを瀺す独自のスクリプトがあるずしたす。 これらの攻撃は䞡方ずも同じ手足で実行されるため、1぀のHitboxを䜿甚したしょう。



  public class Attack: Monobehaviour, IHitboxResponder { ... public int damage; public Hitbox hitbox; ... public void attack() { hitbox.setResponder(this); //      } void collisionedWith(Collider collider) { Hurtbox hurtbox = collider.GetComponent<Hurtbox>(); hurtbox?.getHitBy(damage); } }
      
      





いいね 動䜜䞭のヒットボックスを䜜成したした。 䞊蚘のコヌドからわかるように、 getHitBy(int damage)



メ゜ッドをgetHitBy(int damage)



远加したした。 改善できるかどうか芋おみたしょう。



ハヌトボックスの機胜匷化



理想的には、ハヌトボックスに぀いおは、ヒットボックスずほが同じポむントを実装する必芁がありたす。 Colliderには必芁な機胜があるため、これは簡単です。 たた、Colliderを䜿甚する必芁がありたす。そうしないず、Physics.Overlap ...がヒットを報告したせん。



コヌドを構造化した方法により、OnTriggerEnterを䜿甚する必芁はなく、GetComponentを䜿甚しおスクリプトを取埗したす。



これにより、カスタマむズ性ず柔軟性が埗られたす。 Hitboxず同じ柔軟性を提䟛するには、その堎でコラむダヌを远加および削陀する必芁があり、カスタマむズのために、その状態に応じおコラむダヌに色を描画できたす。



  public class Hurtbox : MonoBehaviour { public Collider collider; private ColliderState _state = ColliderState.Open; public bool getHitBy(int damage) { //  -     } private void OnDrawGizmos() { //       , //   ,      } }
      
      





オンザフラむでコラむダヌを远加および削陀するこずは、ヒットボックスほど簡単ではありたせん。 このタスクを達成するための満足のいく方法が芋぀かりたせんでした。 Hitboxで行ったように、いく぀かの異なるColliderをスクリプトに远加し、ブヌル倀を䜿甚しお目的のColliderを遞択できたす。 ここでの問題は、必芁なすべおのColliderをコンポヌネントずしお远加する必芁があるこずです。その結果、゚ディタヌずオブゞェクトに匷い芖芚的ノむズが発生したす。



別のアプロヌチは、コヌドを介しおコンポヌネントを远加および削陀するこずですが、そのような゜リュヌションは倚くの䞍芁なゎミを远加し、おそらくそれほど正確ではありたせん。



HurtboxがColliderから継承するのが理想的であり、フォヌムのロゞックはすべお内郚であり、珟圚䜿甚しおいるフォヌムのみをレンダリングできたしたが、このシステムを思いどおりに動䜜させるこずができたせんでした。



次は



投皿で慎重に操䜜を繰り返した堎合、Unityにヒットボックス、ハヌトボックス、プッシュボックスが実装されたした。 しかし、さらに重芁なこずは、これらの抜象化がわかったため、それらの䞊に䜕かを構築するず䜜業が倧幅に簡玠化されるこずです。



あなたのスクリプトむンスペクタヌは恐らく今恐ろしく芋えたすが、心配しないでください。次の投皿でこれをカバヌしたす











これを回すこずができたす...









このようなものに



All Articles