Unityに関連する記事です

 プレハブは便利な機能ですが、アセットとして扱われるため、シーン内の情報(ヒエラルキーにあるゲームオブジェクトの情報)を事前に保持できません。
そのため、プレハブやバリアントのプレハブを活用してゲームオブジェクトを動的に生成すると、シーン内にある情報とは、一切紐付けがない状態で生成されます。

 ここでは、効率的なオブジェクトの連携方法を学びましょう。



1.オブジェクト間の効率的な情報共有


 オブジェクトを生成する際に、生成元から必要な情報を引数として渡すことで、オブジェクト同士の情報共有が可能になります。

 それを踏まえて、Untiy の構造自体がどのようになっているか、順番に見直してみましょう。


1.MonoBehaviour クラスの Start メソッドとコンストラクタメソッドの違い


 Unity のスクリプトはゲームオブジェクトにアタッチできるように MonoBehaviour クラスを継承しています。
MonoBehaviour クラスを利用する場合、コンストラクタメソッドを利用することが出来ず、
変わりに Start メソッドを使ってゲームオブジェクトの初期設定を行う設計です。

 大変便利な機能ではありますが、Start メソッドにはコンストラクタメソッドと違って引数がありません
そのため、インスタンス化時に外部クラスからの情報を受け取る手段がない状態です。

 よって、Instantiate メソッドを利用してゲームオブジェクトをインスタンス化した際、
Start メソッドには引数がありませんので、生成元から外部のクラスの情報を受け取ることが出来ません。


2.シーン内のオブジェクトの取得


 インスタンス化されたオブジェクトが、シーン内の他のオブジェクトと連携する必要がある場合、GameObject.Findを使用することが考えられます。
しかし、GameObject.Findはオブジェクトの名前で検索を行うため、オブジェクト名の変更に対応しづらく、効率が悪いと言えます。
名称が一文字でも間違っていれば検索できませんし、大文字小文字も区別されます。
ヒエラルキーにあるゲームオブジェクトを子オブジェクトに至るまで走査するため、ゲームオブジェクトの数が増えるほど処理が重くなります。

 便利なメソッドではありますが、それを上回るデメリットがありますので、この方法はおすすめできないアプローチです。


3.メソッドの引数を利用した情報共有


 結論として、最初にも提示しているように、インスタンス化時に引数を使って情報を渡すことで、オブジェクト同士がシーン内の情報を知ることができます。
インスタンス化したオブジェクトは、引数で受け取った情報を利用して他のオブジェクトと連携することができます。

 ただし、Start メソッドでは対処が出来ず、GameObject.Find メソッドのように重い処理を使うことは避けるべきです。

 生成のタイミングで外部のクラスの情報を受け取れるように、コンストラクタメソッドのような役割を持つ、
必要となる情報の受け渡しをするための引数を持つメソッド新しく定義して使う必要があります。



 メソッドの引数を使うことで、インスタンス化されたオブジェクト同士の情報共有が可能になり、GameObject.Findのような煩雑な処理を回避できます。
引数を使ってシーン内の情報を効率的に取得し、オブジェクト間の連携をスムーズに行いましょう。

 初心者の方も、この手法を利用してより効果的なプログラムを実現できるようになります。


2.サンプルコード


 GameManagerが複数のGroupManagerを生成し、各GroupManagerがグループごとに異なる動作をする例を示します。

 各GroupManagerが引数として受け取ったグループ名を使って特定の動作を行うことで、シーン内の情報を効率的に共有します。


1.ChildManager スクリプトを作成する


 新しく ChildManager スクリプトを作成します。
このスクリプトは、バリアントのプレハブ内にある、シーン内の情報を受け取りたいゲームオブジェクトにアタッチして利用します。


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


 SetUpChild メソッドの引数を通じて、外部のクラスから情報を受け取ることで
シーン内の他のゲームオブジェクトのクラスとの連携を行えるようにします。


2.GroupManager スクリプトを修正する


 新しくメソッドを作成し、GameManager でインスタンスされた際に情報を受け取れるようにします。

 ここで受け取りたい情報は2種類あり、1つは、このGroupManager で利用したいシーンの情報、
もう1つは、ChildManager に渡したいシーンの情報です。

 適宜な引数を設定して、必要な情報を受け取れるようにしましょう。


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



3.GameManager スクリプトを修正する


 一番のスタート地点となる処理になります。
ここで GroupManager をインスタンスする部分は変わりませんが、
インスタンスのタイミングに合わせて、GroupManager の SetUpGroup メソッドを実行し、
GameManager 内にある情報、あるいは GameManager 自体の情報を引数を通じて渡します。


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


 この例では、メソッドの引数を通じて、GameManager 自身の情報を GroupManager に渡しています。


3.まとめ


 Unityでは、プレハブを使ってゲームオブジェクトを効果的に管理し、
動的にインスタンス化することで、シーンの容量を削減し、パフォーマンスを向上させることができます。

 グループ化とプレハブ化の手順、動的なインスタンス化の方法を理解し、効率的な処理の重要性を把握することで、
プロジェクトの管理はわかりやすくなり、ユーザーには、よりスムーズなゲームプレイ体験を実現できるでしょう。

 最後に利点と考慮すべき点とをまとめておきます。

<利点>
1.シーン容量の削減:
    プレハブとしてオブジェクトを管理することで、シーン内の重複する要素を減らすことができ、シーンの容量を削減できます。これにより、読み込み時間やメモリ使用量が軽減されます。

2.メンテナンスの容易化:
    関連するオブジェクトをグループ化することで、プロジェクトのメンテナンスが容易になります。各グループを個別に管理でき、再利用しやすくなります。

3.柔軟性と拡張性:
    専用のクラスを使ってオブジェクトを生成するアプローチは、柔軟性があり、コードをより効果的に組織化できます。
    クラスに専用のメソッドを備えることで、特定のグループに固有の振る舞いを追加することも可能です。

<考慮すべき点>
1.パフォーマンス:
    動的にオブジェクトを生成する手法は、ゲームのパフォーマンスに影響を与える可能性があります。
    オブジェクトの生成や削除は、フレームレートに悪影響を及ぼすことがあるので、注意が必要です。
    Object Poolingなどのテクニックを使用して、オブジェクトの再利用を検討することが重要です。

2.シーン構造:
    適切なグループ化とプレハブ化を行うことで、シーン内の階層構造が複雑化する可能性があります。
    シーン内のオブジェクト階層を適切に管理することで、後々のメンテナンスがスムーズになります。

 以上になります。

 これらのアプローチは一般的に良い実践とされており、効率的でメンテナンス性の高いコードを作成することが期待されます。
ただし、パフォーマンスとシーン構造に対する注意を忘れずに行い、必要に応じて最適化を行うことが重要です。

 様々な要因を考えて、その都度、適切な対処方法を実行するためにも、より深い知識を養っていくことをお勧めします。

コメントをかく


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

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

Menu



技術/知識(実装例)

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

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

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

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

レースゲーム(抜粋)

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

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

3D脱出ゲーム(抜粋)

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

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

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

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

VideoPlayer イベント連動の実装例

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

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

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

private



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

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