Unityに関連する記事です

 以下の内容で順番に実装を進めていきます。

手順14 ー障害物を実装ー
25.Canvas内に障害物(穴)ゲームオブジェクトを設置する
26.障害物用スクリプトを親子クラスで作成する



 新しい学習内容は、以下の通りです。

・クラスの継承、オーバーライドメソッドの使い方



25.Canvas内に障害物(穴)ゲームオブジェクトを設置する

設計


 ビリヤードにおける、ポケット(穴)を障害物として用意します。
ここでは手球と障害物が接触した際に手球の数が1つ減り、手球アイコンもそれに合わせて1つ減るようにする処理を実装していきます。


障害物(穴)画像を取得してUnityへインポートする


 障害物用のフリー素材をネットで見つけてきてダウンロードしましょう。今回はビリヤードに準えて、穴の画像にしていただければいいと思います。

 ダウンロードしましたらUnityにインポートします。インポート場所もSpritesフォルダにします。


的球用のEnemyBallゲームオブジェクトを複製し、名前をObstacle_Holeに変える


 ヒエラルキーにあるEnemyBallゲームオブジェクトを選択して、右クリックしメニューを表示し、Duplicate を選択します。
ヒエラルキーにEnemyBallゲームオブジェクトの複製であるEnemyBall(1)ゲームオブジェクトが作成されます。

 名前を Obstacle_Hole に変更します。インスペクターを確認して設定を変更していきます。


ヒエラルキー画像



Obstacle_Hole ゲームオブジェクトの設定を変更する


 現在の位置は EnemyBall ゲームオブジェクトと同じ位置になっていますので、適宜な位置へ移動させてください。

 Image コンポーネントのSource Image をインポートした穴の画像に変更します。これで敵の画像から障害物の画像に切り替わりました。
RectTransformコンポーネントにて画像のサイズを調整します。そのままでも問題ありません。
もしも大きさを変更した場合には、それに合わせてCapsuleCollider2Dコンポーネントの大きさを確認し、適宜な大きさに調整してください。
 
 最後に EnemyBall スクリプトを Remove してください。


SceneビューとGameSceneビューでの画像



Obstacle_Hole ゲームオブジェクト インスペクター画像


インスペクター画像



インスペクター画像



インスペクター画像



 以上で Obstacle_Hole ゲームオブジェクトの作成は終了です。


26.障害物用スクリプトを親子クラスで作成する

設計


 障害物のゲームオブジェクトは、今後、数種類を用意する予定で考えています。
そのため、各障害物ごとに同じ内容のスクリプトを用意するのでは利便性が悪く、処理も冗長的になります。

 今回はクラスの継承を利用して、共通する変数やメソッドについては親クラスに、それ以外の各障害物固有の処理については子クラスに処理をまとめていく設計にします。

 親クラスは基底クラス(スーパークラス)、親クラスを継承した子クラスは派生クラス(サブクラス)と言います。
ここでは親、子、で名称を統一して使います。


親クラスに用意する処理
<変数>   攻撃力、各クラスへのアサイン(RectTransformコンポーネント、BattleManagerクラス)
<メソッド> Start、SetUpObstacle、OnCollisionEnter2D、BeforeTriggerEffect、AfterTriggerEffect
       (SetUpObstacleメソッド以外は virtual キーワードを付けて子クラスでオーバーライドできるようにする)

 子クラスでは上記の親クラスの変数と情報を自由に使えるようにするので、必要な処理だけを書くだけで済むようにします。


<クラスの継承>


 クラスには継承という機能があります。これは、他のクラスの機能を受け継いで新しいクラスを作成することを言います。

 Unityにおいて C# Script を新しく作成すると、MonoBehaviour というクラスを継承している状態で作成されます。
これは「MonoBehaviourクラスの機能を受け継いだ、新しいクラスを作成する」という処理になります。
MonoBehaviourクラスを継承していると、スクリプトをゲームオブジェクトにアタッチすることができたり、Startメソッドなどが利用できるようになります。

 今回は「MonoBehaviourクラスの機能を受け継いだ、ObstacleBaseクラス」を作成し、それを親クラスとします。
そして「ObstacleBaseクラスの機能を受け継いだ、Obstacle_Holeクラス」を作成し、それを子クラスとして、障害物用のゲームオブジェクトにアタッチします。
Obstacle_Holeクラス自体にはMonoBehaviourクラスはありませんが、親クラスであるObstacleBaseクラスが受け継いでいるため、その機能を利用することが出来ます。


ObstacleBaseクラス(親クラス)
MonoBehaviourクラスを継承


ObstacleBase_Holeクラス(子クラス)
ObstacleBaseクラスを継承 = MonoBehaviourクラスも一緒に継承


参考サイト
未確認飛行 C 様
[オブジェクト指向] 継承
https://ufcpp.net/study/csharp/oo_inherit.html


親クラスを作成する


 設計の部分でも説明がありましたが、親クラスには、すべての障害物に共通する処理をまとめて置くようにします。

親クラスの処理
<変数>   攻撃力、各クラスへのアサイン(RectTransformコンポーネント、BattleManagerクラス)
<メソッド> Start、SetUpObstacle、OnCollisionEnter2D、BeforeTriggerEffect、AfterTriggerEffect
       (SetUpObstacleメソッド以外は virtual キーワードを付けて子クラスでオーバーライドできるようにする)

 各メソッドの修飾子は protected を利用します。これは、親子クラス間でのみ参照を可能とする修飾子です。private よりも少し利用範囲が広いイメージです。
この修飾子を持つ変数やメソッドは親子の間で利用が可能になります。private修飾子や、public修飾子の扱いは同様です。

 また各メソッドには virtual(バーチャル) キーワードが追加されています。このキーワードを持つメソッドは、子クラスに同処理を記述した際に、処理の内容を変更してもよいことを表します。
この機能によって、親クラスで障害物全体の振る舞いを決定し、子クラスで各障害物ごとのふるまいを設定することが出来ます。

 このように同じクラスであっても処理の内容・振る舞いが変化することを多態性と言います。

 今回のスクリプトではコメントを省略しています。ここに、自分でコメントつけて処理を記述してみてください。
もしもコメントが記述できないようであれば、教材の以前の手順や、別のスクリプトを見直してみてください。


ObstacleBase.cs

 <= クリックすると開きます



子クラスを作成する


 続いて、親クラスであるObstacleBaseクラスを継承した子クラスを作成していきます。
ここでは必要な機能だけを記載するだけです。あとは親クラスのprotected修飾子や public修飾子の変数やメソッドをすべて利用することが出来ますので、変更しない処理の記述は不要です。
そのため非常に簡潔に処理をまとめることが出来ます。
 
 protected修飾子のメソッドについては、オーバーライド(上書き)処理を記述できます。これにより、障害物としてふるまいつつ、この障害物独自の処理が記述できます。
 
 今回の障害物はBeforeTriggerEffectメソッドのみをオーバーライドして処理を追加しています。
なおメソッド内の処理は次の手順で新しく追加するメソッドであるためそのままですとエラーが出ます。一度コメントアウトしておいてください。
(エラーがあるとゲームオブジェクトにアタッチできません)


Obstacle_Hole.cs

 <= クリックすると開きます



<オーバーライドメソッドの使い方>

virtualキーワードとoverrideキーワード

 virtual(バーチャル)キーワードを持つメソッドは親クラスにのみ設定できます。
このメソッドについては、子クラスに同じメソッドを記述した際に override(オーバーライド)キーワードを対として記述することで
親クラスのメソッドの内容を利用する際に、処理を追記したり、あるいはすべて上書きして書き換えることが出来ます。
オーバーライド処理ができるのは、virtualキーワードを持つメソッドのみです。

 今回は親クラスに用意しているメソッドには処理が何も書かれていませんでしたので、子クラスで、その内容を記述しています。


親クラスでの処理
  protected virtual void BeforeTriggerEffect(CharaBall charaBall) {

  }


子クラスでの処理
  protected override void BeforeTriggerEffect(CharaBall charaBall) {

      // 手球を1つ減らす
      charaBall.UpdateHp(-power);

      // スタート位置へ戻す
      StartCoroutine(gameManager.ResetCharaPosition(2.0f));
  }

参考サイト
.net column様
【C#の基礎】override修飾子でオーバーライドをする方法
https://www.fenet.jp/dotnet/column/language/1902/


障害物ゲームオブジェクトに Obstacle_Holeクラスをアタッチする


 親子関係にあるクラスは、子クラスをアタッチすることで親クラスの情報も扱えます。
そのため障害物のゲームオブジェクトには、ObstructBaseクラスではなく、Obstacle_Holeクラスをドラッグアンドドロップしてアタッチします。
親クラスはアタッチ不要です。

 アサイン情報には親と子の両方の持つ情報が表示されます。
子クラスには power 変数はないはずですが、親クラスが public 変数として宣言しているので、インスペクターに表示されています。

 power 変数には 1 を登録してください。障害物と手球が接触した際、この数値分だけ、残りの手球数を減少させます。
BattleManager 変数には、ヒエラルキーにあるBattleManagerゲームオブジェクトをドラッグアンドドロップしてアサインします。


Obstacle_Holeアタッチ後の Obstacle_Holeゲームオブジェクト インスペクター画像



 以上でこの手順は終了です。次の手順で手球のスクリプトを修正し、障害物と接触した際の処理を追記します。

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Menu



技術/知識(実装例)

2Dおはじきゲーム(発展編)

2D強制横スクロールアクション(発展編)

3Dダイビングアクション(発展編)

2Dタップシューティング(拡張編)

レースゲーム(抜粋)

2D放置ゲーム(発展編)

3Dレールガンシューティング(応用編)

3D脱出ゲーム(抜粋)

2Dリアルタイムストラテジー

2Dトップビューアドベンチャー(宴アセット使用)

3Dタップアクション(NavMeshAgent 使用)

2Dトップビューアクション(カエルの為に〜、ボコスカウォーズ風)

VideoPlayer イベント連動の実装例

VideoPlayer リスト内からムービー再生の実装例(発展)

AR 画像付きオブジェクト生成の実装例

AR リスト内から生成の実装例(発展)

private



このサイト内の作品はユニティちゃんライセンス条項の元に提供されています。

管理人/副管理人のみ編集できます