UnityのTransformとは結局何なのか|Position・Rotation・Scaleと親子関係を総まとめ

広告

TransformはすべてのGameObjectが持っている

これまで、UnityのTransformについて、

transform.position
transform.localPosition
transform.rotation
transform.localRotation
transform.localScale
transform.lossyScale

を順番に見てきました。

また、

transform.SetParent(...)

を使って、

Wall
└ BulletHole

という親子関係も作りました。

ここまで一つずつ見てきましたが、最後に、

そもそもTransformとは何なのか?

をまとめてみましょう。

UnityでGameObjectを作ると、必ずTransformがあります。

たとえばCubeなら、

Cube
├ Transform
├ Mesh Filter
├ Mesh Renderer
└ Box Collider

となっています。

Cameraなら、

Main Camera
├ Transform
└ Camera

です。

つまり、

TransformはGameObjectの基本となるComponent

です。

すべてのGameObjectが持つTransformのInspector表示(Position・Rotation・Scale)

Transformが持っている3つの基本情報

TransformをInspectorで見ると、

Position
Rotation
Scale

があります。

これは、

Position
→ どこにいる?

Rotation
→ どちらを向いている?

Scale
→ どのくらいの大きさ?

を表しています。

つまりTransformは、

3D空間でGameObjectがどんな状態にあるのか

を管理しています。

Position ― どこにいる?

まず、

Position

です。

Positionは、

GameObjectの位置

を表します。

コードでは、

transform.position

と、

transform.localPosition

があります。

positionは世界から見た位置

transform.position

は、

Unityの世界全体から見た位置

です。

たとえば、

position = (10, 2, 5)

なら、

世界の原点、

(0, 0, 0)

から見て、

X = 10
Y = 2
Z = 5

の場所にいるという意味です。

localPositionは親から見た位置

一方、

transform.localPosition

は、

親から見た位置

です。

たとえば、

Wall
└ BulletHole

で、

Wallが、

position = (10, 0, 0)

BulletHoleが、

position = (10.5, 1, 0)

なら、単純な例では、

BulletHole.localPosition
= (0.5, 1, 0)

です。

つまり、

Wallから右へ0.5、上へ1

ということです。

positionは世界から見た位置、localPositionは親から見た位置

Rotation ― どちらを向いている?

次は、

Rotation

です。

Rotationは、

GameObjectの向き

を表します。

コードでは、

transform.rotation

と、

transform.localRotation

があります。

rotationは世界から見た向き

transform.rotation

は、

世界全体から見た回転

です。

たとえばWallがY軸方向へ90度回転していて、

BulletHoleも一緒に回転しているなら、

世界から見たBulletHoleの向きも変わります。

localRotationは親から見た向き

一方、

transform.localRotation

は、

親から見た相対的な回転

です。

Wallを90度回転しても、

Wall
└ BulletHole

の向きの関係が変わっていなければ、

BulletHoleの localRotation は変わりません。

つまり、

rotation
→ 世界から見た向き

localRotation
→ 親から見た向き

です。

rotationは世界から見た向き、localRotationは親から見た向き

Scale ― どのくらいの大きさ?

最後は、

Scale

です。

Scaleは、

GameObjectの大きさの倍率

を表します。

たとえば、

(1, 1, 1)

なら基本の大きさです。

(2, 2, 2)

なら2倍です。

localScaleは親から見た倍率

コードでは、

transform.localScale

を使います。

これは、

親を基準にしたScale

です。

たとえば、

Wall.localScale
= (2, 2, 2)

BulletHole.localScale
= (1, 1, 1)

なら、

BulletHole自身は親から見て1倍ですが、

世界から見ると親の2倍Scaleの影響を受けます。

lossyScaleは世界側での実効Scale

世界側で、

実際にはどのくらいのScaleになっている?

を確認するときは、

transform.lossyScale

があります。

たとえば単純なケースなら、

親 = 2倍
子 = 1倍

なので、

lossyScale
= 約2倍

となります。

ただし lossyScale は読み取り専用です。

lossyScaleは世界から見た大きさ、localScaleは親から見た大きさ

3つをまとめると

Transformの基本は、

Position
Rotation
Scale

です。

それぞれ、

Position
→ 場所

Rotation
→ 向き

Scale
→ 大きさ

を表します。

これだけでも、

3D空間でGameObjectがどんな状態なのか

をかなり表現できます。

しかしTransformにはもう一つ重要な役割がある

Transformの重要な役割は、

Position
Rotation
Scale

だけではありません。

もう一つあります。

それが、

親子関係

です。

Transform同士で親子関係を作る

たとえば、

Wall
└ BulletHole

というHierarchyがあります。

コードでは、

bulletHole.transform.SetParent(
    wall.transform
);

のようにして親を設定できます。

つまり、

GameObjectの親子関係は実際には、

Transform同士の親子関係

として管理されています。

BulletHoleをWallの子にするSetParentと、HierarchyでのWallとBulletHoleの親子関係

親のTransformが子へ影響する

親子関係を作ると、

親の、

Position
Rotation
Scale

が子へ影響します。

つまり、

親が移動
↓
子も移動

親が回転
↓
子も回転

親が拡大
↓
子も拡大

となります。

これがTransformの親子関係です。

弾痕で考えると分かりやすい

これまで使ってきた、

Wall
└ BulletHole

を考えてみましょう。

BulletHoleをWallの子にすることで、

Wallを動かしても、

Wall → 移動
BulletHole → 一緒に移動

します。

Wallを回転させても、

Wall → 回転
BulletHole → 一緒に回転

します。

Wallを拡大すると、

Wall → Scale変更
BulletHole → Scaleの影響を受ける

ということになります。

親を移動・回転・拡大縮小すると、子も一緒に影響を受ける

ワールド座標とローカル座標

ここまで出てきた、

world
local

という考え方も整理しましょう。

Unityでは、

誰を基準に見るか

によって値が変わります。

ワールドとは?

ワールドとは、

Unityのシーン全体

だと考えると分かりやすいでしょう。

原点は、

(0, 0, 0)

です。

その世界全体を基準にした値が、

position
rotation

などです。

localとは?

localは、

親を基準にした値

です。

つまり、

localPosition
localRotation
localScale

は、

親Transformから見た状態を表します。

「local」が付いたら親基準

初心者の段階では、

local
=
親から見た

と覚えると非常に分かりやすいです。

たとえば、

localPosition

なら、

親から見た位置

です。

localRotation

なら、

親から見た向き

です。

localScale

なら、

親から見たScale

です。

一枚にまとめると

Transformを図にすると、

                 Transform
                     │
        ┌────────────┼────────────┐
        │            │            │
     Position     Rotation      Scale
        │            │            │
   どこにいる?  どちら向き?   大きさは?
        │            │            │
   ┌────┴────┐  ┌────┴────┐  ┌────┴────┐
   │         │  │         │  │         │
 world     local world   local world   local
   │         │    │       │     │       │
position   local  rotation local lossy  local
          Position         Rotation Scale Scale

さらにTransformには、

Parent
Child

という親子関係もあります。

つまり、

Transform
├ Position
├ Rotation
├ Scale
└ Parent / Child

と考えることができます。

WallとBulletHoleで全部まとめる

たとえば、

Wall
└ BulletHole

があります。

Wallが、

position
= (10, 0, 0)

rotation
= Y 90°

localScale
= (2, 2, 2)

だったとします。

BulletHoleはWallの子です。

そのためBulletHoleは、

Wallから見てどこ?
→ localPosition

Wallから見てどちら向き?
→ localRotation

Wallから見て何倍?
→ localScale

という情報を持ちます。

一方、

世界から見る場合は、

世界から見てどこ?
→ position

世界から見てどちら向き?
→ rotation

世界から見て実効的に何倍?
→ lossyScale

となります。

Wallと BulletHoleのposition・rotation・localScale・lossyScaleを数値で比較した表

親がないGameObjectでは?

親がないGameObjectなら、

世界基準
=
自分の基準

に近い状態です。

そのため、

position

と、

localPosition

は同じ値になります。

同様に、

rotation

と、

localRotation

も同じ回転を表します。

親子関係ができたときに、

localという考え方が重要になる

わけです。

InspectorのTransformは基本的にlocal

UnityのInspectorを見ると、

Transform

Position
Rotation
Scale

と表示されています。

親がある場合、この表示値は基本的に、

localPosition
localRotation
localScale

として考えると理解しやすいでしょう。

そのため、

Inspectorで、

Position X = 1

となっていても、

世界座標のXが1とは限りません。

親がどこにいるかによって変わります。

Transformは「空間上の住所」だけではない

Transformを、

GameObjectの座標

だけだと思うと少し足りません。

Transformが管理しているのは、

場所
向き
大きさ
親子関係

です。

つまり、

GameObjectが3D空間の中で、他のGameObjectとどんな関係にあるのか

まで含めて管理しています。

transformはなぜ頻繁に出てくるのか

Unityのコードでは、

transform.position
transform.Rotate(...)
transform.Translate(...)
transform.SetParent(...)

など、

transform が頻繁に登場します。

これは当然です。

ゲームでは、

動かす
回す
大きさを変える
他のオブジェクトについていかせる

といった処理が非常に多いからです。

つまり、

Transformはゲーム中の「動き」と非常に深く関係するComponent

なのです。

Rigidbodyとは何が違う?

ここまで理解すると、

Rigidbodyも位置を動かすのでは?

と思うかもしれません。

確かにRigidbodyもGameObjectの移動に関係します。

ただし、

Transform
→ 空間上の位置・回転・Scale・親子関係

Rigidbody
→ 物理法則による動きを扱う

という役割の違いがあります。

Rigidbodyを使って動いた結果も、

最終的にはTransformの位置や回転としてシーン上に表れます。

Raycastの記事からTransformまでつながった

今回のシリーズは最初、

Camera.main.ScreenPointToRay(...)

から始まりました。

そこから、

Camera.main
↓
ScreenPointToRay
↓
Physics.Raycast
↓
RaycastHit
↓
hit.point
↓
hit.normal
↓
Instantiate
↓
SetParent
↓
position / localPosition
↓
rotation / localRotation
↓
localScale / lossyScale
↓
Transform

とつながりました。

最初は、

マウスでクリックした場所を調べる

という処理でした。

しかし最終的には、

Unityの3D空間そのものを扱うTransformの考え方

までつながっています。

Transformを一言で言うと?

初心者向けに一言で表すなら、

Transformは、GameObjectが3D空間で「どこにいて、どちらを向き、どの大きさで、何を基準にしているか」を管理するComponent

と考えるとよいでしょう。

最後に一覧で整理する

プロパティ 意味 基準
position 位置 世界
localPosition 位置 親
rotation 回転 世界
localRotation 回転 親
lossyScale 実効Scale 世界
localScale Scale 親

そして、

SetParent()

によって、

その「親基準」を作る

ことができます。

Transformの重要ポイントのまとめ

まとめ

Transformの中心にあるのは、

Position
Rotation
Scale

です。

そして、

world
local

という2つの見方があります。

整理すると、

世界から見る

position
rotation
lossyScale

と、

親から見る

localPosition
localRotation
localScale

です。

さらに、

親
└ 子

というTransformの親子関係によって、

親の、

移動
回転
Scale

が子へ影響します。

つまりTransformとは、

単なる座標の入れ物ではなく、

GameObjectが3D空間の中でどう存在し、他のGameObjectとどう結び付いているかを表す基本Component

なのです。

UnityでGameObjectを理解するうえで、Transformは避けて通れません。

しかし、

Position
Rotation
Scale

world
local

Parent
Child

という3つのまとまりに分けて考えれば、かなり整理しやすくなります。


【シリーズ】Raycastで弾痕を作りながら学ぶ(9/9)
← 前の記事:localScaleとlossyScaleの違い | シリーズ目次

訪問数 5 回, 今日の訪問数 5回

広告

Unity

Posted by hidepon