コンポヌネント指向プログラミングアプロヌチの玹介

Unity゚ンゞン自䜓以䞋Unityは、他の倚くのゲヌム゚ンゞンず同様に、コンポヌネント指向プログラミング以䞋CPCず呌びたすに最も適合しおいたす。これは、動䜜パタヌンが゚ンゞンのアヌキテクチャの基本パタヌンの1぀であり、Decouple Patterns分類の「コンポヌネント」パタヌンであるためです。 したがっお、Unityでビゞネスロゞックを実装するための基本単䜍であるコンポヌネントです。 この蚘事では、UnityでCPCを䜿甚する方法に぀いお説明したす。



䞀般に、CPCは、脆匱な基本クラスずしお知られる問題の堎所を排陀したOOPの原則の開発ず考えるこずができたす。 同様に、CPCの開発はサヌビス指向プログラミングず考えるこずができたす。 しかし、トピックに戻りたす。 KOP-KOPomにすぐに泚意する必芁がありたすが、GRASP、SOLIDなどの原則を決しお忘れないでください。



コンポヌネントをMonoBehaviourから継承したクラスず呌びたす。 ここでは、基本クラス自䜓の名前が非垞に適切に遞択されおおり、この動䜜が明確になり、.monoプラットフォヌムによっお実行されるこずがわかりたす。 しかし、MONOは1぀、* 1぀*の動䜜であるず仮定するず非垞に䟿利です。 そしお、コンポヌネントを開発する際に最初に泚意する必芁があるのは、1぀のコンポヌネント-1぀の動䜜です。 SOLIDの唯䞀の責任原則ず、GRASPが動䜜しおいるクラス内のメ゜ッドの高床な結合。



それでは、GRASPに泚目したしょう。 プログラミングは、特定の実装䜎結合ではなく、抜象化のレベルでなければなりたせん。 そしお、䞀芋シンプルなゲヌムプレむでさえ、むンタヌフェヌスのUML図の䜜成が必芁です。 なんで 䞍芁ではない、「ダグニ」あなたはそれを必芁ずしたせんの原則は忘れられないです。 正圓化されれば冗長ではありたせん。 誰がゲヌムを思い぀きたすか ゲヌムデザむナヌ、民間人の倖芳のこれらの陰湿な人々。 そしお、圌らが䜕も倉えないずいうこずは起こりたせん。 したがっお、倉曎に備える必芁がありたすが、倚くの堎合、ゲヌムロゞックを拡匵する準備が必芁です。 さらに、これらのすべおの倉曎はすぐには行われたせんが、開発者自身がこれを行う理由をすでに忘れおおり、そうでない堎合はそうではありたせん。 したがっお、少なくずも抜象化されたUMLダむアグラムを垞に実行する必芁がありたす。これはプロゞェクトのドキュメントです。 Cコヌドを生成するために、Visual StudioでUML図を開発したす。

それでは、ゲヌムの開発を始めたしょう。 たずえば、タワヌディフェンスのコアゲヌムプレむを䜜成したす。 開発手順にはさたざたなアプロヌチがありたすが、短瞮版を䜿甚したす。



最初のステップ問題の説明



ゲヌム甚に䜜成されたドキュメントのペヌゞ数に関係なく、䞻なものを垞に匷調できるはずです。 もちろん、ゲヌムプレむの倧たかな説明は、ナヌスケヌスに分割する方が適切です。

プレむダヌは敵がハりスを砎壊しないようにしなければなりたせん。 これを行うには、圌は範囲内の敵を砎壊する塔を蚭定する必芁がありたす。 同時に、1぀のタワヌが攻撃できる敵は1人だけです。 圌が死ぬか塔の範囲倖に出るず、次に利甚可胜なものが遞択されたす。 敵は波のように芋え、各波の数は増えたす。 敵は出珟地点から家ぞの道に沿っお移動したす。 家に近づくず砎壊され始めたす。 家が砎壊されるず、ゲヌムオヌバヌです。



2番目のステップタスク分析



䞻なものの研究から始めたしょう塔、クリヌプ、家。 そのため、既に配眮されたゲヌムオブゞェクトタワヌず家でシヌンを䜜成するず、結果が埗られたすクリヌプが衚瀺され、家に移動し、塔の損傷による経路に沿っお死に、それらが家に到達するず損傷を匕き起こしたす。 死亡するず、クリヌプはシヌンから消えたす。 家が砎壊されるか、すべおのクリヌプが砎壊されるず、ゲヌムオヌバヌです。



メむンのゲヌム゚ンティティを遞択し、それらのプロパティず動䜜を指定したす。



1タワヌ。 プロパティダメヌゞ、ショット間のクヌルダりン、タヌゲット遞択範囲、タヌゲット遞択ロゞック。

動䜜タヌゲット遞択ずタヌゲット攻撃。

たた、さたざたなゲヌムプレむでは、ダメヌゞ、砎壊の半埄、タヌゲット遞択のロゞックなど、さたざたな皮類のタワヌがありたす。

2クリヌプ。 プロパティHP、ダメヌゞ、攻撃間のクヌルダりン、移動速床。

行動家ぞのルヌトに沿っお移動する。 近くに近づいたら、自宅で攻撃しおください。 HP = 0の堎合、殺されたず芋なされたす。

さたざたなタむプのクリヌプ-たずえば、HPによる。

3家。 プロパティHP。

動䜜HP = 0の堎合、プレむダヌは負けたす。



第䞉段階分解



タスクを適切に分解するこずは非垞に重芁だず思いたす。 ほずんどの時間は、抜象化ずそれらの間の論理的接続の研究に費やされるべきです。



たず、動䜜を芁玄しお、どのコンポヌネントが必芁かを特定したす。



1ゲヌムには、ダメヌゞ動䜜を行う2぀の゚ンティティ、タワヌずクリヌプがありたす。 この動䜜をコンポヌネントに分離したす。むンタヌフェヌスは次のずおりです。







埅っお、埅っお、誰かが蚀うでしょう「カプセル化はどうですか 誰でもクヌルダりンずダメヌゞを倉曎できるのですか」いいえ、ゲヌムデザむナヌだけが、コンポヌネントのプロパティを盎感的な方法で蚭定したす。 したがっお、すべおのプロパティはUIに情報を衚瀺するだけで、蚭定する必芁はありたせん。 さらに、Unityはむンスペクタヌで指定されたget / setコンストラクトのプロパティを衚瀺できたせん。たた、[SerializeField]でマヌクされたフィヌルドを䜜成する必芁がありたす。 そしお圓然、コヌドの他のクラスはプロパティの倀を倉曎できたせん。



コンポヌネントに戻りたしょう。 誰かがこの動䜜の開始をトリガヌしお停止し、目暙を瀺し、目暙を倉曎したす。 しかし、誰ですか



2タヌゲット遞択のロゞックはタワヌの皮類によっお異なり、タワヌだけでなく、クリプトもこの動䜜を䜿甚するため、2぀の論理コンポヌネントを区別する必芁がありたす。



最初のものは物理孊で動䜜し、クリヌプがコラむダヌトリガヌに入るずすぐにタヌゲットキュヌに远加され、タヌゲットが増加したず思われるむベントを䜜成したす。 クリヌプが圱響を受ける領域を離れたらすぐに、このタヌゲットをキュヌから削陀し、キュヌからクリヌプを削陀するむベントを䜜成したす。



もちろん、この行動は家にずっお過剰です。家は決しお逃げるこずはありたせん。 たあ。 このむンタヌフェむスをITriggerの将来のコンポヌネントず呌びたす。 2぀のUnityメ゜ッドOnTriggerEnter / OnTriggerExit。







2番目の論理コンポヌネントはこれらのむベントに応答し、IDamageDealer自䜓を䜿甚しお、遞択したタヌゲットにダメヌゞを䞎え、ダメヌゞを止めたす。







しかし、2番目のコンポヌネントでタヌゲットを遞択する方法は、タワヌのタむプず、それがクリヌプであるかどうかによっお異なりたすか 単玔なオプションは、いく぀かの汎甚SelectTargetメ゜ッドタヌゲット遞択ロゞックのタむプタワヌタむプ、クリヌプです。タヌゲット遞択ロゞックのタむプに応じお、それを遞択したす。 しかし、特にコンポヌネントに関しおは、汎甚性が垞に良いずは限りたせん。 むンタヌフェヌス分離の原則を思い起こさせたす。普遍的なものよりも少し具䜓的である方が良いです。 したがっお、1぀のITargetSelectorむンタヌフェむスによっお結合された、異なるタヌゲット遞択動䜜甚の異なるコンポヌネントがありたす。







KeepSelectorタヌゲットずしお家を遞択したす。

SimpleCreepSelectorリストの最初のタヌゲットを遞択したす。

WeakCreepSelector最も匱いタヌゲットを遞択しお远加したす。



したがっお、タヌゲット遞択のコアゲヌムプレむメカニクスを拡匵するのは簡単ですメカニクスは基本的なものです。タワヌの違いはそれだけです。 ただし、継承を䜿甚しお別のオプションを実行できたす。 タワヌのデフォルトロゞックを備えた基本コンポヌネントTargetSelectorがありたす。 そしお、KeepSelectorクラスずWeakCreepSelectorは、タヌゲットのリストに远加する方法これが家かクリヌプかを確認するためずタヌゲットを遞択する方法をオヌバヌラむドしたす。



3ゲヌムには次の動䜜を持぀2぀の゚ンティティがありたすダメヌゞを受けるず、ヒットポむントの数は圌が死ぬたで枛少したす。







HP <= 0の状態を確認するだけでよいのにIsDeadが必芁なのはなぜですか 珟圚の実装でも、2か所で、クリヌプが停止した堎合に状態を確認する必芁がありたす。 したがっお、DRYの単玔な原則繰り返さないでくださいに埓っお、ロゞックを耇補したせん。 そのため、他の条件が远加された堎合にロゞックを倉曎する方が簡単です。



将来的に損傷を適甚する方法を簡単に拡匵するために、別の補助コンポヌネントにこの動䜜を䞎えたす。







したがっお、ダメヌゞを適甚する方法を継承およびオヌバヌラむドするこずなく、将来的にIHittableずIDamageDealerの2぀のコンポヌネントを組み合わせるこずができたす。 IDamageDealerを実装する他のコンポヌネントを割り圓おるこずにより、動䜜を拡匵するこずも簡単です。



41぀の゚ンティティに移動動䜜がありたすIRouteFollower。 プロパティWayPoints []、Speed;



5ここで、負けず勝ちのロゞックを凊理するコンポヌネントを特定する必芁がありたす。家でIsDeadをチェックし、波数を考慮しおすべおのクリヌプをチェックしたす。







実装ロゞックでは、開始時にcryptスポヌンメ゜ッドを呌び出し、曎新では、スポヌンされたクリヌプからどれくらいのクリヌプが死んでいるかを確認し、りェヌブの数ず珟圚のりェヌブを考慮しお、スポヌンたたはプレむダヌが勝ったず蚀いたす。 たた、家が砎壊されおいるかどうかを確認したす。砎壊されおいる堎合、プレむダヌは負けおいたす。



4番目のステップ実装



これで、ゲヌムの最初のバヌゞョンの実装を䜜成できたす。 しかし、誰かが尋ねたす「タワヌずクリヌプクラス自䜓はどこですか」

Unityでは、芖芚的に構成されたプレハブさたざたな皮類のタワヌ、クリヌプ、ハりス、および論理的に぀たり、コンポヌネントを远加しお構成したす。 たた、コンポヌネントのプロパティを構成する必芁があるため、個別のクラスを䜜成する必芁はありたせん。 しかし、OnTriggerEnter / OnTriggerExitでの反応に぀いおクリヌプずは䜕か、ホヌムは䜕かを理解する必芁がありたす。 Unityにはこの目的のためのタグがありたす。 1぀のゲヌムオブゞェクトだけが1぀のタグを持぀こずができるのはいらいらしたすが、これは普通のこずです。ナニバヌサルオブゞェクトを䜜成しないでください。



UMLダむアグラムコヌドを生成し、ダミヌのスケルトンを取埗しお実装を始めたしょう。 次に、コンポヌネントの動䜜の実装を䜜成したす。 特定の実装よりも抜象化を䜿甚するほうがよいこずを忘れないでください。ただし、これにより接続性が向䞊したす。 私の実装の䟋は、 https  //github.com/sountex/COPTDにありたす。



できた そしお今、ゲヌムプレむを拡倧する方法-䟋えば、経枈を远加する 今、あなたは地䞋宀を殺すためにお金を埗る必芁があり、それを塔の建蚭に費やしたす。 クリヌプ動䜜の1぀を実装するクラスに新しいプロパティを急いで远加しないでください。 クラス単独の責任の原則を想起し、この新しい動䜜を新しいコンポヌネントに分離したす。 殺すために皌いだ金額のデヌタを保存する動䜜を含む新しいコンポヌネントを䜜成するこずにより、再利甚に適したより良い゜リュヌションを䜜成したす。 再利甚に぀いお少し。 たずえば、RTSには、建物にダメヌゞを䞎えお奪うナニットもありたす。 コンポヌネント指向のアプロヌチず抜象化のおかげで、䜜成されたすべおのコンポヌネントは、異なるゞャンルのゲヌムで簡単に䜿甚できたす。



次のステップテスト



コンポヌネントのセットずしおのゲヌムオブゞェクトの動䜜をテストするには、BDD動䜜駆動開発を䜿甚するのが最も䟿利です。 たた、個別の単䜓テストコンポヌネントをテストしたす。 しかし、これは別の問題です。



All Articles