Unityでインディゲームを作る!

Unityでのゲーム制作を目指し、それに関わる話題についてのブログ

UnityにおけるWorld TransformとLocal Transformについて。Transformコンポーネントの見えない変化に注意しよう!

Unity_LocalTransform

 今回はすごく大事だけど、ついつい忘れてしまいがちな、World TransformLocal Transformについて書いておきます。

 Transformは空のゲーム・オブジェクトであっても、少なくともこのコンポーネントは持たなければならない、という意味でUnityにおいて最も重要なコンポーネントであると言えます。

UnityTransform_TransformInspector

 位置(Position)回転(Rotation)スケール(Scale)の情報を持ち、インスペクター上ではそれぞれVector3(3次元ベクトル)で表されています。

 

 今回、書き記しておきたいことは、このTransformコンポーネントがそのオブジェクトの親子関係やヒエラルキー上のどこに居るかで性質が変わる、ということです。

UnityTransform_Hierarchy

 ヒエラルキーに直接置かれた場合、つまり、親オブジェクトを持たない、あるいは自身が親オブジェクトである場合は、このTransformコンポーネントはWorld Transformとなります。つまり、この時はWorld TransformとLocal Transformの値が一致します。

 子オブジェクトになった場合、そのTransformコンポーネントがインスペクター上で表すのはLocal Transformです。親オブジェクトがシーンの原点にいないと、World TransformとLocal Transformはそれぞれ異なる値になります。

 

 今回のケースでは、Parentという箱のオブジェクトの下にChildというボールのオブジェクトを置いています。

UnityTransform_Hierarchy

 ここでParentオブジェクトを横に動かしてみます。当然、Childであるボールは子オブジェクトなので、親である箱と一緒に動きます。

UnityTransform_MoveParentBox

Parentオブジェクトを選択し、横に動かす

UnityTransform_MovedParentInspector

 Parent(箱)の元々の座標は(0.0, 0.5, 0.0)だったので3メートルだけ右に動いたことになります。ここで、子オブジェクトのインスペクターを見てみます。

UnityTransform_MovedBallInspector

 記事の最初に貼ってあるインスペクターの画像は、子オブジェクトの初期位置のモノでした。つまり、この画像を見てわかるように親オブジェクトが動いたのに、ボールの座標が変わっていません。

 これはつまり、このTransformコンポーネントがLocal Transformを表しているからです。

 

 ここで実験用のスクリプトを子オブジェクトにアタッチして実行してみます。単にWorld PositionとLocal Positionをコンソールに表示するだけのものです。

UnityTransform_TestScript

 これをChild、つまりボールのオブジェクトに付けてプレイモードを実行します。するとコンソールに次のように表示されます。

UnityTransform_ConsoleLog

 ご覧のように異なる値が表示され、Local Positionの方は先ほどのインスペクターの画像と一致します。World Positonがシーンの原点(0.0, 0.0, 0.0)を基準とした座標を表しているのに対して、Local Positionは親オブジェクトの位置を基準とした空間(子オブジェクトのローカル空間)の座標を表しているわけです。

 

 transform.localPositionは親オブジェクトの挙動を気にすることなく、そのローカル空間でどの位置に置くか、あるいは移動させるかの処理をする時に使えます。

 

 今回は座標(Position)についてのみで、回転やスケールは省略しましたが、WorldとLocalの関係性は同様です。

 

 今回書いたことは基本中の基本ではあるんですが、特に表示が変わるわけでもないし、つい忘れてしまうんですよね。そしてワールド座標とローカル座標を混同した処理をしてしまって、何かおかしなことになるわけです。

 Unityでは複数のオブジェクトを階層を使って組み合わせることは多いですし、あるオブジェクトの階層下にあるオブジェクトを動かしたりする時などに、おかしなことが起きたら、今扱っているTransformはWorldなのかLocalなのかの確認をするといいかもしれません。