こんにちは、Unityエンジニアのオオバです。
Transformとはオブジェクトの「移動」「回転」「大きさ」を管理するUnityの基本となるコンポーネント。
もう1つの側面が 階層化 です。
Transformは階層をいくつも作ることができ、オブジェクト配置するときに役立ちます。
階層化で重要になるのは親子同士Transformの取得方法です。
そのためにTransformにはいくつか取得メソッドが用意されています。
本記事ではFindメソッドについて解説します。
タイトルの通り、オオバの考えは Findメソッドの使用は禁止 です。
開発におけるリスクが高い のが理由です。
詳しくは以降の章で解説しています。ぜひ最後まで読んでみてください。
TransformのFindは基本使用禁止
結論から言うと、 TransformのFindメソッドは使用しないほうが安全 です。
簡単にまとめるとこんな感じです。
①仕様変更に弱い
②プログラムの理解に時間がかかる
まさにこの2点。
詳しく解説していきます。
👉DOTweenの教科書を読んでUnityアニメーションをプログラミングしてみよう!
TransformのFindとは?
使用禁止の話の前にTransformのFindについて解説します。
Findとは簡単に自分の子階層を取得できるメソッドです。
使い方は簡単。 A/B/C
というパスを指定するだけ。
例えば下記の構造のTransformを取得してみましょう。
ルート階層の
FindTransform
に取得スクリプトをセットしています。 こちらがスクリプトの抜粋です。
Findメソッド の引数を色々と変えてみました。
// 取得成功 → ○1階層下の子供は名前直指定でOK
var tr0 = transform.Find("Parent");
// 取得成功 → ○パスが適正
var tr1 = transform.Find("Parent/Child");
// 取得失敗 → ×パスが不正
var tr2 = transform.Find("Child/Grandchild");
// 取得失敗 → ×名前直指定
var tr3 = transform.Find("Grandchild");
結果は、ソースコードのコメントにに記載しています。
子オブジェクトを取得するためには、
Transformのパスを正確に指定する必要がある 点に注意してください。
昔はFindChildというメソッドがありました。
しかし、現在は非推奨メソッドとなっております。
いずれ削除されるので早々にFindメソッドに置き換えましょう。
TransformのFindは使わないほうがいい
早速Transformを使ってはいけない理由について解説します。
Transformクラスの Findメソッド
自体は簡単に使えて、ちょっと便利だなって思いましたよね。
しかし以下の理由から 実際のゲーム開発の現場では使えません 。
①仕様変更にもろい
②プログラムの理解に時間がかかる
Findメソッドの問題点① 仕様変更にもろい
あなたは新規のゲーム開発をしていたとします。
開発中のゲームのデザインってコロコロ変わりますよね。
いわゆる 仕様変更 です。
それによって何が起きるかというと、
GameObjectの階層もコロコロ変わってしまう ということです。
つまりTransformのFindメソッドを使用すると、
GameObjectの階層が変わるたびにソースコードも変えないといけない のです。
数カ所なら良いですが、デザインの影響はゲーム全体です。
デザイン修正のたびに、Transformの参照取得のためだけのソースコードを変更。
非常に時間の無駄 なのです。
Findメソッドの問題点② プログラムの理解に時間がかかる
Findメソッドのパス指定にはもう1つのデメリットがあります。
それは、 プログラムの内容理解に時間がかかってしまうこと です。
どういうことかというと、Findで指定されたパスを読み解くために、
Unityエディタとソースコードを何度も行ったり来たりする必要がある のです。
この両者の行き来の回数は少なければ少ない方が良いのですが、
パス指定によって回数が「爆増」するわけですね。
結果的に内容を理解するために 膨大な時間 を要してしまうのです。
【解決方法】事前のシリアライズ
以上2つの理由からTransformのFindメソッドは使用禁止にしています。
解決方法は事前のシリアライズです。
すなわち、最初から参照関係を保持した状態にしておくということです。
[SerializeField] private Transform _grandChild;
このように _grandChild
を定義。
そして事前にオブジェクトをセットしておきます。
すると、 GameObjectの階層が変わったとしても参照が外れない のです。
パス指定よりよっぽど簡単ですよね。
シリアライズしたオブジェクトは「ピン」ですぐに発見
シリアライズしたインスペクタを クリック してみてください。
するとこのようにどのGameObjectをセットしているのか示してくれます。
これがとっても便利なんです。
ピン によって一発でオブジェクトを検索できるので、
パス指定方法と比べるとはるかにプログラムの理解は早くなります。
ぜひFindを使っている箇所は上記の解決方法を使ってみてください。
Transformには子階層のオブジェクトを取得する機能のほか、移動や回転といった重要な機能を持っています。
ゲーム開発ではTransformの知識は必須 ということですね。
ところで、Transformを網羅的に分かりやすく解説記事を書きました。
ぜひ復習がてら読んでみてください。あなたの知らない機能が登場するかもしれません。
まとめ
TransformのFindメソッドについて解説してきました。
①FindはTransformの子階層を取得するメソッド
②実際の現場ではFindは使用禁止
③禁止理由1. 仕様変更に弱いため
④禁止理由2. プログラムの理解に無駄に時間がかかるため
最終的に Findはおすすめできないメソッド です。
例外があるとすると、キャラクターの骨構造の中の1つを取得したいといったケースです。
キャラクタの手に何かを持たせたい、だからその手の骨のTransformを取得したい。
そんな感じです。ただ、それも手の部分にスクリプトをセットしたほうが、安全な気もします。
普通に使用する上ではあまり登場することはないメソッドであることは間違いない。
もし、チーム開発でFindを見かけた際は注意。
何かしら意図があるならOKですが、
ただたんに使っているケースであれば 要注意 だということです。
この記事があなたのUnity開発に役立つと嬉しいです。
この記事が気に入ったらフォローしよう
- Unity2020.3.20f1