移動
指定座標にオブジェクトを配置する
Unity エディタからオブジェクトに対して行える設定は、スクリプトからも同様に設定できます。Unity ではオブジェクトが持つ状態はすべてコンポーネントと呼ばれる個別の部品の組み合わせで構成されています。オブジェクトが持つコンポーネントは「Inspector」ウィンドウに表示されています。
通常、コンポーネントは Unity ユーザーインタフェース上のメニューにある「Component」メニューから追加できますが、必要であればスクリプトからコンポーネントの追加や削除を行うこともできます。Unity は標準で多くのコンポーネントを提供していますが、それらはすべて UnityEngine.Component クラスから派生しています。
UnityEngine.Object UnityEngine.Component
public class Component : Object
興味深いことに Unity のスクリプト自身もまた Component クラスを継承する MonoBehaviour クラスを実装するため、コンポーネントの一種として管理されます。
オブジェクトに設定されているスクリプト(MonoBehaviour)自身の transform プロパティを変更することで、スクリプトが設定されているオブジェクトの位置を変更できます。
public Transform transform { get; }
このプロパティは、オブジェクトの座標や向き、大きさを表す UnityEngni.Transform クラスを返します。このクラスのオブジェクトは「Inspector」ウィンドウに表示されている Transform に相当する機能を提供します。
UnityEngine.Object UnityEngine.Component UnityEngine.Transform
public class Transform : Component, IEnumerable
オブジェクトの空間内における位置を変更するには position プロパティを変更します。同様に、このプロパティからオブジェクトの現在位置を取得できます。
public class Vector3 position { get; set; }
このプロパティは、オブジェクトの座標を表す原点からのベクトルを Vector3 構造体で表します。
using UnityEngine; public class Test : MonoBehaviour { void Start () { transform.position = Vector3.zero; } }
コード1は実行するとオブジェクトの座標を原点 (0, 0, 0) に移動させるスクリプトです。自分自身の transform プロパティが返す Transform オブジェクトの position プロパティに Vector3.zero を代入しています。このときの position プロパティに設定する Vector3 構造体の値が、新しいオブジェクトの座標となります。
実行結果の最初の画像は実行前のオブジェクトの状態、2 番目の画像が実行中の状態です。Inspector の Position を見ると、正しく座標が変更されていることが確認できます。
ワールド座標系とローカル座標系
Unity のシーンに登録されているオブジェクトは親子関係でグループ化されます。現在のシーンでインスタンス化されているオブジェクトの構造は「Hierarchy」ウィンドウで確認できます。
このとき、オブジェクトの位置や向き、サイズといった変換情報は親オブジェクトの影響をうけます。Unity エディタ上で親オブジェクトを移動させれば、関連付けられているすべての子オブジェクトも親に合わせて移動します。つまり、親オブジェクトに対して子オブジェクトは相対的に作用します。
親オブジェクトとは無関係に、空間の原点を中心にした座標系をワールド座標と呼び、これに対して親オブジェクトの座標を原点とした座標系をローカル座標と呼びます。
通常、スクリプトからオブジェクトを操作するときはローカル座標を想定するでしょう。ところが、前述した position プロパティはワールド座標を表すため、親オブジェクトとは無関係に空間全体の原点を軸としています。そうではなく、親オブジェクトを中心としたローカル座標で移動させたい場合は localPosition プロパティを使ってください。
public Vector3 localPosition { get; set; }
position プロパティとの違いは、このプロパティで読み書きする値はオブジェクトのローカル座標、すなわち親オブジェクトの原点を軸にしていることです。よって、スクリプトから座標を変更しても、親との関係が無視されることはなくなります。
using UnityEngine; public class Test : MonoBehaviour { void Start () { transform.localPosition = Vector3.zero; } }
コード2は localPosition プロパティにゼロのベクトルを設定しているため、ローカル座標系の原点にオブジェクトを移動させます。実行結果の例では 2 つの立方体を共通の Owner 親オブジェクトに追加し、それぞれ親の原点から X 軸方向に距離を取った状態で開始しています。最初の画像が実行前、2番目の画像が実行中の状態です。
Owner オブジェクトはワールド座標の原点に対し Z 軸が -3 の位置まで移動させています。親オブジェクトの位置に合わせて、子オブジェクトである立方体も同様に Z 軸が -3 の位置に移動しています。
スクリプトは画面から向かって右側の立方体にのみ設定して開始しています。実行結果から、立方体の位置が親の原点まで移動することが確認できます。
localPosition プロパティではなく、ワールド座標系の position プロパティを用いれば、ローカル座標系とワールド座標系の違いを体験できるでしょう。
図3はコード2のスクリプトを書き換え、position プロパティに対してゼロのベクトルを設定したものです。この場合、立方体は親の原点ではなくワールド座標(世界全体)の原点に移動してしまいます。ワールド座標系では、親の座標は作用しません。
移動
position プロパティや localPosition プロパティを用いることで、オブジェクトの位置を自由に変更できます。ゲーム中では、オブジェクトの現在の位置から指定した距離を移動させるという処理が多くなりますが、移動処理には Translate() メソッドを使うこともできます。このメソッドはオーバーロードされています。
public void Translate(float x, float y, float z)
public void Translate(Vector3 translation)
X 軸の移動量は x パラメータ、Y 軸の移動量は y パラメータ、Z 軸の移動量は z パラメータに、それぞれ指定します。
translation パラメータには、移動量を表す Vector3 型のベクトルを指定します。
このメソッドは、オブジェクトの現在の位置から指定したベクトルだけ移動します。同様の処理は position プロパティや localPosition プロパティに対して複合代入演算で値を加えても可能です。
transform.position += new Vector3(x, y, z);
Translate() メソッドによるオブジェクトの移動は、上記のコードと同義です。
using UnityEngine; public class Test : MonoBehaviour { void Start () { transform.Translate(2, 0, 0); transform.Translate(0, 1, 0); transform.Translate(0, 0, -3); } }
コード3は Translate() メソッドを複数呼び出して、オブジェクトを移動させています。このプログラムで Translate() メソッドの呼び出しを分割する意味はありませんが、このメソッドによる移動が現在位置からのベクトルの加算であることを確認するために、このような処理にしています。
Translate() メソッドは、キー入力や時間によって指定の方向に一定の量で移動させるような処理に適しているでしょう。