Unityの transform.Rotate() と GetComponent<Transform>().Rotate() は何が違う?

広告

この記事は、北村愛実 著『Unityの教科書 Unity 6完全対応版』(SBクリエイティブ)で扱われているルーレット(第3章)のコードを題材に、授業でつまずきやすい点を補足するために作成した学習記事です。コードおよび制作手順の詳細は、書籍もあわせてご参照ください。

Unityでルーレットを回転させるコードを書いていると、次のような1行が出てきます。

// 回転速度ぶん、ルーレットを回転させる
transform.Rotate(0, 0, this.rotSpeed);

ところが、Unityでは次のように書いても、ほぼ同じことができます。

GetComponent<Transform>().Rotate(0, 0, this.rotSpeed);

では、この2つは何が違うのでしょうか。この記事では、この短いコードを材料にして、UnityとC#の基本的な考え方を整理していきます。

ルーレットそのものの作り方は、こちらの記事で解説しています。
Unity 6でルーレットを作る ― クリックで回して、だんだん止める仕組み(PC版)

この記事で分かること

  • 小文字の transform の正体
  • GetComponent<Transform>() が何をしているか
  • Component(コンポーネント)とは何か
  • なぜ普段は transform.Rotate() と書けばよいのか
  • メソッドの戻り値に続けて . で呼び出す書き方
項目内容
対象Unity・C#を学び始めたばかりの方
前提Update の中で transform.Rotate() を書いたことがある
UnityUnity 6(バージョンに依存しない基本内容です)

1. まずは transform.Rotate() を読む

最初のコードはこちらです。

transform.Rotate(0, 0, this.rotSpeed);

一気に理解しようとせず、.(ドット)の前と後ろの2つに分けてみます。

部分意味
transform何に対して
Rotate(0, 0, this.rotSpeed)何をするか

つまり「transform に対して Rotate を実行する」というコードです。Rotate は「回転させる」という意味なので、全体としては次のように読めます。

このGameObjectのTransformを
Z軸まわりに rotSpeed ぶん回転させる

2. Transformとは何だったか

UnityのGameObjectには、必ず Transform が付いています。Transformには主に次の情報が入っています。

  • 位置(Position)
  • 回転(Rotation)
  • 大きさ(Scale)

Inspectorを見ると、GameObjectのいちばん上にある、おなじみの項目です。

Transform
  Position
  Rotation
  Scale

つまり、Inspectorで見ているこのTransformを、C#から操作しているわけです。transform.Rotate(0, 0, this.rotSpeed); は、そのTransformのRotation(回転)を変更しています。

3. では小文字の transform は何?

ここが今回いちばん重要なところです。

小文字で始まる transform はクラス名ではありません。大文字の Transform がクラス(型)の名前で、小文字の transform は、このGameObjectのTransformを取り出すためにUnityが用意してくれているプロパティです。

書き方正体
Transformクラス(型)の名前
transformこのGameObjectのTransformを返すプロパティ

そのため transform.Rotate(...) と書けば、このスクリプトが付いているGameObjectのTransformを操作できます。イメージとしては次の流れです。

このスクリプトが付いているGameObject
        ↓
     Transform
        ↓
      Rotate()

4. GetComponent<Transform>() でも取得できる

一方、もう1つのコードを見てみましょう。

GetComponent<Transform>().Rotate(0, 0, this.rotSpeed);

まずは前半の GetComponent<Transform>() だけに注目します。これは「このGameObjectから、TransformというComponentを取得する」という意味です。

UnityのGameObjectは、いろいろなComponent(部品)を組み合わせて作られています。

GameObject
 ├ Transform
 ├ Sprite Renderer
 ├ Rigidbody 2D
 ├ Collider 2D
 └ 自分で作ったスクリプト

その中から、GetComponent<Transform>() によってTransformを探して取得するわけです。

イラスト:GameObjectのComponentの中で、transformプロパティとGetComponent<Transform>()がどちらも同じTransformにたどり着く様子

5. 日本語っぽく読んでみよう

初学者のうちは、コードを英語のまま丸暗記するより、日本語っぽく分解すると理解しやすくなります。

コード読み方
Get取得する
Componentコンポーネントを
<Transform>Transformという種類の

つなげると「TransformというComponentを取得する」です。その後ろに .Rotate(0, 0, this.rotSpeed) が続くので、コード全体は次の流れになります。

Transformを取得する
        ↓
取得したTransformのRotateを呼び出す
        ↓
回転する

< > の中に型を書いて「どの種類か」を指定するこの書き方は、C#のジェネリックメソッドという仕組みです。<T> の意味をもっと知りたい方は、こちらの記事をどうぞ。
ジェネリックメソッドとは?―「型だけ違う同じ処理」を1つにまとめよう【C#入門】

6. 実は、この2つは同じものを操作している

ここまで来ると、2つのコードの関係が見えてきます。どちらもこのスクリプトが付いているGameObjectのTransformを使って回転させています。違うのは、Transformをどう取得しているかだけです。

書き方1:transform プロパティを使う

transform.Rotate(0, 0, this.rotSpeed);

Unityが用意している transform プロパティを使っています。

書き方2:GetComponent で取得する

GetComponent<Transform>().Rotate(0, 0, this.rotSpeed);

GetComponent を使って、明示的にTransformを取得しています。

書き方1書き方2
コードtransform.Rotate(...)GetComponent<Transform>().Rotate(...)
Transformの取り出し方専用のプロパティComponentを探して取得
短さ・読みやすさ◎△
回転の結果同じ同じ

7. では、どちらを使えばいい?

Transformを使うだけなら、通常はこちらで十分です。

transform.Rotate(0, 0, this.rotSpeed);

短くて読みやすいからです。わざわざ GetComponent<Transform>() と書く必要はありません。

ただし、GetComponent を学ぶ意味は大いにあります。なぜなら、Transform以外のComponentでは頻繁に使うからです。たとえば次のように書くと、このGameObjectに付いている Rigidbody2D や AudioSource を取得できます。

Rigidbody2D rb = GetComponent<Rigidbody2D>();
AudioSource audioSource = GetComponent<AudioSource>();

ワンポイント:GetComponent は Start で1回だけ

GetComponent は、GameObjectに付いているComponentの中から目的のものを探す処理です。Update の中で毎フレーム呼ぶと、そのたびに探すことになります。何度も使うComponentは、Start で1回だけ取得して変数に入れておくのが定番の書き方です。

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    Rigidbody2D rb;   // 取得したComponentを入れておく変数

    void Start()
    {
        // 最初に1回だけ取得しておく
        rb = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        // 以降は変数を使い回す
        rb.AddForce(Vector2.right);
    }
}

なお、transform は最初から用意されているプロパティなので、このような準備は不要です。そのまま transform.Rotate(...) と書いて大丈夫です。

8. GetComponent が分かるとUnityの考え方が見えてくる

Unityでは、GameObjectに機能を付けるときにComponentを追加していきます。たとえばプレイヤーなら、次のように複数のComponentを組み合わせます。

Player
 ├ Transform
 ├ SpriteRenderer
 ├ Rigidbody2D
 ├ Collider2D
 └ PlayerController

そしてスクリプトから GetComponent<Rigidbody2D>() などを使って、必要なComponentを取得して操作します。

つまり GetComponent は単なる命令ではなく、Unityの「GameObject + Component」という仕組みを理解する入口でもあります。

9. 「メソッドが返したもの」に続けてメソッドを呼べる

もう1つ、C#として大事なことがあります。GetComponent<Transform>().Rotate(...); をよく見ると、GetComponent<Transform>() の直後に .Rotate(...) が付いています。なぜこんな書き方ができるのでしょうか。

GetComponent<Transform>() は、実行するとTransformを返します(戻り値)。そのため、次の2行と同じように考えることができます。

Transform t = GetComponent<Transform>();   // Transformを受け取る
t.Rotate(0, 0, this.rotSpeed);              // 受け取ったTransformを回す

つまり GetComponent<Transform>().Rotate(0, 0, this.rotSpeed); は、この2行を1行にまとめて書いた形です。初学者のうちは、2行に分けたほうが流れを追いやすいかもしれません。

イラスト:GetComponent<Transform>()が返したTransformに対して.Rotate()を呼ぶ流れと、「.」を「の」と読む考え方

10. . の意味にも注目しよう

今回のコードには . が何度も登場します。C#の . は、日本語の「〇〇の△△」と読むと分かりやすくなります。

コード読み方
transform.Rotate(...)transform の Rotate
GetComponent<Transform>().Rotate(...)GetComponent<Transform>() で取得したもの の Rotate
player.Move();player の Move
textBox1.TexttextBox1 の Text

UnityでもWinFormsでも、この . の読み方に慣れると、コードがずっと読みやすくなります。

11. ルーレットの1行から、実はいろいろ学べる

最初はただの transform.Rotate(0, 0, this.rotSpeed); という1行でした。しかし少し掘り下げてみると、次のようなC#とUnityの考え方がたくさん入っていました。

  • GameObject
  • Component
  • Transform
  • プロパティ
  • メソッド
  • GetComponent<T>()
  • 戻り値
  • . によるメンバーへのアクセス

コードを覚えるだけなら、transform.Rotate(...); をそのまま入力すれば動きます。しかし「なぜこれで動くのだろう?」と一度立ち止まって考えることで、別のコードを見たときにも応用できる知識になっていきます。

まとめ

コード考え方
transformこのGameObjectのTransformを使うために、Unityが用意している便利な入口(プロパティ)
GetComponent<Transform>()このGameObjectから、Transform Componentを探して取得するメソッド
  • どちらも、このGameObjectのTransformを使って回転させている
  • 普段Transformを操作するときは transform.Rotate(...) で十分
  • GetComponent は、Rigidbody2DやAudioSourceなど他のComponentを使うときの基本
  • 何度も使うComponentは Start で1回だけ取得して変数に入れておく

GetComponent<Transform>() という書き方を一度理解しておくと、次のようなコードを見たときにも読めるようになります。

GetComponent<Rigidbody2D>()
GetComponent<AudioSource>()
GetComponent<Animator>()

GameObjectについているComponentを取得しているんだな

ルーレットを回転させるたった1行ですが、ここにはUnityの基本的な設計思想がかなり詰まっています。

参考書籍

北村愛実 著
『Unityの教科書 Unity 6完全対応版』
SBクリエイティブ
書籍サポートページ(サンプルファイル)

本記事では、書籍で扱われているルーレット(第3章)のコードを題材に、初学者向けの補足説明を加えて解説しています。

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

広告

C#,Unity,初学者

Posted by hidepon