ぱふの自由帳

ぱふの技術ブログ。メインはUnity。最近はUnity1Weekの放送してます。良ければフォローお願いします、、

Prefab変更したのにPrefabから生成したオブジェクトが変更されない件

はじめに

「Prefabを変更することで一括で値を変えて…っと。あれ?反映されない…(´・ω・`)」という実話を元に作成しました(笑
理解してしまえば当たり前のことだったので、内容は入門者向けです。

注意:D&Dという用語を多用しますが、ドラッグ&ドロップのつもりです

メイン

現象説明

冒頭だけではいまいちどういう話をしているか分からないと思うので、簡単に説明します。

  1. Prefabを元にD&DでオブジェクトAを生成
  2. オブジェクトAをもぞもぞ弄る
  3. オブジェクトAをコピーしてオブジェクトB~Zを作成
  4. オブジェクトA~Zの値を一括変更したいのでPrefabを変更
  5. 「あれ。値変わらないんだけど」

という感じの現象です。2のもぞもぞ弄る際にどれだけもぞもぞ弄るかで結果が変わってきます。

Let's確認

文字よりも実際に画像で見た方がわかりやすと思うので画像を交えて説明します。

BoxというPrefabを用意しました。BoxのTransformは以下の図のようになっています。

f:id:PafuOfDuck:20170908204705p:plain

例1

D&Dでもして、このBoxを元に適当な場所にAという(インスタンス)オブジェクトを生成します。AのTransformは以下の図のようになっています。

f:id:PafuOfDuck:20170908205135p:plain

AからコピーであるBを作成しました。BのTransformは以下の図のようになっています。

f:id:PafuOfDuck:20170908205154p:plain

実際のオブジェクトを見ると下図のように見えます。

f:id:PafuOfDuck:20170908205426p:plain

ここでPrefabのPositionとRotation、Scaleを変更するとどうなると思いますか?
実は変更されるのはScaleのみなのです。

〈適当に弄った後の図〉 f:id:PafuOfDuck:20170908205826p:plain

ここで、一つ知識の紹介です。
《Prefabの値から一度でも修正した値はPrefabを変更しても自動で適用されない》
当たり前と言えば当たり前ですね。Prefabに従い続けるのであれば位置の修正も出来ませんよね。というわけで、D&Dした瞬間に修正されるPositionは変更が適用されなかったのです。
逆に修正を加えていないScaleは変更が適用されました。

あれ?Rotationは?と思った方。そうです。
《RotationもD&Dの際に修正されたものとして扱われる》
これ知らなかった方もいるんじゃないでしょうか?(私のように..orz

例2

例1と同様にD&Dでもして、Boxを元に適当な場所にAという(インスタンス)オブジェクトを生成します。そして、Scaleを弄ります。AのTransformは以下の図のようになっています。

f:id:PafuOfDuck:20170908211106p:plain

Scaleを弄った後のAからコピーであるBを作成しました。
実際のオブジェクトを見ると下図のように見えます。

f:id:PafuOfDuck:20170908211048p:plain

ここでPrefabのScaleを変更するとどうなると思いますか?AはScaleを修正してしまっているので変更は適用されませんよね?Bはどうでしょうか?
以下の図で見てみましょう。

f:id:PafuOfDuck:20170908211852p:plain

はい。何も変わりませんね。そもそも変更前、PrefabのScaleが(1, 1, 1)だったのにBは(1, 0.1, 1)というように既に修正された値になってます。なので、変更はAと同じく適用されません。

まとめる

例1&2から分かったことは以下の事柄です!

  • Prefabの値から一度でも修正した値はPrefabを変更しても自動で適用されない
  • RotationはD&Dで生成の際に(値が同じでも)値を修正したものとして扱われる
  • そもそもPositionとRotationは常にPrefabから変更できない
  • 値を修正したオブジェクトから複製されるオブジェクトも値を修正したオブジェクトとして扱われる
  • よく見ると、修正した値の変数名が太字になっている

例1&2では挙げていませんが、Inspectorで設定したpublic変数の値も同様の扱いを受けるので気にかけておきましょう。

解決方法は?

私が考えているのは"オブジェクトからオブジェクトを複製する前に必ずApply押そうね!じゃないとPrefabで一括変更しようとした時に痛い目見るよ!”というぐらいです。Apply押せばPrefabが更新されるので基本的にうまくいくはずです…きっと…。
他に良い方法があれば是非教えてください。

おしまい

長くてすいません。私も長い文章書くの面倒なので分かりやすいサイトになるようにもっと簡単に説明できるようになりたいものです。

なお、「こういう手軽な方法があるよ」や「間違ったこと書いているよ」等ありましたらコメントやtwitterのDMで教えて下さると助かります( ´ ▽ ` )

初心者の方や熟練者の方を問わずTwitterのフォローお待ちしています…(`・ω・´) ヨロシク!