この記事ではUnityでの空間の座標について解説しています。
<空間の見方を便利にする2つの座標系>
Unityにおいて、空間を表現する際にワールド基準、ローカル基準という2つの見方をします。
何故このように2つの見方をするかというと、計算がしやすいからです。
↑のようにゲームオブジェクトを空間に置いた時
自身がどの位置にいるのかを参照する際に使用します。
Unity初心者の方はこの2つを混同しやすいのでこの2つの違いについて解説していこうと思います。
<ワールド座標(グローバル座標)について>
ワールド座標というのは原点から見た座標になります。
(X,Y,Z)>(0,0,0)の位置からどれだけの距離にいるのかを絶対的な数値で知る事ができます。
グローバル座標で(10,10,10)といえば、絶対に原点からXが10, Yが10, Zが10の位置にいます。
<ローカル座標について>
そのゲームオブジェクトの1つ上の親から見た相対的な座標です。
Unityではゲームオブジェクトに「親子関係」というものを作成する事ができます。
親子関係がよくわからない人は↓の記事を参考にしてください。
親子関係になると子オブジェクトが親オブジェクトに追従するようになります。
↓の映像ではCubeしか動かしていませんが、Sphereも追従して動いている事がわかると思います。
このように位置、回転、大きさが親の影響を受けます。
ちなみに、親は子の影響を受けるわけではないので注意してください。
この時、親から見てどの位置にいるのかを知るためにローカル座標が用いられます。
例えば↓のように2つのゲームオブジェクトを用意します。
そして、インスペクターでCubeの位置をx座標だけ10に
Sphereの位置をx座標だけ15にします。
Cubeの座標は(10,0,0),Sphereの座標は(15,0,0)で現在親子関係ではありません。
ではSphereをCubeの子にしてみてください。
Cubeのインスペクターは変わりませんが、Sphereの座標が(5,0,0)になったかと思います。
Cubeが10でSphereが15の位置にいるので、Cubeの子になったSphereはCubeから見て5の位置に存在するという事です。15-10=5ですね。
このように、親から見た相対的な座標をローカル座標と呼びます。
親が1つも存在しない場合ローカル座標=ワールド座標ですが、親が存在する場合、全然違う座標系になるため、注意してください。
<ワールド空間・ローカル空間>
また、座標だけではなく、回転や大きさなどにもワールドとローカルが存在します。
これらも(0,0,0)から見てどれだけ回転しているか、大きくなっているかがワールドで、親から見てどれだけ回転しているか、大きくなっているかがローカルになります。
このような考え方を座標の時と同じようにワールド空間、ローカル空間と言います。
考え方を座標から拡大していると考えてもらっていいかと思います。
<Transformでのワールドとローカル>
インスペクターでのTransformの値はローカル基準のものになります。
↑では全てローカルでしたが、スクリプトでの扱いは
・transform.position・・・ワールド空間での位置
・transform.rotation・・・ワールド空間での回転
・transform.lossyScale・・・ワールド空間での大きさ
・transform.localPosition・・・ローカル空間での位置
・transform.localRotation・・・ローカル空間での角度
・transform.localScale・・・ローカル空間での大きさ
で表されます。
インスペクターではlocalとつかないのにローカルでしたが、スクリプトでは区分けが存在しますので注意してください。
この辺りをごっちゃにしてしまってバグってしまう事がよくあるので気に留めておくといいと思います。
<ワールド座標とローカル座標の変換>
ワールド座標をローカル座標に変換するには
Vector3 local = 親のゲームオブジェクト.transform.InverseTransformPoint (ワールド座標);
で変換する事ができます。
ローカル座標をワールド座標に変換するには
Vector3 world = 親のゲームオブジェクト.transform.TransformPoint (ローカル座標);
で変換する事ができます。
<Space型>
スクリプトで空間をワールド基準なのかローカル基準を表したい時にはこのSpace型を使用します。
enum型でワールドかローカルかを示すのに使います。
名前空間 | UnityEngine |
型 | enum |
World
ワールド座標を表します。
○ 使い方
public float speed = 100.0f; void Update() { //ワールド空間上で斜めに回ります。 transform.Rotate(Vector3.one * speed * Time.deltaTime, Space.World); }
Self
ローカル座標を表します。
○ 使い方
public float speed = 100.0f; void Update() { //ローカル空間上で斜めに回ります。 transform.Rotate(Vector3.one * speed * Time.deltaTime, Space.Self); }