Unity は、サポートされているプラットフォームとデバイスの長いリストを備えた、非常に人気のある多用途のゲーム エンジンです。Unity について考えるとき、おそらく 3D ゲームが最初に思い浮かぶでしょう。このエンジンはかつて Unity 3D と呼ばれていたこともあります。ただし、ほとんどのモバイル、コンソール、デスクトップ ゲームは 2D で表現されるため、2D ゲームを構築するために Unity が提供する機能を理解することが重要です。
このチュートリアルでは、2D スペース ランダー ゲームを構築し、その過程で次のスキルを学びます。
- スプライトとカメラの使い方。
- _物理 2D_ コンポーネントと、衝突とゲームプレイの処理方法についてのすべて。
- 2D アニメーションと状態を設定する方法。
- レイヤーとスプライトの順序が 2D ゲームに与える影響。
このチュートリアルのマテリアルは Unity バージョン 2020.3 で構築されました。
【上記の続き】【Unity】2D空間ログインゲーム開発入門チュートリアル(前編)
2D コライダーと物理学
Unity を使用すると、2D ゲームと同じように物理的な 3D システムの重力を調整できます。新しいプロジェクトに対する Unity のデフォルトの重力設定は地球の重力と同じで、定義上、9.80665 m/s2 です。しかし、宇宙船を地球ではなく月に着陸させると、月の重力は地球の約 16.6%、つまり 1.62519 メートル/秒になります2。
注: 初心者向けプロジェクトの重力は、簡単に飛行してすぐにゲームをテストできるように-1に設定されています。
ゲームの重力を変更するには、[編集] ▸ [プロジェクト設定] をクリックし、[物理 2D] タブを選択し、[物理 2D] パネルを使用して重力の Y 値を -1 から -1.62519 に変更します。
事態はいよいよ重くなってきます!
「開始」をクリックしてゲームを実行し、飛び回って重力によって宇宙船の動きがどのように変化するかを確認してください。
重力については小さな一歩ですが、推進力については大きな飛躍が必要です。
物体との衝突
着陸船で現場を航行しようとしたことがあるなら、おそらく岩の 1 つや 2 つにぶつかったことがあるでしょう。これは Unity の 2D コリジョン システムです。
重力や他の物理オブジェクトと相互作用するすべてのオブジェクトには、Collider 2D コンポーネントとRigidbody 2Dコンポーネントが必要です。
階層内の _lander_ ゲーム オブジェクトを選択します。
Rigidbody 2D コンポーネントと Polygon Collider 2D コンポーネントがアタッチされていることがわかります。Rigidbody 2D コンポーネントをスプライトに追加して、Unity の 2D 物理システムによって制御されるようにします。
物理コンポーネントのクイックコース
Rigidbody 2Dコンポーネント自体は、それが接続されているゲーム オブジェクトに重力が影響することを意味します。また、エンティティに力を適用する Physics2D 関連のメソッドを使用して、スクリプトからエンティティを制御することもできます。
ただし、スプライトを他のオブジェクトと相互作用させ、衝突させたい場合は、Collider2D コンポーネントも必要になります。適切な Collider コンポーネントを追加すると、スプライトが他のスプライトとの衝突に応答できるようになります。
ポリゴン 2Dコライダーは、ボックスやサークル コライダー 2D コンポーネントなどの他の単純なコライダーよりもパフォーマンスが優れていますが、オブジェクト間のより正確な物理的相互作用が可能になります。最高のパフォーマンスを確保するには、ゲーム内で使用できる最も単純なコライダー シェイプを常に使用してください。
衝突面
階層内で Lander ゲーム オブジェクトを選択し、ポリゴン 2D コライダーで [コライダーの編集] をクリックして、宇宙船上のコライダーを探索します。
シーン ビューのコライダーのエッジの上にマウス カーソルを置きます。ハンドルを使用すると、コライダー ポイントを移動できます。また、ポイントを作成または削除してコライダーの形状を変更することもできます。
現時点では、_lander_collider の形状を変更しないでください。
注: Landerゲーム オブジェクトにアタッチされているLander.csスクリプト内のコードは、ゲーム シーン内の他のオブジェクトとの衝突を処理するために使用されます。衝突力の大きさが一定の閾値を超えると、着陸船は破壊されてしまいます。OnCollisionEnter2D
着陸パッドにも衝突装置が必要です。衝突装置がなければ、着陸しようとしたときに船が落ちてしまいます。
階層内で、LanderObjectiveゲーム オブジェクトをダブルクリックして、ランディング パッドにフォーカスします。インスペクターを使用して、「コンポーネントの追加」をクリックし、Box Collider 2D コンポーネントを選択します。
Unity は、_Box Collider 2D_ コンポーネントをLanderObjectiveゲーム オブジェクトに追加し、スプライト サイズに合わせてコライダーのサイズを自動的に変更します。
寒い!
他のこと
リジッドボディおよび 2D コライダー コンポーネントについては、他にも覚えておくべきことがいくつかあります。
- 物理エンティティを単に重力に影響させるのではなく、トランスフォーム コンポーネントを通じて物理エンティティを移動させたい場合は、Kinematic Body タイプを使用するように Rigidbody を変更します。Unity の重力の制御下に置くには、ダイナミクスを使用します。まったく動かない場合は、静止させます。
- 剛体コンポーネントの質量、線形抗力、角度抗力、その他の物理的プロパティを変更することもできます。
- コライダーはトリガー モードで使用でき、他の物理オブジェクトと物理的に衝突しません。代わりに、MonoBehavior スクリプトで提供されるすべてのメソッドを使用してコードがイベントに反応できるようにします。
OnTriggerEnter2D
- スクリプト コードで競合するイベントを処理するには、 を使用します。これはすべてのMonoBehaviorスクリプトで使用できます。
OnCollisionEnter2D
- オプションのPhysics2D マテリアル 2D参照をコライダーに割り当てて、弾力性や摩擦などのプロパティを制御できます。
注: ゲーム内にオブジェクトが数個しかない場合は気付かないかもしれませんが、画面上に数百のオブジェクトがあり、そのすべてが物理的な相互作用を伴う場合は、より単純なコライダー シェイプを使用するとゲームのパフォーマンスが向上します。
多数のオブジェクトが衝突している場合は、Polygon Collider 2D コンポーネントの使用戦略を再考した方がよいでしょう。
ランダーアニメーション
重力に対抗するための目に見えるスラスターがなければ、着陸船は完成しません。現在、スラスターは作動していますが、噴射していることを知らせる視覚的なフィードバックはありません。
Unity アニメーション 101
シーン内のゲーム オブジェクトにアニメーションを割り当てるには、アニメーション化するゲーム オブジェクトにアニメーター コンポーネントをアタッチします。このコンポーネントには、アニメーション コントローラへの参照が必要です。アニメーション コントローラは、使用するアニメーション クリップとそれらのクリップの制御方法、およびアニメーション ブレンドやトランジションなどのその他の「より高度な」エフェクトを定義します。
スラスター用アニメーションコントローラー
階層内で Lander ゲーム オブジェクトを展開すると、ネストされた他の 4 つのゲーム オブジェクトが表示されます。ThrusterMaster ゲームオブジェクトを選択すると、アニメーター コンポーネントがアタッチされていることがわかりますが、AnimationController への参照はありません。
Thruster Master ゲーム オブジェクトが選択された状態で、[Animation Editor] タブをクリックします。エディターのメイン ウィンドウにこのタブが表示されない場合は、[ウィンドウ] ▸ [アニメーション] ▸ [アニメーション]を選択して開きます。
階層内のゲーム オブジェクトを選択すると (実際に選択します!)、インスペクターがそのゲーム オブジェクトに関連するコンポーネントを表示するのと同じように、アニメーション ウィンドウにそのゲーム オブジェクトに関連するアニメーションが表示されます。_Create をクリックして、ThrusterMainの_animation クリップを作成します。
ThrusterAnimという名前を入力し、「Resources/Animations」フォルダーに配置します。
[プロジェクト] ウィンドウのアニメーション フォルダーに 2 つの新しいアニメーション アセットが表示されます。ThrusterAnimはスラスター エフェクトのアニメーションを保持するアニメーション クリップで、ThrusterMainはアニメーションを制御するアニメーター コントローラーです。
アニメーション ウィンドウにアニメーション タイムラインが表示され、ここで個々のスラスター スプライト フレームを配置および順序付けることができます。
[属性の追加] をクリックし、アニメーション化する属性タイプとして [スプライト レンダラー/スプライト] を選択します。
エディタは次のようになっているはずです。
タイムラインの処理時間
処理タイムライン
プロジェクト ウィンドウで、Sprite フォルダーをクリックし、_thruster-spritesheet.png_sprites を展開します。スライスされた 4 つのスラスター スプライトをハイライト表示し、アニメーション エディターのスラスター マスター:スプライト タイムラインにドラッグします。
スプライト フレームがタイムライン上で集まってしまいますが、これは自分で修正できます。右端のスプライトから開始します。スプライトをクリックして右にドラッグし、隣接するスプライトから約 0:05 の間隔をあけます。
最後のフレームの1:00マークを選択し、Delete キーを押して削除します。
アニメーション ウィンドウで [プレビュー] をクリックし、[再生] をクリックします。シーン ビューで着陸船に注目して、作業のプレビューを確認してください。
キャプテンの準備は完了です!
ThrusterMain が選択されたままの状態では、sprite_renderer_component でスプライトの変更も確認できます。
カチカチ音:]
次に、アニメーション コントローラーを構成します。
アニメーションコントローラーを設定する
_lander.cs_ スクリプトは現在、プレイヤーがスラスターを発射するかどうかに応じて、アニメーション パラメーターを または に設定します。アニメーション コントローラーはこれらのパラメーターを評価し、特定の状態の開始または終了を許可します。true``false
プロジェクト ウィンドウで、Animation サブフォルダーをクリックします。次に、ThrusterMain.controller をダブルクリックします。これにより、アニメーション エディターが開き、スラスター メイン ゲーム オブジェクトでアニメーション クリップを作成したときに追加されたコントローラー Unity が表示されます。
スラスターのアニメーションが継続的に実行されるようになりました。論理的には、スラスター アニメーションは、プレイヤーが現在スラスターを発射しているときにのみ実行されるべきです。
アニメーション エディターのグリッド領域を右クリックし、[状態/空の作成] をクリックします。
インスペクターを使用して、新しいステートにNoThrustという名前を付けます。これは、プレーヤー入力がない場合のアニメーションのデフォルトの状態です。
Entryから開始して、アニメーターは直接NoThrustに流れ、ブール引数が変更されるまでそこに留まる必要があります。アニメーション状態の変化を発生させるには、接続を使用してトランジションを追加する必要があります。true
[なし推力]を右クリックし、[レイヤーのデフォルト状態として設定]をクリックします。以下に示すように、 NoThrustがオレンジ色で表示され、Entryの矢印がNo Thrustを指しているはずです。
オレンジは、最初に実行されるステートであることを示します。
アニメーション エディターを使用して、 [パラメーター] タブの[+]をクリックして、新しいパラメーター タイプBoolを作成します。_Apply Thrust_ という名前を付けます。
[NoThrust]を右クリックし、[トランジションの作成]をクリックして、[スラスター アニメーション]をクリックします。これにより、2 つの状態の間で状態を変更できる遷移が作成されます。次に、同じ一連の手順を実行しますが、今回はThrusterAnimからNoThrustへの遷移を作成します。
NoThruster から ThrusterAnim への遷移線をクリックし、インスペクターで+をクリックして条件を追加します。これにより、使用可能な唯一の条件、つまり推力の適用が選択されます。
ドロップダウン リストでtrueが選択されていることを確認します。これは、アニメーションがスラスター アニメーション状態に移行するには、「Apply Thrust」が true でなければならないことを意味します。
次に、 ThrusterAnimからNoThrustへの遷移ラインを編集して、同じapplyingThrust条件を使用します。ただし、今回は _error_ 状態をチェックしています。
アニメーション エディターでアニメーションの再生速度を調整できます。Thruster アニメーションの状態をクリックし、インスペクターでSpeedプロパティを1.5に変更します。
スラスター アニメーションは、プレイヤーのトリガー反応を反映して応答を示すために迅速に応答する必要があります。両方のトランジション ライン ( NoThrustとThrusterAnimの間の線) をクリックし、インスペクターを使用してトランジションに関連する設定を0に変更します。チェックを外すと、終了時間と固定期間も設定されます。
最後に、同じアニメーションとコントローラーを左右のスラスターに適用します。階層からThrusterLeftとThrusterRightを選択し、プロジェクト ウィンドウのアニメーション フォルダーからThrusterMain.controllerを Animator コンポーネントのコントローラー プロパティにドラッグ アンド ドロップします。
[スタート] をクリックしてゲームを実行し、_WASD_ または _矢印キー_ を使用して新しいスラスターを試してください。
ヒューストン、空挺中です!:]
スプライトの並べ替えとレイヤー
スプライトの並べ替え機能がなければ、2D エンジンは完成しません。Unity では、レイヤーとレイヤーソートシステムを使用してスプライトを並べ替えることができます。
エディタで [Play] をクリックしてゲームを再度実行し、最悪の運転能力を使って着陸船を近くの岩に衝突させます。[再起動] ボタンが表示されたら、エディターのシーン ビューを確認します。いくつかの岩が背景画像の後ろに隠れていることに気づくかもしれません。
スターター プロジェクトを開いていて、背景画像しか表示されていない可能性もあります。そうであれば、よくやった!
これは、レンダリング エンジンがスプライトの階層化順序を決定できないために発生します。船を除くすべてのスプライトは現在、レンダリング順序が -1 のデフォルトの並べ替えレイヤーを使用するように設定されています。グラフィックス カードはすべての描画呼び出しを受け取りますが、描画する順序は伝えません。
この問題を解決するには、レイヤーおよびレイヤー順序システムを使用してスプライトを分離します。Unity は、定義されたレイヤー順序でこれらのレイヤーにスプライトをレンダリングします。Unity は、個々のレイヤーごとに、レイヤー内の各スプライトのスプライトの順序番号を使用して、各スプライトをレンダリングする順序を決定します。
これは順序付きリストと考えることができます。
-
A层
- シーケンス0
- シーケンス 1
-
B階
レイヤーを追加します
[編集] ▸ [プロジェクト設定] をクリックし、[タグとレイヤー] を選択します。「ソートレイヤー」セクションを展開します。
+をクリックして3 つの新しいレイヤーを追加します。
- 背景
- 岩
- プレーヤー
各レイヤーの横にあるハンドルをクリックしてドラッグし、上記の順序になっていることを確認します。ここでのレイヤーの順序によって、Unity がこれらのレイヤーにスプライトをレンダリングする順序が決まります。
タマネギと同じように、空間は層で構成されています。
階層内で [背景] をクリックし、スプライト レンダラー コンポーネントで [レイヤーの並べ替え] ドロップダウン リストをクリックし、リストから [背景] を選択します。
岩はまだ _Default_ レイヤー上にあるため、岩は間違いなく背景の後ろにあります。
ロック ゲーム オブジェクトを展開し、すべての child_rock_game オブジェクトを強調表示します。以下に示すように、インスペクターを使用してオブジェクトを use_rock_sorted レイヤーに変更します。
シーン内の岩は互いに重なり合う傾向があるため、特定のレイヤー上のスプライトに対して「レイヤー内の順序」プロパティがどのように機能するかを示すのに役立ちます。
岩層の各 _rock_ に個別の並べ替え値を指定しない場合、ゲーム中に他の岩がランダムに「ポップアップ」することに気づくでしょう。これは、Unity が現在レイヤー内にあるのと同じ順序で岩を一貫してレンダリングしないためです。
重なっている岩を見つけて、その前の岩にその後ろの岩よりも高い層順序値を割り当てます。
階層内のLanderをクリックし、そのスプライト レンダラーとそのすべての子ゲーム オブジェクト sprite_sprite_renderer_components の並べ替えレイヤー プロパティを _player__sort_layer_ に変更します。
階層内の Pickup の下にある Fuel ゲーム オブジェクトに対しても同じことを行います。これにより、他のものよりも先にレンダリングされるようになります。
微調整レイヤー
ただし、問題があります。スラスター アニメーション (および通常は着陸船の後ろに隠れている着陸船の足) のスプライトはどうなるでしょうか? これらと着陸船自体に特定のレイヤー番号の順序を設定しないと、レンダリングに奇妙な問題が発生することになります。
Lander 自体の Layer Order プロパティを2に変更します。各 Thrusters 子ゲーム オブジェクトとLanderFeetゲーム オブジェクトを選択し、その Layer_Order_value を1に設定します。
着陸船が着陸パッドに着地すると、着陸パッドが少し沈み、着陸したことを示します。ランディング パッドと岩のスプライトは互いに重なり合っているため、効果を正しく表示するには、ランディング パッドを岩の後ろに配置する必要があります。
LanderObjectiveスプライトを変更してROCK_LAYER を使用し、それに LAYER_ORDER_value 0を割り当てます。Layer Scale 値1を使用するように、Landing Site Objective の下に岩を設定します。
最後に、Prefabs フォルダー内の Exploded Prefab をクリックし、そのソート レイヤーをプレーヤーに変更します。
冷静な人は爆発なんて見ません。しかし、私たちはやり遂げました!
[_Play_] をクリックして、燃料供給源を手に取り、着陸パッドに着陸して操縦スキルをテストします。岩を避けないよう、どちらの方向にも強く押しすぎないように注意してください。
ばっちり成功!:]
十分に練習すれば、スペース X と同じくらい上手にロケットを着陸できるようになります。:]
完结!!!
【Unity】2D空間ログインゲーム開発入門チュートリアル(前編)