【Unity】座標を取得するtransform.positionとは?

Unity

こんにちは、ともくんのゲーム作り部屋にようこそ!

このページでは、

「Unityでオブジェクトの座標を取得したいんだけど、どうやってやればいいのか分からない!」

「キャラクターが移動しすぎてしまって困っている。」

というお悩みの方に向けた内容となっています。

Unityでゲームを作っていると、キャラクターがこの位置にきたら処理を行いたいということがよくありますが、それを実現するのが「transform.position」という変数です。

Unityでは、ゲームのオブジェクト毎にTransfomコンポーネントというところで位置に関する情報が管理されていて、その中にあるpositionという変数によって座標データは保管されています。

そのため、特定の座標になったら処理を行うという場合は、スクリプト内でtransform.positionを使って座標を取得しておく必要があります。

そこで、このページでは、オブジェクトの座標を取得することができる「transform.position」について、どんな変数なのか、取得する方法や実際の利用例、また注意点までを紹介していきます。

なお、このページでは、

Windows11
Unity Hub3.11.0
Unity6

のバージョンで解説しています。

この記事を書いた人

ゲーム作りを学び始めた一児のパパです。
このブログは、子供から「ゲームを作ってみたい!」と言われ、非プログラマーでゲーム作りをしたことない僕が、ゲーム作りの本を読んで独学でゲーム開発を学んでいるブログです。
同じように初めてゲーム作りをしている方と一緒に学んでいけるようなブログに出来たらいいなと思っています。
また、「このコードはおかしい」とか「もっと良い書き方があるよ!」などあれば、どんどん指摘して頂けると助かります。

transform.positionとは?座標が取得できるようになる

まずは、

をまとめていきます。

座標や回転を管理するTransformコンポーネント

transform.positionの頭のtransformという部分は、Transformコンポーネントのことを指しています。

Transformコンポーネントとは、そのオブジェクトの座標や回転、大きさを管理しているコンポーネントで、シーンビューに配置したオブジェクトは、自動的にこのTransformコンポーネントが付いていて、インスペクターウィンドウでそれぞれの座標や回転情報を見ることができます。

スクリプトでこのTransformコンポーネントの値を参照する際は、「transform」と書きます。

通常、コンポーネントを参照する場合、GetComponent(コンポーネント名)と書く必要がありますが、このTransformコンポーネントだけは「transform」という変数が準備されているので、その必要がありません。

座標を管理している変数がposition

このTransformコンポーネントの中で、座標を管理している変数が「position」になっています。

コンポーネントには、様々な変数やメソッドが準備されていて、コンポーネントを呼び出した後に、これらの変数やメソッドを書いてあげることで、その情報を取得したり処理を行うことができます。

そのため、Transformコンポーネントの中で座標を管理しているposition変数の情報を取得するために、「transform.position」という書き方をしています。

座標はVector3型で保存されている

このtransform.positionですが、座標をVector3という型で保存しています。

Vector3型とは、三次元の位置を表すために使われている型で、座標は(x, y, z)という形で、以下の3つの変数をまとめて保管しています。

そのため、それぞれの軸ごとの座標を見たい場合は、transform.position.xtransform.position.yなどのように書くことで、取得することができます。

transform.positionで座標を取得する方法

transform.positionで座標を取得する場合に、

・スクリプトにアタッチしているオブジェクトを移動させるのか?
・スクリプトにアタッチしていないオブジェクトを移動させるのか?

によって、そのスクリプトの書き方が変わってきます。

なお、スクリプトのアタッチがよく分からない方は、以下のページを参考にしてみてください。

アタッチされているオブジェクトの座標を取得する場合

スクリプトに直接アタッチしているオブジェクトの座標を取得したい場合は、以下のように書いてあげることで、簡単に取得することができます。

ゲーム実行開始時点の座標をコンソールウィンドウに表示しています。

using UnityEngine;

public class Test : MonoBehaviour
{
    Vector3 myPosition;	// Vector3型の変数を作成
    void Start()
    {
        myPosition = transform.position;	// 座標を取得して変数に代入
        Debug.Log("X座標は" + myPosition.x + "です");
        Debug.Log("Y座標は" + myPosition.y + "です");
        Debug.Log("Z座標は" + myPosition.z + "です");
    }
}
コンソール画面の表示結果例

X座標は2.27です
Y座標は-3.1です
Z座標は10です

(表示結果は例です)

Vector3型myPosition変数を作り、Startメソッドの中でtransform.positionを代入して、X・Y・Zの座標をそれぞれx・y・zの変数で取得しています。

アタッチされていないオブジェクトの座標を取得する場合

スクリプトに直接アタッチしていないオブジェクトの座標を取得する場合は、以下のようにFindメソッドを使ってオブジェクト名から探してくる必要があります。

GameObject.Find(“オブジェクト名”)

そして、そのオブジェクトのTransformコンポーネントにアクセスしていくことになるので、例えばオブジェクト名を「dog」とした場合、

using UnityEngine;

public class Test : MonoBehaviour
{
    Vector3 myPosition;	// Vector3型の変数を作成
    void Start()
    {
        myPosition = GameObject.Find("dog").transform.position;	// 「dog」の座標を取得して変数に代入
        Debug.Log("X座標は" + myPosition.x + "です");
        Debug.Log("Y座標は" + myPosition.y + "です");
        Debug.Log("Z座標は" + myPosition.z + "です");
    }
}

と書いてあげることで、アタッチしていないオブジェクトの座標を取得することができます。

Unityでtransform.positionを使った使用例

ここからは、実際にUnityでtransform.positionを使った例を紹介していきます。

例①特定の座標にキャラクターが来た時の処理

アクションゲームやシューティングゲームなどで、特定の座標にキャラクターが来た際に処理を行いたい、という場合のスクリプトです。

今回は、

キャラクターのY座標が1以上になると背景が赤色に、-1以下になると青色に、それ以外は白色になる

というスクリプトを書いてみます。

以下は、背景用においたオブジェクトにアタッチしているスクリプトです。

using UnityEngine;

public class BackgroundColor : MonoBehaviour
{
    Vector3 playerPosition; // Vector3型の変数を作成
    SpriteRenderer spriteRenderer;  // SpriteRendererコンポーネントを参照

    void Start()
    {
        spriteRenderer = GetComponent<SpriteRenderer>();    // SpriteRendererを取得する
    }

    void Update()
    {
        playerPosition = GameObject.Find("player").transform.position;  // プレイヤーの座標を変数に代入する

        if (playerPosition.y >= 1)          // Y座標が1以上の場合
        {
            spriteRenderer.material.color = Color.red;       // 赤色に変更
        }
        else if (playerPosition.y <= -1)    // Y座標が-1以下の場合
        {
            spriteRenderer.material.color = Color.blue;     // 青色に変更
        }
        else                                // それ以外の場合
        {
            spriteRenderer.material.color = Color.white;    // 白色に変更
        }
    }
}

15行目でスクリプトがアタッチしていないキャラクターの座標を取得したいので、GameObject.Find(“player”)でプレイヤーを探してきます。

なお、キャラクターの座標は常に取得しないといけないので、Updateメソッドに記載しています。

そして、17行目以降でplayerPositionという変数にプレイヤーの座標を代入して、if文でY座標による条件ごとの色が変わる処理を書いています。

これでプレイヤーのY座標の条件によって、処理を変更することができました。

例②キャラクターの移動を制限する際の処理

キャラクターが自由に操作できる場合に、ゲームの画面外に行くのを防ぐための移動制限を加える際にも、transform.positionは使えます。

今回は、キャラクターに直接スクリプトをアタッチしています。

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    float playerSpeed = 0.02f;   // float型のplayerSpeed変数を作成し0.02を代入
    Vector3 playerPosition; // Vector3型の変数を作成

    void Update()
    {
        playerPosition = transform.position;    // 座標を取得して変数に代入

        if (Input.GetKey(KeyCode.W) &&  // Wキーを押しているかどうか
            playerPosition.y <= 4)      // Y座標が4以下のとき
        {
            transform.Translate(0, playerSpeed, 0); // Y座標をプラス側に移動させる
        }

        if (Input.GetKey(KeyCode.A) &&  // Aキーを押しているかどうか
            playerPosition.x >= -7.2f)      // X座標が-7.2以上のとき
        {
            transform.Translate(-playerSpeed, 0, 0); // X座標をマイナス側に移動させる
        }

        if (Input.GetKey(KeyCode.S) &&  // Sキーを押しているかどうか
            playerPosition.y >= -4)     // Y座標が-4以上のとき
        {
            transform.Translate(0, -playerSpeed, 0); // Y座標をマイナス側に移動させる
        }

        if (Input.GetKey(KeyCode.D) &&  // Dキーを押しているかどうか
            playerPosition.x <= 7.2f)     // X座標が7.2以下のとき
        {
            transform.Translate(playerSpeed, 0, 0); // X座標をプラス側に移動させる
        }
    }
}

先ほどと同じく、playerPositionという変数にプレイヤーの座標を代入して、プレイヤーの移動処理に対して条件を追加しています。

プレイヤーの移動は、transform.Translateを使ってWASDキーで移動するようにしています。

なお、transform.Translateについては、以下の記事も参考にしてみてください。

これでカメラ外の座標に行こうとすると、WASDの移動キーを押しても移動しないようにできました。

transform.positionを使う際の注意点

transform.positionは座標を取得することができ、その座標に合わせて処理を行えることが分かりましたが、transform.positionにはいくつか注意点があります。

それぞれの座標を直接加算・減算して変更できない

transform.positionがオブジェクトの座標を取得できるのであれば、transform.positionの座標の値に直接加算したり減算したり変更できるのではないかと思ってしまいます。

例えば、プレイヤーのX座標を2だけ動かしたいという場合に、

transform.position.x += 2;

とだけ書きたいところですが、エラーが発生してしまいます。

どうやらアクセス修飾子の関係で、直接このような加算や減算は行えなくなっているようです。

そこで、以下のように一度Vector3型の変数(myPositionなど)に代入して、X座標に2を加えて、その値を再度transform.positionに代入してあげることで座標を変更することができます。

using UnityEngine;

public class Test : MonoBehaviour
{
    Vector3 myPosition; // Vector3型の変数を作成

    void Start()
    {
        myPosition = transform.position;    // 座標を取得して変数に代入
        myPosition.x += 2;                  // X座標に2を加算する
        transform.position = myPosition;    // 座標に再度代入する
    }
}

ただ、個人的には、座標を加算・減算で変更するのであれば、このやり方よりもtransform.Translateを使った方が便利かと思っています。

ワールド座標とローカル座標で取得方法が異なる

先ほどの例でtransform.positionで取得した座標は、ワールド座標となっています。

ワールド座標とは、ゲーム全体の中でそのオブジェクトがいる座標のことを言います。

そして、Unityにはもう一つ、ローカル座標というものがあります。

ローカル座標とは、そのオブジェクト自体が個別に持っている座標のことで、例えば親子関係などになっているオブジェクトは、親の座標を中心としたローカル座標を持っています。

このローカル座標を取得する場合は、transform.positionではなくtransform.localPositionを使用する必要があるので、注意しておきましょう。

まとめ

このページでは、transform.positionによる座標の取得方法や使い方についてまとめていきましたが、いかがでしたでしょうか?

transform.positionとは、Transformコンポーネントにある座標を管理しているposition変数のことです。

このtransform.positionを使うことで、オブジェクトの座標の位置を取得することが出来るので、座標に合わせてゲーム内で処理を行っていくことができます。

特に、ゲーム作りでは、transform.positionでキャラクターの移動操作による制限をかけたり、敵キャラクターが画面外に出たらそのオブジェクトを消去させたりなど、色んな使い方があるので覚えておきましょう。

最後までお読みいただきまして、ありがとうございました!

コメント