無限のゲヌムの䟋ずしお、Unityで2D物理孊ず戊う





私の奇劙な創造的な道は、私にゲヌムの開発をもたらしたした。 私たちの倧孊ず協力するギリシャ語のスモヌルレタヌを1぀持぀IT䌁業の優れた孊生プログラムのおかげで、チヌムを線成し、ドキュメントを䜜成し、高品質のQA゚ンゞニアhello、Annaの監督の䞋でアゞャむルゲヌム開発をセットアップするこずができたした



あたり考えずに、Unityが゚ンゞンずしお遞択されたした。 これは玠晎らしい゚ンゞンで、非垞に悪いゲヌムをすばやく簡単に䜜成するこずができたす。 優れたゲヌムを䜜成するには、ドキュメントをシャベルで掘り䞋げ、いく぀かの機胜を掘り䞋げ、開発経隓を積む必芁がありたす。



私たちのゲヌムは、物理的な゚ンゞンを予想倖の方法で䜿甚し、モバむルプラットフォヌムで倚くのパフォヌマンスの問題を匕き起こしたした。 この蚘事は、私たちのゲヌムの䟋ずしお、物理゚ンゞンず、実行可胜なベヌタ版ぞの道のりで芋られたその仕事のすべおの機胜ずの私の苊劎に぀いお説明しおいたす。



ゲヌム



ゲヌムのGIF


それがどのように䜜られたかに぀いおのいく぀かの蚀葉。

Blenderずいく぀かのPythonスクリプトを䜿甚しお䜜成されたした。 撮圱時には、画面の隅に16個の正方圢があり、その色は浮動小数点数の32ビットを゚ンコヌドしたした。これは、特定の時間での電話の回転です。 R、G-デヌタ、B-パリティ。 0-0、255-1。コンピュヌタヌでキャプチャされたビデオは、ffmpegを䜿甚しおフレヌムに分割され、デコヌドされた各フレヌムには解読された角床が割り圓おられたした。 この圢匏により、撮圱プロセス䞭の圧瞮に耐えるこずができ、すべおのプログラムが時間の経過に぀いおわずかに異なるアむデアを持っおいるずいう事実を克服したした。 実際には、ゲヌムはレンダリングず同じ方法でプレむされたす。



飛行機は無限の予枬䞍可胜な掞窟を飛行したす。そこにはボヌナス、あらゆる皮類のコむン、敵がホヌミングミサむルを撃぀こずができたす。 壁に衝突-すぐに倱われたした。

このゲヌムの特城は、レベルが地平線に釘付けされ、その制埡がゞャむロスコヌプであり、さらに絶察的であるこずです。 電話を45床傟けた-飛行機は45床の角床で飛んだ。 デッドルヌプを䜜成する必芁がありたす-タブレットをねじる必芁がありたす。 感床はなく、ハヌドコアのみです。

開発者にずっお、2぀の䞻な明らかな問題がありたす。



問題1無限倧


Unityは、オブゞェクトの座暙を小数点以䞋6桁たでの粟床で通垞の32ビット浮動小数点数の圢匏で保存および凊理したす。 問題は、私たちのゲヌムが無限であり、十分に長く飛べば、壁を介しおテレポヌトするたで、さたざたな皮類のクレむゞヌなバグが発生するこずです。 この問題を解決するには、いく぀かのアプロヌチがありたす。



  1. 無芖する たずえば、Minecraftでは、䞞め誀差によっおゲヌムがより面癜くなり、 「遠くの土地」ずいう珟象が発生したした。
  2. 飛行機が原点から遠すぎる堎合は、0; 0; 0にテレポヌトしたす。
  3. 基準点の倉曎。 移動するのは平面ではなく、その呚囲のレベルです。


この堎合、受け入れられる唯䞀のオプションは、実装された3番目のオプションです。 実装に぀いお-少し埌で。

最初の-無芖-は絶察に受け入れられたせん。 私たちのゲヌムを氞遠にプレむできるロボットを䜜成するこずは、誰かが解決する興味深いそしお非垞に単玔なタスクです。 はい、そしお普通の韓囜人プレむダヌを過小評䟡すべきではありたせん-飛行機は高速で、レベルは予想倖に生成されたす。 そしお、壁を通過する前に飛ぶず、5分間の飛行の埌、より正確な射撃が明らかに倱敗し始めたす。

2番目-プレむダヌず党䞖界のテレポヌト-モバむルデバむスをひざたずかせ、堎合によっおは-箄0.5秒間。 これは非垞に顕著であるため、受け入れられたせん。 しかし、これは単玔な無限のPCゲヌムには完党に受け入れられるオプションです。



問題2レベルの生成






無限のランナヌを構築するには、いく぀かの基本的なアプロヌチがありたす。



  1. ランダムに結合された既補のレベルセグメントの䜿甚。 これは、たずえばSubway Surfersで行われたす。 実装は簡単ですが、プレヌダヌはすぐに慣れお、䜕を準備するかを知っおいたす。これは退屈です。
  2. レベルずは、障害物がランダムに配眮される単なる線です。 これは、Joypack JoyrideずTemple Runで行われたす。 私たちの堎合、これにより操䜜の数が倧幅に制限されたす。
  3. すべおがランダムに生成されたす。 プレむダヌにずっお最も難しく、予枬䞍可胜で興味深いオプションです。


もちろん、最も難しいオプションを遞択したした。 圌の心の䞭には、非垞に耇雑な状態の機械があり、それらはランダムな遷移を実行したす。 しかし、この蚘事のフレヌムワヌク内では、興味深いメカニズムではなく、遞択した参照ポむントを考慮したレベル生成プロセスずその組織です。



レベル構造






私たちは掞窟を飛びたす。床ず倩井がありたす-いく぀かのブロック、基本的な建物ナニット。 ブロックは、シヌムレスに適合するセグメントに結合されたす。 セグメントは、党䜓ずしお、航空機の呚りを回転し、その速床ベクトルに沿っお移動し、飛行の錯芚を䜜り出したす。 セグメントがカメラの芖野を離れるず、ゞェネレヌタヌの指瀺に埓っお、ブロックがクリアされ、レベルの最埌のセグメントにドッキングされ、新しいブロックで埋められたす。 そのようなセグメントの党䜓がレベルです。



経隓豊富なUnity開発者は、䜜業量ず考えられるすべおの萜ずし穎を考慮しお、正圓に眉をひそめるこずができたした。 しかし、蚀葉ではすべおが簡単ですが、私は開発経隓がありたせんでした...



Unityの物理の基本法則



1か月の開発、実隓、およびドキュメントの読み取りのために、Unityで物理孊の3぀の基本法則を特定したした。 違反する可胜性はありたすが、違反のコストは生産性です。 ゚ンゞンは間違いに぀いお譊告するこずはなく、プロファむラヌがなければそれらに぀いお知るこずはできたせん。 これらの法埋を順守しないず、ゲヌムが数十倍遅くなる可胜性がありたす。 私が理解しおいるように、法埋に違反するず、物理゚ンゞンが問題のコラむダヌを䞍正ずしおマヌクし、オブゞェクト䞊で再䜜成し、その埌に物理の再蚈算を行うずいう事実に぀ながりたす。



1.コラむダヌは、移動、回転、オン/オフ、およびサむズ倉曎しないでください。


オブゞェクトにコラむダヌを远加したらすぐに、コラむダヌたたはそれが含たれおいるオブゞェクトぞの圱響を忘れおください。 通垞のコラむダヌは非垞に静的なオブゞェクトです。 たずえば、ツリヌにはコラむダヌが1぀ありたす。 ツリヌがプレヌダヌに萜ちる可胜性がある堎合、そのツリヌはパフォヌマンスずずもに萜ちたす。 この朚が、コラむダヌが持っおいないが動くこずができる魔法の栄逊䟡の高い雲から成長する堎合、生産性の䜎䞋を䌎いたす。



2.オブゞェクトが移動たたは回転する堎合-固䜓でなければなりたせん Rigidbodyコンポヌネントが必芁です。


これはドキュメントに蚘茉されおいたす、はい。 Unityは非垞にシンプルで盎感的であるため、ゲヌムの䜜成を開始するために思慮深く読む必芁はありたせん。

リゞッドボディは、オブゞェクトに察する物理゚ンゞンの姿勢を倉曎したす。 倖力がそれに圱響を䞎え始め、線圢および角速床を持ち、最も重芁なこずは、物理孊の完党な再蚈算を匕き起こすこずなく、物理゚ンゞンによっお固䜓を移動および回転できるこずです。

固䜓には、通垞ず運動の2皮類がありたす。 普通の䜓は互いに、たた普通のコラむダヌず盞互䜜甚したす。ある䜓は別の䜓を通過できたせん。 キネマティックボディは、単玔化されたシミュレヌションのルヌルに埓いたす。重力などの倖力の圱響を受けたせん。 圌らは自由に互いに通過しおコラむダヌを通過できたすが、無限の質量を持っおいるかのように普通の固䜓をはじきたす。

オブゞェクトが物理゚ンゞンの制埡䞋で䞎えるのが残念ではない堎合-通垞の゜リッドを䜿甚したす。 たずえば、厖から石を矎しく転がす必芁がある堎合。 スクリプトたたはアニメヌタヌがオブゞェクトを盎接制埡する堎合-キネマティックボディを䜿甚するため、゚ンゞンずオブゞェクトのランダムな衝突に垞に苊劎する必芁はありたせん。 たずえば、アニメヌションキャラクタヌたたは誘導ミサむルが䜕かず接觊したずきに爆発する堎合。



3.オブゞェクトが゜リッドボディの堎合-゜リッドボディのメ゜ッドを介しお移動および回転する必芁がありたす。


コラむダヌを远加した盎埌にオブゞェクトのトランスフォヌムに盎接アクセスするこずを忘れおください。 今、そしお氞遠に、トランスフォヌムは敵であり生産性を損なうものです。 transform.position = ...たたはtransform.eulerAngles = ...を蚘述する前に、「私は今、私がやっおいるこずを完党に明確に理解したした。この行によっお匕き起こされるブレヌキに満足しおいたす」ずいうフレヌズを蚀っおください。 階局関係を忘れないでください。゜リッドを含むオブゞェクトを突然移動するず、物理が再蚈算されたす。



゜リッドステヌト制埡には3぀のレベルがありたす。


-最高レベル、したがっお自然なレベルは、匷さによるものです。 これらは、AddForceおよびAddTorqueメ゜ッドです。 物理゚ンゞンは䜓重を考慮し、結果の速床を正しく蚈算したす。 身䜓の盞互䜜甚はすべおこのレベルで行われたす。

-䞭玚レベル-速床の倉曎。 これらは、速床ず角速床のプロパティです。 それらに基づいお、盞互䜜甚䞭に身䜓に圱響を䞎える力が蚈算され、明らかに、次の瞬間の身䜓の䜍眮も蚈算されたす。 ゜リッドボディの速床が非垞に遅い堎合、リ゜ヌスを節玄するために「眠りに萜ちる」。

-最䞋䜍レベルは、オブゞェクトの座暙ず空間内の向きです。 これらは、MovePositionおよびMoveRotationメ゜ッドです。 物理蚈算の次の反埩これは重芁です。1぀のフレヌム内の埌続の各メ゜ッド呌び出しは前のメ゜ッドを眮き換えるためですは、オブゞェクトを新しい䜍眮にテレポヌトしたす。 私たちのゲヌムは、オブゞェクトを完党に制埡できるため、たさにこのレベルを䜿甚しおいたす。



船倖に残っおいるものは䜕ですか オブゞェクトずスケヌルのオン/オフを切り替えたす。 ゚ンゞンを混乱させるこずなくオブゞェクトのサむズを倉曎する方法があるかどうかはわかりたせん。 そうではない可胜性がありたす。 オブゞェクトをオフにするのは簡単で、オンにしたす...はい、オンにしたオブゞェクトの近くの物理を再蚈算したす。 したがっお、同時に倚くのオブゞェクトを含めないようにしお、ナヌザヌが気付かないようにこのプロセスを時間内に拡匵しおください。



パフォヌマンスには圱響したせんが、パフォヌマンスには圱響する法埋がありたす。゜リッドは゜リッドの䞀郚にはなれたせん。 芪オブゞェクトが支配的であるため、子は芪に察しお静止したたたになるか、予枬䞍胜で誀った動䜜をしたす。



Unityには、物理​​孊に関係しないが蚀及に倀する別の機胜がありたす。Instantiate/ Destroyメ゜ッドを䜿甚したオブゞェクトの動的な䜜成ず削陀は、非垞に遅いプロセスです。 オブゞェクトの䜜成䞭にフヌドの䞋で䜕が起こっおいるか想像するこずすら恐れおいたす。 䜕かを動的に䜜成および削陀する必芁がある堎合は、工堎を䜿甚し、ゲヌムの読み蟌み䞭に必芁なオブゞェクトでそれらに燃料を補絊したす。 むンスタンス化は最埌の手段ずしお呌び出す必芁がありたす-ファクトリヌが突然空きオブゞェクトを䜿い果たし、氞久に砎棄するこずを忘れた堎合-䜜成されたすべおを再利甚する必芁がありたす。



法埋を実践する



このセクションでは、ゲヌムずその機胜を䜜成する際の掚論の行です







レベルは明らかに回転しお移動する必芁がありたす。

レベルの回転軞飛行機を原点に配眮するこずで、人生を氞遠に楜にしたす。 これで、ポむントの座暙ベクトルの長さを蚈算するこずにより、ポむントからポむントたでの距離を蚈算できたす。 些现なこずですが、玠晎らしい。

子は芪の䞀郚であるため、オブゞェクトの共同移動はUnityのオブゞェクトの階局を通じお簡単に実装されたす。 たずえば、説明されおいるレベル構造は、次のように論理的に実装されたす。

-





- - \





- - - \ 1





- - - - \ 1 (Collider)





- - - - \ ...





- - - - \ N





- - - \ 2 ...





- - - \ 3 ...





- - - \ 4 ...





レベルオブゞェクトなしでも実行できたす



軞䞊のスクリプトは、ゞャむロスコヌプからデヌタを受信し、適切な角床を蚭定したす...そしお、回転が階局に沿っおコラむダヌに送信されるため、䞀床に倚くのルヌルに違反したす。 軞を゜リッドボディにし、適切な方法で回転させる必芁がありたす。 しかし、レベルの動きはどうですか 明らかに、回転軞ずレベルオブゞェクトは移動したせん。各セグメントを個別に移動する必芁がありたす。そうしないず、無限の問題に盎面したす。 したがっお、゜リッドはセグメントでなければなりたせん。 しかし、すでに階局の䞊䜍に゜リッドボディがあり、゜リッドボディを゜リッドボディの䞀郚にするこずはできたせん。 論理的で゚レガントな階局は適合せず、回転軞にオブゞェクトを䜿甚せずに、回転ず移動の䞡方ですべおを手で行う必芁がありたす。 独自のゲヌムプレむ機胜がある堎合は、これに備えおください。



セグメントを盎接移動する必芁がある堎合は、セグメントを回転する必芁がありたす。 䞻な難点は、Unity物理゚ンゞンには「任意の点を䞭心にオブゞェクトを回転させる」メ゜ッドがないこずですTransformにはありたすが、誘惑されないでください。 「䞭心の呚りを回転する」だけです。 任意の軞を䞭心ずした回転は回転ず移動の䞡方であり、これらは2぀の異なる操䜜であるため、これは論理的です。 しかし、暡倣するこずができたす。 たず、セグメントをその軞の呚りに回転させ、次に「その軞」の座暙を平面の呚りに回転させたす。 飛行機が原点にあるずいう事実により、孊校のゞオメトリを芚えおりィキペディアに登る必芁さえありたせん。Unityにはすべおが揃っおいたす。 回転角をクォヌタニオンに倉換し、ポむントの座暙で乗算するだけで十分です。 ずころで、回転行列が䜿甚される前に、蚘事の執筆䞭にこの暩利に぀いお知りたした。



飛行機を壁に抌し蟌み、殺すこずを望んでいる敵がいたす。 飛行機を壁から抌しのけるシヌルドがあり、生き残るのに圹立ちたす。 これは簡単に実装されたす-各フレヌムが各セグメントの座暙に远加され、その埌砎棄される倉䜍ベクトルがありたす。 特別な方法で飛行機をキックしたい人は誰でも、キックのベクトルを残すこずができたす。これは、この倉䜍ベクトルに远加されたす。



最終的に、各フレヌムのセグメントの実際の座暙は、次のようにレベルのレベルコントロヌルセンタヌによっお蚈算されたす。

 Vector3 position = segment.CachedRigidbody.position; Vector3 deltaPos = Time.deltaTime * Vector3.left * settings.Speed; segment.truePosition = Quaternion.Euler( 0, 0, deltaAngle ) * ( position + deltaPos + movementOffset );
      
      





再生成䞭のセグメントの正確な結合に必芁なすべおの蚈算ず束葉杖の埌、segment.truePositionがセグメント゜リッドのMovePositionメ゜ッドに送信されたす。



結論



どのくらい速く動䜜したすか 叀いフラッグシップ-Nexus 5およびLG G2-ゲヌムは60 FPSで飛行し、セグメントの生成䞭に新しいコラむダヌを含める間、ほずんど目立たないドロヌダりンがありこれは避けられず、費甚はかかりたせん、ワヌムは地面から匕き出されたす地獄のようなもの、これを回避するために、しかし今、第䞉法の意図的な違反がありたす。 40の安定したFPSは、遭遇したゞャむロスコヌプを備えたデバむスを提䟛したす。 すべおの法埋の知識ず考慮なしでは、パフォヌマンスは、控えめに蚀っおも䞍十分で、電話は過熱しおいたした。 あたりにも倚くのこずで、私は2D物理孊のための気取らない専甚゚ンゞンを曞くこずを考えおいたした。 幞いなこずに、Unityの物理孊は十分に柔軟であるため、すべおの問題を回避しお独自のゲヌムを䜜成するこずができ、わずか数週間の実隓で十分でした。



Unity物理゚ンゞンの䞻な萜ずし穎をすべお知ったので、人類の3人の貧しい孊生の倢、人生、信仰を砎壊するこずで、ゲヌムのクロヌンをすばやく䜜成できたす。 この蚘事があなたの将来の時間を倧幅に節玄し、あなたのプロゞェクトの生産的物理孊の法則のそれほど明癜でない違反を芋぀けるのに圹立぀こずを願っおいたす。



シンプルで盎感的なツヌルを䜿甚しおいる堎合でも、ドキュメントず実隓を読んでください。



All Articles