こんにちは、Unityエンジニアのオオバです。

お悩みさん
お悩みさん
  • UnityのTransformって何?
  • Transformって大事?
  • 基本的な使い方を知りたい
  • Transformのよく使うテクニックを知りたい
  • オオバ
    オオバ
    本記事ではこれらの悩みを解決します。

    Transformはゲーム開発において超絶必須

    はじめに結論を簡単にまとめます。

    Transformはゲーム開発において超絶必須

    ①Transformは移動・回転・拡大縮小といった重要機能を持つ

    ②GameObjectに必ず付与、削除不能な特別コンポーネント

    ③ゲーム開発では必ず使うレギュラーコンポーネント

    TransformはUnityでゲーム開発する上で超絶必須機能 です。「移動」「回転」「拡大縮小」「グループ化」といったゲーム中に何度も登場する重要な機能を担っています。ゲーム開発でキャラクターを動かしたり、パズルを動かすときには必ずTransformを操作します。

    Unity初心者から熟練者まで誰もが常時関わる機能です。ぜひTransformを使えるようになりましょう。

    👉DOTweenの教科書を読んでUnityアニメーションをプログラミングしてみよう!

    もくじ

    特別なコンポーネントTransformとは?

    Transform(トランスフォーム)とは コンポーネントの1種 です。コンポーネントとはUnityにとっては機能のことを指します。Transformはコンポーネントの1つなので、カメラやライトと同じような機能の1つと考えて大丈夫です。

    Transformにどのような機能があるかというと、 「移動」」「回転」「拡大縮小」「グループ化(階層化)」 です。ゲーム開発ではよく使われる機能を持っていると言えます。

    またTransformコンポーネント(以下:Transform)は以下の3つの点においてUnityの中では 特別な存在 です。

    Transform 3つの特別なポイント

    ①GameObjectに必ずセットされる

    ②Transformは削除不可能

    ③Transformの取得にGetComponentは不要

    そもそも 「コンポーネント」って何? という方のためにお伝えすると、 コンポーネントの理解はUnityのゲーム開発では必須 です。「ちょっと理解があいまいだな」と思っている方はぜひ次の記事がおすすめです。Unity歴11年のオオバがコンポーネントについて徹底解説しています。本記事とあわせて読むことでより学べると思いますので、ぜひ読んでみてください。

    特別その①GameObjectに必ずセットされる

    Transformは1つのGameObjectに1つ ”必ず” セットされます。つまり、 TransfromをもたないGameObjectは存在しない ということです。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_0

    すべてのGameObjectには移動や回転といった基本的な機能がTransformによって実装されているのです。

    そもそもGameObjectとはUnityの基礎となるオブジェクトです。こちらの記事でGameObjectを徹底解説していますので、ぜひあわせて読んでみてください。

    特別その②Transformは削除不可能

    Transformは削除できません。特別その①GameObjectに必ずセットされるで解説したとおり、GameObjectには 必ずTransformが存在します。 つまり、このTransformを削除する方法はないということです。

    以下の図の通りTransformのInspectorウィンドウには「Remove Component」がありません。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_1

    ちなみに通常のコンポーネントの削除はRemove Componentを使います。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_2

    スクリプトから削除しようとすると以下のようなエラーが出力されます。

    Can't destroy Transform component of 'Destroyを実行したメソッド名'.  
    If you want to destroy the game object, please call 'Destroy' on the game object instead. Destroying the transform component is not allowed.  
    

    つまり、TransformはDestroy(オブジェクトの削除)を許可していない のです。

    Transformは2つ以上追加不可

    Transformは2つ以上追加できません。 ためしに Add Component からTransformを追加してみます。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_3

    上図の通り、そもそも「Transform」がリストに表示されないのです。GameObjectに最初から付与されていることから、追加することのないコンポーネントなので リストから除外 されているのだと思われます。

    特別その③Transformの取得にGetComponentは不要

    通常コンポーネントを取得するために GetComponent を使います。しかし、Transformはコンポーネントの中では特別で、 transform を使ってもTransformを取得できます。

    Before
    // GetComponentでTransformを取得  
    Transform tr = gameObject.GetComponent<Transform>();  
    

    After
    Transform tr = gameObject.transform;  
    

    上のソースコードの通りGetComponentを使わず、 transform でTransformを取得できるのです。

    RectTransformはUIで使用するTransformのサブクラス

    Transformと似た名前で「RectTransform」コンポーネントを見かけますよね。

    RectTransformは ”UI用のTransform” です。

    UI上の「位置」「回転」「拡大縮小」といった機能を担っています。

    また、RectTransform自体はTransformのサブクラスです。

    つまりRectTransformはTransformに機能を追加した存在。

    UI開発でお世話になるRectTransformは、Transformを学ぶことでより深く理解できると思います。

    Transformの基本的な使い方4選

    TransformはUnityにとって「特別なコンポーネント」だとわかりました。ここからはTransformの基本的な使い方について解説していきます。

    Transformの基本的な使い方4選

    ①Transformの位置変更「position・localPosition」

    ②Transformの回転「eulerAngles・rotation」

    ③Transformで拡大縮小「localScale」

    ④Transformの階層化「SetParent」

    使い方①Transformの位置変更「position・localPosition」

    ゲーム開発でキャラクターの位置を動かしたくなりますよね。位置の変更はTransformの役割です。Inspectorウィンドウ上では「Position」が 位置のパラメーター です。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_4

    X、Y、Zそれぞれの座標を変更できます。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_5

    スクリプトでTransformの位置を操作する場合は position または localPosition を使います。実際のサンプルを見ていきましょう。1秒後にTransformのX座標を0から2へ移動させるサンプルです。

    💻ソースコード : 位置を変更するサンプル
    using System.Collections;  
    using UnityEngine;  
    public class PositionUpdate : MonoBehaviour  
    {
        IEnumerator Start()  
        {
            transform.localPosition = new Vector3(0, 0, 0);  
            // コルーチンで1秒待機  
            yield return new WaitForSeconds(1f);  
            // 1秒後に座標を(2, 0, 0)へ移動  
            transform.localPosition = new Vector3(2f, 0, 0);  
        }
    }
    

    このスクリプトを実際に動かしてみましょう。今回Unityちゃんに先のサンプルコードをアタッチして動かしてみました。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_6

    1秒後にX座標が移動したことがわかります。

    このようにTransformの position または localPosition に値をセットすることで、Transformの座標を更新、変更することが出来るのです。

    👉 【無料】SD版Unityちゃんのダウンロードから使い方を解説!

    ところで先の例では「コルーチン」を使って1秒の 待機処理 を実装しました。コルーチンは非同期処理と呼ばれ、 ゲーム開発では必須の知識 。コルーチンを学びたい、復習したい方はあわせてこちらの記事がおすすめです。

    positionとlocalPositionの違い

    Transformの座標プロパティには「position」と「localPosition」の2つが存在します。似ているようで全く違います。両者の違いは”正確”に理解しておく必要があります。自分の思ったとおりにオブジェクトを配置するために 必須の知識 です。

    結論から解説すると positionは「絶対座標」localPositionは「相対座標」 です。

    position「絶対座標」とは?

    言わずもがな Unityの世界は3D です。X軸、Y軸、Z軸そして「原点」が存在します。原点とはXYZそれぞれ0の座標です。(0, 0, 0)のこと。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_7

    絶対座標とは原点基準の座標 です。下の図はUnityちゃんを原点からX座標2離れた位置に配置しました。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_8

    もう1例としてUnityちゃんを原点から(1, 0, 2)の座標に配置。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_9

    このように 絶対座標は感覚的でわかりやすい です。絶対座標は「グローバル座標」とも呼ばれます。

    localPosition「相対座標」とは?

    次にlocalPosition(相対座標)についてです。結論、 localPosition(相対座標)とは「親階層基準の座標」 です。使い方④Transformの階層化で詳しく解説しますが、Transformは階層を作れます。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_10

    上図のような階層です。

    下記のシンプルな親子関係を例にlocalPositionを解説します。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_11

    親階層を「Parent」、子階層を「Child」と名付けました。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_12

    まずは親階層のParentの位置を(0, 1, 0)にしてみます。

    では子階層ChildはX軸を2だけ動かした(2, 0, 0)の位置にしてみます。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_13

    するとposition「絶対座標」とは?で解説したときのUnityちゃんと位置が変わります。Parentの位置が基準のため、Unityちゃんは原点よりY座標が1上なのです。

    localPositionとpositionの比較画像

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_14

    同じ座標でもlocalPosition(相対座標)とposition(絶対座標)では配置される場所がかることがわかります。

    Visual Scriptingを使うとソースコードを書かずにTransformを操作できるようになります。これによりプログラマーとクリエーターの協業作業がしやすくなります。興味ある方はこちらの記事も読んでみてください。

    positionとlocalPositionの使い分け

    絶対座標のpositionと相対座標のlocalPositionの違いを解説してきましたが、どう使い分けたら良いかわからないですよね。結論から書きますと、 普段の使用はlocalPosition で大丈夫です。Transformの階層が深く、どうしても子階層を絶対座標に移動させたい場合に position を使いましょう。

    重要なことですが、 無意味にlocalPositionとpositionを混ぜるのは混乱の元なので絶対に禁止 です。自分自身もそうですが、チームメンバーも訳がわからなくなります。ほとんどの配置処理はlocalPositionの使用をおすすめします。

    繰り返しになりますが、普段の使用は「localPosition」、どうしてもな場合に限り「position」という考えで大丈夫です。

    ところでUnityでアニメーションを作成するときの候補に「AnimationClip」は必ず挙がります。 AnimationClipは初心者でも簡単にアニメーションを作れるUnityのツールです。 ゲームにはアニメーションは必須スキル。次の記事ではAnimationClipの使い方を初心者向けに徹底解説しました。本記事とあわせてぜひを読んでみてください。

    Unityの単位はメートル

    Unity内の座標の話が登場したため、Unityの距離と単位について解説します。結論、 Unityの単位はメートル です。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_15

    例えばPositionに(3, 0, 0)とセットすれば、原点からX軸 3メートル離れた位置 に配置したことになります。

    単位は思っている以上に重要です。Unityに3Dソフトで作成した素材をインポートすることがあります。 3Dソフトの単位はメートルとは限りません。

    Unityにインポートして、意図した大きさにならない場合は単位の確認が重要なのです。 「Unityはメートル」 であることをぜひ覚えておきましょう。

    Vector3とは?

    今回登場した Vector3 とは3つの数字を保持するデータです。x、y、zの3つのプロパティでアクセスできます。次のサンプルを見てみましょう。

    💻ソースコード : Vector3の各要素をログ出力するサンプル抜粋
    // Vector3を生成  
    Vector3 vector3 = new Vector3(10, 5, 20);  
    
    // vector3のx、y、zの各要素をログ出力  
    Debug.Log($"{vector3.x} / {vector3.y} / {vector3.z}");  
    

    実行すると以下のようにログがConsoleウィンドウに出力されます。

    Vector3は数字を保持する他に、四則演算、2点間の距離といった便利な機能が多く実装されています。1点気をつけるべき点は、Vector3の保持する数字は小数です。小数とは、「1.4」「0.5」「-0.07」このような ”小数点” を持つ数字。

    逆に整数を扱う Vector3Int という型も存在します。ここでは紹介だけで終っておきますね。

    Translateメソッドで位置移動

    Transformのposition、localPositionの値の更新で位置を変更してきました。その他に、 Translate メソッドもTransformの位置を変更できます。Translateメソッドの引数に移動させる距離を指定。Transoformの現在距離に加算します。

    transform.Translate(new Vector3(1, 0, 0));  
    

    上のTranslateのコードは下記のコードと処理内容は同じです。

    transform.localPosition += new Vector3(1, 0, 0);  
    

    相対座標に対して距離を加算します。

    一方Translateの第2引数に Space.World を代入すると、絶対座標の方向指定になります。

    transform.Translate(new Vector3(1, 0, 0), Space.World);  
    

    上のTranslateのコードは下記のコードと同じです。

    transform.position += new Vector3(1, 0, 0);  
    

    絶対座標に対して距離を加算します。

    無理してTranslateを使わずともposition、localPositionを使っても同じ処理を書けます。初心者はTranslateは覚えなくても大丈夫。まずは基本となる「position」と「localPosition」の使い方を覚えておきましょう。

    使い方②Transformの回転「eulerAngles・rotation」

    Transformの回転機能について解説します。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_16

    Inspectorウィンドウでは Rotation がTransformの角度パラメーターです。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_17

    X、Y,Zそれぞれの軸の回転が可能です。

    スクリプトから回転を制御する方法はいくつかあります。

    localEulerAngles・eulerAnglesで角度を変更

    localEulerAngles、または eulerAnglesを使って角度を変更する処理の紹介です。Eulerの読み方は 「オイラー」 です。使い方①Transformの位置変更「position・localPosition」と同様、回転にも原点基準の回転と親基準の回転が存在します。

    次のサンプルコードを見てみましょう。1秒後にTransformのY軸を90度回転させます。

    using System.Collections;  
    using UnityEngine;  
    public class EulerAnglesUpdate : MonoBehaviour  
    {
        IEnumerator Start()  
        {
            transform.localEulerAngles = new Vector3(0, 0, 0);  
            // コルーチンで1秒待機  
            yield return new WaitForSeconds(1f);  
            // 1秒後に座標を(0, 90, 0)へ移動  
            transform.localEulerAngles = new Vector3(0, 90, 0);  
        }
    }
    

    このコードを実行してみます。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_18

    すると、1秒経過するとUnityちゃんが90度横を向来ました。localEulerAngles、EulerAnglesはVector3の値を代入することでTransformを回転させます。

    localRotation / rotationで角度を変更

    eulerAnglesのほかに、 rotation を使って角度を変更できます。rotationにはVector3ではなく、 Quaternion(読み方 : クォータニオン) を使います。

    聞き慣れないキーワードかもしれません。しかし回転処理をさせる上でとても便利です。また原点基準のrotation、親階層基準のlocalRotationを利用できます。localEulerAngles・eulerAnglesで角度を変更で紹介した90度回転するUnityちゃんサンプルを rotation で実装すると以下のコードになります。

    using System.Collections;  
    using UnityEngine;  
    public class RotationUpdate : MonoBehaviour  
    {
        IEnumerator Start()  
        {
            transform.rotation = Quaternion.identity;  
            // コルーチンで1秒待機  
            yield return new WaitForSeconds(1f);  
            // 1秒後に正面方向が(1, 0, 0)を向く  
            transform.rotation = Quaternion.LookRotation(  
                    new Vector3(1, 0, 0), new Vector3(0, 1, 0)  
                );  
        }
    }
    

    ポイントは以下のコードです。パッと見よくわからないと思うので解説します。

    transform.rotation = Quaternion.LookRotation(  
            new Vector3(1, 0, 0), new Vector3(0, 1, 0)  
        );  
    

    Quaternion.LookRotation は、第1引数に「向かせたい方向」、第2引数に「回転物の上方向」を指定します。第1引数に「向かせたい方向」は、回転物の正面が向く方向になります。 正面とは「正のZ方向」 です。つまり(0, 0, 1)。

    下図のUnityちゃんの例では、Z方向はUnityちゃんの背中の方向です。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_19

    つまり、このUnityちゃんの正面とは背中方向だということです。

    ※今までの例を分かりやすく伝えるためにUnityちゃんを180度回転させています

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_20

    上図のとおり第2引数の上方向は(1, 0, 0)です。向かせたい方向は(1, 0, 0)。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_21

    回転を実行すると、Unityちゃんの背中が正のX方向(1, 0, 0)を向くのです。

    Quaternion.LookRotationはなぜ上方向を指定するのか?

    Quaternion.LookRotation はなぜ第2引数で上方向を指定するのでしょうか。理由は3D上の回転なので、さまざまな方向から回転できてしまうからです。以下の例は第2引数の上方向を(0, 1, 0)ではない値を指定した例です。最終的な結果は同じですが、途中経過が意図しません。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_22

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_23

    上方向を指定することで、意図した回転になるのです。今回立っているUnityちゃんを動かしたいので、上方向とはY軸方向。つまり(0, 1, 0)と指定しました。Yの値を1にしていますが、10にしても100にしても大丈夫です。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_24

    このコードを実行するとEulerAnglesのサンプルと同じ挙動になります。

    Quaternionは難しい

    本記事ではQuaternionを深堀りしません。なぜなら 難しいから です。

    Quaternionを理解するためには前提として数学的な知識が必要。初心者は内部処理は知らなくてよいと考えています。とりあえず使い方を知っておくだけで大丈夫。それよりゲーム開発に時間を使うほうが有意義だと思っています。

    それでもQuaternionについて理解したい方はこちらの動画がおすすめです。元Unityの安原さんの動画です。とても分かりやすく順序立てて解説しているためぜひ見てみてください。

    使い方③Transformで拡大縮小「localScale」

    Transformの拡大縮小を解説します。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_25

    Inspectorウィンドウでは Scale が拡大縮小のパラメーター。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_26

    X、Y,Zそれぞれの軸の拡大縮小が可能です。スクリプトでは localScale を使います。

    using System.Collections;  
    using UnityEngine;  
    public class ScaleUpdate : MonoBehaviour  
    {
        IEnumerator Start()  
        {
            transform.localScale = new Vector3(1, 1, 1);  
            // コルーチンで1秒待機  
            yield return new WaitForSeconds(1f);  
            // 1秒後に2倍にスケール  
            transform.localScale = new Vector3(2, 2, 2);  
        }
    }
    

    このコードを実行すると、1秒後にUnityちゃんは2倍の大きさになります。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_27

    Transformの拡大縮小は移動や回転と違い、「localScale」1種類のみです。

    使い方④Transformの階層化「SetParent」

    移動、回転、拡大縮小に並んでTransformの重要な機能は 階層化 です。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_28

    今までで何度か登場しましたが、上図のような階層を作れます。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_29

    Inspectorウィンドウ上ではGameObjecctをドラッグ・アンド・ドロップすることで階層化出来ます。

    SetParentを使ってTransformを階層化

    プログラムで実装する場合は SetParent メソッドを使います。

    using UnityEngine;  
    public class SetParentSample : MonoBehaviour  
    {
        [SerializeField] Transform _parent;  
    
        void Awake()  
        {
            // SetParentで自分自身を「_parent」の子階層にする  
            transform.SetParent(_parent, false);  
        }
    }
    

    SetParent の引数にTransformインスタンスを指定します。指定されたTransformが親階層に設定されるのです。

    そもそも Awake とはなにか?という人もいますよね。AwakeとはUnityではイベント関数と呼ばれています。 MonoBehaviour クラスを継承するとUnityから自動で呼ばれる関数です。

    Awakeはイベント関数の1つで、初回に1度呼ばれます。詳しくは次の記事を読んでみてください。

    SetParentの第2引数の違いは重要

    SetParentメソッドの第2引数の理解は重要です。大きく挙動が変わります。

    ※何も指定しなければtrueです

    SetParentの第2引数は、子オブジェクトの座標、回転、拡大縮小パラメーターを引き継ぐかどうかです。

    仕様だけ説明しても理解しづらいため具体例を挙げて紹介します。

    次のような「Parent」と「Child」の2つのオブジェクトを用意します。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_30

    2つのオブジェクトは最初並列で、親子関係ではありません。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_31

    SetParentで親子関係にしたとき、第2引数の切り替えでどのような変化があるのか確認していきます。

    SetParentの第2引数がtrueの場合

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_32

    trueを指定すると見た目は何も起きません。

    SetParentの第2引数がfalseの場合

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_33

    falseを指定すると「Child」が動きましたね。

    繰り返しになりますが、SetParentの第2引数は 子オブジェクトの座標、回転、拡大縮小パラメーターを引き継ぐかどうか です。

    SetParentの第2引数をfalseにすると、Childは親子になる前の(0, 0, 0)座標を引き継ぎます。親のParentの座標は(4, 0, 0)でした。子階層は親階層を基準にした座標でしたね。

    つまり、Childは(4, 0, 0)を基準に(0, 0, 0)に配置されたということです。パッと見Childは(4, 0, 0)に移動したように見えますね。SetParent第2引数は、たいていfalseを採用します。trueはめったに使いません。使わざるを得ない状況で使うと良いでしょう。

    1つ上の親を参照するparent

    Transformの親子を作ったら、親子供それぞれアクセスしたくなります。指定のTransformの親アクセスは「parent」プロパティです。次のような親子関係の「Child」から親にアクセスしてみます。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_34

    次のコードを見てみましょう。

    using UnityEngine;  
    public class ParentSample : MonoBehaviour  
    {
        void Awake()  
        {
            var parent = transform.parent;  
            Debug.Log(parent);  
        }
    }
    

    このコードをChildにセットして実行します。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_35

    するとこのように親階層である「Parent」を取得したログが出力されます。

    ルート階層でparentアクセスはnull

    parentアクセスの注意点はルート階層で使った場合です。結論、ルート階層でparentアクセスするとnullが返ってきます。具体的には以下の状態です。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_36

    Hierarchyウィンドウの第一階層に親階層は存在しません。parentにアクセスしてもnullなのです。先のコードを改善すると以下です。

    using UnityEngine;  
    public class ParentSample : MonoBehaviour  
    {
        void Awake()  
        {
            var parent = transform.parent;  
            if (parent != null) {  
                // nullチェックしてアクセスすると安全  
            }
        }
    }
    

    transform.parent はnullの可能性があるため、nullチェックすると安全です。

    ルートの参照方法root

    深い階層からルートのTransformにアクセスしたくなる時があります。そんなときは root プロパティを使います。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_37

    上図のようなイメージです。深い階層「Child」から「Root」を取得します。次のコードをChildにアタッチして実行してみましょう。

    using UnityEngine;  
    public class RootSample : MonoBehaviour  
    {
        void Awake()  
        {
            var root = transform.root;  
            Debug.Log(root);  
        }
    }
    

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_38

    するとConsoleウィンドウにRootが取得できた旨のログが出力されました。そこまでよく使う機能ではないですが、基本知識として 深い子階層からでもroot参照できる ことを覚えておきましょう。

    ここまで何度も登場している「MonoBehaviour」。MonoBehaviourはコンポーネントの一種で ゲーム開発の基盤 です。MonoBehaviourを正しく理解し使いこなすことで Unityでのゲーム開発効率を飛躍的にアップ させます。「まだMonoBehaviourについて理解できていないな」 と思われる方はこちらの記事がオススメ。

    MonoBehaviourを徹底解説しています。ぜひ読んでみてください。

    よく使うTransformテクニック9選

    Transformの基本をおさえたところで、次はよく使うTransformテクニックを紹介します。

    よく使うTransformテクニック9選

    ①Transformを指定した方向を向かせる「LookAt」

    ②Transformのアニメーション

    ③指定の軸と座標を中心に回転

    ④すべての子オブジェクトを取得する

    ⑤指定のTransformが親オブジェクトかチェック

    ⑥Hierarchy内のTransform数を取得

    ⑦親子関係を解除するDetachChildren

    ⑧スクリーン座標をワールド座標に変換するテクニック

    ⑨絶対座標におけるスケール値を取得する

    テク①Transformを指定した方向を向かせる「LookAt」

    ゲーム開発で指定の方向を向かせる場面はよく発生します。例えば敵が自分に対して弾を撃ってくるシーン。敵は自分を向いてから弾を撃ちますよね。一見、難しそうに感じますが簡単です。

    LookAt メソッドを使うと指定したオブジェクトに向く処理を簡単に実装できます。向かせたいTransformの Z方向がターゲットを向く のです。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_39

    サンプルコードはこちら。Unityちゃんにアタッチしています。
    _target 変数に球を指定。

    using UnityEngine;  
    public class LookAtTargetSample : MonoBehaviour  
    {
        // 視線を向かせるTransformをセット  
        [SerializeField] Transform _target;  
        void Update()  
        {
            transform.LookAt(_target);  
        }
    }
    

    実行するとこのようにUnityちゃんは球の方を向いてくれます。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_40

    LookAtは引数に 座標 を指定することもできます。

    💻ソースコード : 座標指定でLookAtの使用例
    // Vector3型の座標を指定することも可能  
    transform.LookAt(new Vector3(5, 0, -5));  
    

    座標指定のLookAtは上のような使い方です。

    テク②Transformのアニメーション

    Transformのアニメーションはゲーム開発では高頻度で登場します。どういったアニメーション方法があるのか解説していきます。

    Updateでアニメーション

    とてもシンプルなアニメーション方法です。等速直線運動させてみます。「等速直線運動」とは速度一定の動きです。サンプルとして一定区間を行ったり来たりするアニメーションを作ってみました。

    using UnityEngine;  
    public class TransformAnimationSample : MonoBehaviour  
    {
        float _dir = 1f;  
    
        void Update()  
        {
            var rangeX = 1.5f;  
            var speed = 2f;  
    
            var pos = transform.localPosition;  
            if (pos.x < -rangeX)  
            {
                // X座標が区間を越えたら方向を変える  
                _dir *= -1f;  
                pos.x = -rangeX;  
            }
            else if (pos.x > rangeX)  
            {
                // X座標が区間を越えたら方向を変える  
                _dir *= -1f;  
                pos.x = rangeX;  
            }
            // Unityちゃんの座標を更新  
            pos.x += speed * Time.deltaTime * _dir;  
            // 座標をUnityちゃんに反映  
            transform.localPosition = pos;  
        }
    }
    

    このソースコードをUnityで実行してみます。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_41

    するとUnityちゃんが一定区間を行ったり来たりするアニメーションの完成です。

    ソースコードの中で Time.deltaTime って何?と思った人もいると思います。アニメーションさせるときにはかなり重要な要素です。Updateでものを動かす場合はTime.deltaTimeを使う理由で解説しているため、ぜひこのまま読み進めていってください。

    AnimationClipでアニメーション

    最後にAnimationClipを使ったアニメーションの紹介。AnimationClipとはタイムライン風のAnimationウィンドウを使います。キーフレームを打ちながらアニメーションを作成します。

    感覚的にアニメーションが作れますし、プログラミング不要です。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_42

    AnimationClip、Animationウィンドウの使い方は、次の記事の「Animationウィンドウ」の章で解説していますので読んでみてください。

    DOTweenでアニメーション

    最後に「DOTween」を使ったアニメーションを紹介します。Unity外部の機能(無料)になるのですが、さまざまなゲーム開発で採用されています。DOTweenを使うと数行のコードで簡単にアニメーションを実装できます。

    using DG.Tweening;  
    using UnityEngine;  
    public class TweenAnimationSample : MonoBehaviour  
    {
        void Awake()  
        {
            var rangeX = 1.5f;  
            var speed = 2f;  
            // DOTweenで実装  
            transform.DOLocalMoveX(rangeX, speed).SetEase(Ease.Linear)  
                .SetLoops(-1, LoopType.Yoyo).SetSpeedBased(true);  
        }
    }
    

    Updateでアニメーションで紹介したサンプルプログラムは28行ありました。DOTweenを使うと13行まで減らせました。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_43

    また、Updateメソッドを使わないためとてもシンプルです。

    リアルなバウンドするアニメーション

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_44

    スローモーション

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_45

    氷山の一角ですがこのようなアニメーションが簡単に作れてしまうのがDOTweenの魅力です。詳しくはオオバが執筆した DOTweenの教科書がおすすめです。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_46

    そのまま使えるソースコードとアニメーション動画付き。全体文字数11万文字のボリューム満点の教科書です。 無料範囲だけでもDOTweenの基礎はガッチリ固められます 。ぜひ一度読んでみてください。いいねボタンを押してもらえると嬉しいです。

    テク③指定の軸と座標を中心に回転

    任意の座標を中心にものを回転させたくなる時があります。以下のような感じです。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_47

    そんなときは RotateAround を使用すると便利。

    準備

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_48

    回転の中心からUnityちゃんを離しておきます。今回の回転軸はY座標です。サンプルコードはこちら。

    using UnityEngine;  
    public class RotateAroundSample : MonoBehaviour  
    {
        void Update()  
        {
            // 回転の中心  
            var center = new Vector3(0, 0, 0);  
            // 回転軸(Y座標)  
            var axis = new Vector3(0, 1, 0);  
            // 毎フレーム回転する角度  
            var angle = 1;  
            transform.RotateAround(center, axis, angle);  
        }
    }
    

    RotateAround に「回転の中心座標」「回転軸」「回転スピード」をセットします。この処理をUpdateで毎フレーム実行することでアニメーションするのです。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_49

    さらにテク①Transformを指定した方向を向かせる「LookAt」と組み合わせると指定方向を向きながら回転処理をさせることもできます。面白いですよね。

    テク④子オブジェクトの取得

    使い方④Transformの階層化「SetParent」で解説したとおり、Transformは階層化できます。階層化した子オブジェクトを取得する機会はよくあります。本章では2つの子オブジェクトを取得する方法を紹介します。

    1階層下の子オブジェクトの取得

    1階層下の子オブジェクト、つまり実の子供の取得方法です。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_50

    transformをforeach文で回すことで、1階層下の子オブジェクトすべてを取得できます。

    using UnityEngine;  
    public class GetChildrenSample : MonoBehaviour  
    {
        private void Awake()  
        {
            // 1階層下の子部ジェクトをすべて取得  
            foreach(Transform tr in transform)  
            {
                Debug.Log(tr.name);  
            }
        }
    }
    

    上のコードのとおりTransformにforeachを使って子オブジェクトすべてを取得しています。よく使うテクニックなのでぜひ覚えておきましょう。

    Transformにforeachが使える理由

    パッと見、配列やリストに見えない「Transform」をforeachで回すことに違和感があるかもしれません。

    Transformクラスは「IEnumerableインターフェース」を継承しているためforeachで回せるのです。

    本記事ではこれ以上深く解説しませんが、IEnumerableを継承したクラスはforeachが使えるということを覚えておきましょう。

    もう1つの方法「GetChild」

    GetChild メソッドを使っても1つ下の階層オブジェクトを取得できます。引数に整数を代入して子オブジェクトを取得します。

    その数字とは、Hierarchyウィンドウ上の順番です。具体的には以下の図です。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_51

    Parentから見て上の方が数字が小さくなります。

    1番目の子オブジェクトはプログラムでは「 0 」を指定することに注意です。

    💻ソースコード : GetChildのサンプル
    void Awake()  
    {
        // 2番目の子オブジェクトを取得する  
        Transform child = transform.GetChild(1)  
    }
    

    もう1つ注意点。下図では3つの子オブジェクトが存在します。そこで GetChild(3) と存在しない子オブジェクトを参照しようとするとどうなるか。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_52

    結論エラーです。

    UnityException: Transform child out of bounds  
    

    このようなエラーが出力されてプログラムが止まります。

    子オブジェクトの数を取得「childCount」で紹介する childCount を使って子オブジェクトの数を取得しながらGetChildを使うとよいです。

    子オブジェクトすべて取得

    GetComponentsInChildren を使うことで自分を含めて子階層すべてを取得できます。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_53

    自分を含め子階層すべてのTransformを取得するサンプルコードはこちら。

    using UnityEngine;  
    public class GetChildrenSample : MonoBehaviour  
    {
        private void Awake()  
        {
            var children = GetComponentsInChildren<Transform>();  
            foreach(Transform tr in children)  
            {
                Debug.Log(tr.name);  
            }
        }
    }
    

    もし自分自身を除外した子階層すべてを取得したい場合は、以下のように自分自身を除外する処理を書いてください。

    using UnityEngine;  
    public class GetChildrenSample : MonoBehaviour  
    {
        private void Awake()  
        {
            var children = GetComponentsInChildren<Transform>();  
            foreach(Transform tr in children)  
            {
                // 自分自身を除外する  
                if (tr != transform) {  
                    Debug.Log(tr.name);  
                }
            }
        }
    }
    

    テク⑤指定のTransformが親オブジェクトかチェック

    指定のTransformが自分自身の親なのかチェックしたい時があります。 IsChildOf を使うと簡単です。

    下の図は実行者(Executor)がIsChildOfを使った際の判定範囲です。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_54

    ピンクの枠内のオブジェクトはtrueを返します。 自分自身IsChildOfで比較してもtrue が返ってくることに注意です。

    using UnityEngine;  
    public class IsChildOfSample : MonoBehaviour  
    {
        [SerializeField] Transform _checkTransform;  
        void Awake()  
        {
            transform.IsChildOf(_checkTransform);  
        }
    }
    

    ↑サンプルコードはこちら。

    テク⑥Hierarchy内のTransform数を取得

    今どのくらいのTransformを使っているのか調べたくなることがあります。本章ではHierarchy内の Transform数の取得方法 を紹介します。

    Transforom数の全取得「hierarchyCount」

    hierarchyCount を使用すると所属するTransformの数を取得できます。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_55

    上図の例ではTransformは8個存在します。

    💻ソースコード : hierarchyCountのサンプル
    using UnityEngine;  
    public class HierarchyCountSample : MonoBehaviour  
    {
        void Awake()  
        {
            Debug.Log(transform.hierarchyCount);  
        }
    }
    

    上のコードを実行すると「8」が出力されます。

    子オブジェクトの数を取得「childCount」

    childCountを使うと1階層下の子オブジェクトの数が取得できます。以下のようなイメージです。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_56

    子オブジェクトは3つです。

    💻ソースコード : childCountのサンプル
    using UnityEngine;  
    public class ChildCountSample : MonoBehaviour  
    {
        void Awake()  
        {
            Debug.Log(transform.childCount);  
        }
    }
    

    このプログラムを実行すると「3」が出力されます。

    テク⑦親子関係を解除するDetachChildren

    親子関係を操作するときに使えるテクニック DetachChilren を紹介します。DetachChildrenを使うとオブジェクトを解除できます。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_57

    動画のとおり子オブジェクト全てを子供から外すことができます。

    💻ソースコード : DetachChildrenのサンプル
    using UnityEngine;  
    public class GetChild : MonoBehaviour  
    {
        void Awake()  
        {
            transform.DetachChildren();  
        }
    }
    

    あまり頻出するテクニックではありませんが、こんな機能もあるんだなくらいの温度感で覚えておくとよいかと思います。

    テク⑧スクリーン座標を絶対座標に変換するテクニック

    座標にはいくつか種類があります。スクリーン座標とは画面の座標。分かりやすく言えば「マウス座標」です。例えば以下のようなペイントアプリを作ってみます。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_58

    マウス座標に追随して絶対座標上にメッシュを生成しているのです。

    👉 【Unity】ペイントアプリのようなメッシュの作り方

    ここで重要なのは 「座標変換」 。TransformとCameraを使うことでスクリーン座標を絶対座標に変換できます。詳しくはこちらの記事で解説していますので、読んでみてください。

    テク⑨絶対座標におけるスケール値を取得する「lossyScale」

    深い階層にあるオブジェクトの絶対座標におけるスケールを取得したくなるときがあります。具体的には次のような場合です。各階層でスケール値を変更しています(分かりやすくGameObject名にスケール値を記載)。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_59

    深い階層にあるUnityChan_Bが実際にどう見えるでしょうか?

    ※ちなみにUnityちゃん自体はスケール1

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_60

    UnityChan_A1倍 のまま。 UnityChan_B は各階層のスケールを乗算した結果 1.8倍 になります。このスケール1.8は、 lossyScale を使うと簡単に取得できるのです。

    💻ソースコード : lossyScaleのサンプル
    using UnityEngine;  
    public class LossyScaleSample : MonoBehaviour  
    {
        void Awake()  
        {
            // 絶対座標上でのスケール  
            Debug.Log(transform.lossyScale);  
        }
    }
    

    このコンポーネントをUnityChanBにアタッチします。すると「1.8」が出力されます。各階層でスケールを調整する必要があり、絶対座標上でのスケール値を取得したいときに _lossyScale が活躍します。ぜひ覚えておきましょう。

    パフォーマンスを意識したTransformの使い方

    Unity開発しているとTransformの使い方1つで負荷が大きく変わることがあります。本章ではパフォーマンスを意識したTransformの使い方について解説します。 ちょっとした意識の積み重ねが完成時のゲームパフォーマンスを大きく変える のです。

    Transformはキャッシュして使う

    Transformにアクセスする方法は gameObject.transform または transsform でした。しかし、この方法は毎度 GetComponent<Transform> をしているのと同じ。

    つまり毎回 GetComponent の負荷を積み上げているのです。アクセス頻度が低いのであれば問題ありません。しかし、Transformは Update で毎フレームアクセスすこともありますよね。そんなときは キャッシュ して使うと良いです。

    💻ソースコード : Transformをキャッシュしていない例
    using UnityEngine;  
    public class LookAtPosSample : MonoBehaviour  
    {
        void Update()  
        {
            transform.Translate(new Vector3(0, 0, 1f));  
        }
    }
    
    💻ソースコード : Transformをキャッシュした例
    using UnityEngine;  
    public class LookAtPosSample : MonoBehaviour  
    {
        private Transform _cachedTransform;  
        void Awake()  
        {
            // Transformインスタンスをキャッシュする  
            _cachedTransform = transform;  
        }
    
        void Update()  
        {
            _cachedTransform.Translate(new Vector3(0, 0, 1f));  
        }
    }
    

    一度 _cachedTransform 変数にAwakeのタイミングでキャッシュ。Update内ではキャッシュしたTransformにアクセスするのです。すると負荷自体は0になります。

    もちろん、通常の使用では普通に transform アクセスで問題ありません。大量のTransformが存在し、毎フレームアクセスしているといった状況で初めて効果のあるテクニックであることを覚えておいてください。

    TransformはGetComponentを使っていない

    実は「transform」、「gameobject.transform」は内部でGetComponent<Tranform>を使っていません。Unity内部では最適化された ”Transform専用の取得関数” が用意されています。もちろんGetComponent<Transform>でもTransformを取得できます。しかし「transform」、「gameobject.transform」を使った方がGetComponent<Transform>よりパフォーマンスはよいのです。

    ただし、いくら最適化したとしてもTransformのキャッシュ利用にはかないません。Transformにアクセスするときの最適な方法はTransformをキャッシュして使うことなのです。

    位置と回転同時に更新するときはSetPositionAndRotationを使用

    移動と回転を同時に実行する場合は、 SetPositionAndRotation を使いましょう。transform.localPositiontransform.localRotation とそれぞれ処理を書いてしまいがちです。しかしそれは良くない方法です。移動と回転を同時に実行する場合は、以下の通り SetPositionAndRotationメソッド を使いましょう。

    transform.SetPositionAndRotation(  
        new Vector3(1, 0, 0),  
        Quaternion.AngleAxis(30, new Vector3(0, 1, 0))  
    );  
    

    メリットは負荷軽減です。移動、回転それぞれ処理を書くよりパフォーマンスは良くなります。

    hierarchyCapacityでパフォーマンスアップ

    ゲーム中のTransformの階層が決まっている場合、 hierarchyCapacity を指定することでパフォーマンス向上が期待できます。

    void Awake()  
    {
        transform.hierarchyCapacity = 10;  
    }
    

    上記はTransformの階層を10までと指定したサンプルコードです。

    ※10以上越えたとしても警告は出ますがゲームは動きます

    なんのパフォーマンスがあがるのか、というとメモリ消費量です。公式リファレンスによるとSetParent、Destroyのパフォーマンスも向上するようです。

    📚 参考サイト : Transform-hierarchyCapacity - Unity スクリプトリファレンス

    Unityエディタ上で20階層ほどのTransformで検証しました。しかし、SetParentのCPU負荷に変化はありませんでした。階層の浅いTransformではあまり効果はないのかもしれません。

    positionはlocalPositionより負荷が高くなる

    とても細かい話ですが知っておかないと損するお話。 TransformのpositionはlocalPositionより負荷が高い です。下図はposition、localPositionへのアクセス負荷を計測したものです。positionはlocalPositionに比べて 負荷が約2倍 です。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_61

    枠で囲った数字は、1フレーム処理するためにかかったミリ秒数。positionは 15.33ミリ秒 。localPositionは 7.14ミリ秒 かかっています。2倍も多くかかる理由は Transformの階層数 に関係しています。

    浅い階層では、以下の通りpositionとlocalPositionの負荷の差はほぼありません。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_62

    Transformの階層が深くなると顕著にpositionの負荷は高くなる のです。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_63

    もちろん、今回のサンプルは10万回position、localPositionにアクセスした負荷なので、通常使用においては気にしなくて大丈夫です。もし 大量のTransform のpositionにアクセスする必要がある場合は、意識してみてください。サンプルコードはこちらです。

    using UnityEngine;  
    using UnityEngine.Profiling;  
    
    public class Perfomance : MonoBehaviour  
    {
        CustomSampler localPosSampler;  
        CustomSampler posSampler;  
        public int n = 100000;  
        private void Awake()  
        {
            localPosSampler = CustomSampler.Create("### LocalPosition ###");  
            posSampler = CustomSampler.Create("### Position ###");  
        }
    
        void Update()  
        {
            localPosSampler.Begin(this);  
            for(int i = 0; i < n; i++)  
            {
                var localpos = transform.localPosition;  
            }
            localPosSampler.End();  
    
            posSampler.Begin(this);  
            for (int i = 0; i < n; i++)  
            {
                var pos = transform.position;  
            }
            posSampler.End();  
        }
    }
    

    Transformの注意点

    Transformの基本的な使い方からよく使うテクニック、パフォーマンスを意識した話と網羅的に解説してきました。最後にTransformを使う上での注意点を紹介します。

    InspectorウィンドウのPositionはlocalPosition

    勘の良い人はすでに気づいていると思いますが、InspectorウィンドウのPositionは相対座標、つまりlocalPositionです。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_64

    また、Rotationも同様、親基準の角度です。そして、Rotationと記述していますが、Inspectorウィンドウ上では「EulerAnglesの値」です。Quternionではありません。

    Unityは左手座標系

    ところで Unityは左手座標系 です。左手座標系とは左手の「親指をX軸」「人差し指をY軸」「中指をZ軸」にあわせたとき、
    指先に向かうほど値が大きくなる座標系です。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_65

    つまり、X軸は右に行くほど、Y軸は上に行くほど、Z軸は奥に行くほど値は大きくなります。MayaやBlenderといった3DソフトとUnityを連携したときに、座標系が違う場合があるため注意が必要です。

    Transform.Findはおすすめしない理由

    子階層Transformを取得する方法はもう1つあります。文字列を指定した方法です。

    transform.Find("a/b/c");  
    

    このような感じでGameObject名を指定します。 「/(スラッシュ)」 は階層です。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_66

    オオバ的にTransform.Findの使用はおすすめしません。次の記事で詳しく解説していますのでぜひ読んでみてください。

    Updateでものを動かす場合はTime.deltaTimeを使う理由

    Updateとは毎フレーム固定の秒数使っているわけではありません。ゲームをプレイしている「カクつき」を経験したことがあると思います。これは、Updateが毎フレーム固定ではない証拠です。フレームレート30のゲームだったら、30より下になるとカクつきを感じます。

    カクつく原因は負荷です。重い処理を実行することでUpdateの実行タイミングは遅れるのです。遅れること自体は仕方なく、そのために今回紹介する「Time.deltaTime」が活躍します。

    Time.deltaTimeとは、Updateにかかった時間です。つまり1フレームにかかった時間という理解で大丈夫。

    サンプルコードを見てみましょう。Transformを毎フレーム1メートル処理です。このままでも動きはしますが正しくはありません。

    void Update()  
    {
        transform.localPosition += new Vector3(1, 0, 0);  
    }
    

    ↓正しくはこちら。

    void Update()  
    {
        transform.localPosition += new Vector3(1, 0, 0) * Time.deltaTime * 30;  
    }
    

    * Time.deltaTime * 30 が追加されています。この「30」というのはフレームレートです。Application.targetFrameRate = 30; で指定可能です。Time.deltaTime は先ほどの説明のとおり、フレームにかかった時間です。この計算式によって、カクつきなどでフレーム時間が遅くなっても意図した位置にTransformを移動させることができるのです。

    毎フレーム移動させる公式
    1フレームで移動させたい距離 * Time.deltaTime * フレームレート;  
    

    毎フレーム移動させたい場合の移動公式です。重要なのはTime.deltaTime。ぜひ覚えておきましょう。

    TransformアクセスにGetComponentは使うな

    コンポーネントにアクセスする際、 GetComponent を使います。しかし、Transformに関しては特別で、直接transformとアクセスするのがおすすめです。

    // ×  
    gameObject.GetCpomponent<Transform>()  
    

    // ◯  
    gameObject.trasform  
    

    理由はパフォーマンスです。次の図は大量のTransformにアクセスした負荷を計測したものです。

    【Unityの基本】Transformを徹底解説「移動」や「回転」だけじゃない_67

    GetComponentよりtransformの方が 3倍早い のです。これはUnityがTransformに最適化をしているため。

    実際にTransformは内部的に専用の取得メソッドが呼ばれています。Transformにアクセスする際は、GetComponentではなく「transform」を使ってみてください。

    FixedUpdateで動かしてはいけない

    最初に結論、FixedUpdateでTransformを動かしてはいけません。「ドキ!!」とびっくりした人もいるかも知れません。 FixedUpdateは物理演算処理で使うために用意されたイベント関数 です。Unityのイベント関数内で更新型のメソッドは3つあります。

    この中で、FixedUpdateは 0.02秒 ごとに一定の間隔で実行されます。

    画面を更新するスピードをフレームレートやFPSと言います。例えばフレームレート30の場合、1秒に30回画面を更新することになるのです。仮にフレームレート30のゲームの場合、1フレーム0.03秒。イベント関数Updateは0.03秒に1回実行されるのです。2フレームで0.06秒ですね。

    一方FixedUpdateは0.02秒に1回実行するため、Updateが2フレーム実行したら3回実行してしまうのです。(0.06秒 ÷ 0.02秒 ≒ 3回)。

    FixedUpdateはフレームレートとは別軸でタイムを刻んでいる ということです。つまり、FixedUpdateでTransformを動かしてしまうと意図しないアニメーションになります。本来1フレーム分動かしたい処理が2回走ってしまうこともあり、動きがずれてしまうのです。

    結論、 FixedUpdateは物理演算系の処理に使いましょう。

    Unity Transformのまとめ

    Transformについて徹底的に解説してきました。この記事を簡単にまとめます。

    Transformまとめ

    ①Transformとはゲーム開発に必須コンポーネント

    ②TransformはすべてのGameObjectにセットされている

    ③Transformの重要機能4種「移動」「回転」「拡大縮小」「階層化」

    ④よく使うTransformテクニック9つを紹介

    ⑤使い方しだいでTransformのパフォーマンスは変わる

    こんな感じです。

    普段何気なく使っているUnityの移動や回転は、Transformの機能を使っているということがわかったと思います。 ゲーム開発にTransformは必須 です。つまりTransformの正しい使い方を理解することはゲーム開発にとって超重要だということです。

    1回読んだだけでは理解できなかった部分もあると思います。ぜひこの記事をブックマークして、何度も読み返してみてください。同時にUnityを動かしてみましょう。効率の良い学び方はインプットしながらアウトプットすること です。ぜひ、この記事を片手にUnityを動かしてTransformの理解を深めてみてください。

    この記事があなたの人生を豊かにする手助けになるとうれしいです。

    「Unity初心者大学」というUnity初心者向けのYouTube始めました!!
    ぜひチャンネル登録をお願いします!

    最後まで読んでいただきありがとうございました!
    すばらしいUnityライフをお過ごしください。

    オススメ記事
    検証環境