Developer

【初心者Unity】タグの使い方
2021.02.28
Lv1

【初心者Unity】タグの使い方

1.はじめに


ゲーム内で複数のオブジェクトに対して同じ処理を行う場合、ひとつひとつのオブジェクトに対応したスクリプトを発行するのは骨の折れる作業です。
例えば、敵モンスターに分類されるゲームオブジェクトに接触した際に戦闘画面に切り替わる、というような処理を実装する場合、接触した相手が敵モンスターかそれ以外かの条件式に全ての敵モンスターオブジェクトの名前を書いていく、というのは現実的に難しい運用です。

例)ひとつひとつのゲームオブジェクト名を指定

if(接触したオブジェクトの名前が盗賊Aならば){…}
if(接触したオブジェクトの名前が盗賊Bならば){…}
if(接触したオブジェクトの名前が盗賊Cならば){…}

Unityではこのようなケースに対し、タグと呼ばれる、ゲームオブジェクトをグループ化する便利な機能を提供しています。
タグによってゲームオブジェクトをグループ化することで、「もし接触した相手が”敵モンスター”タグのついたオブジェクトだったら~」というように、条件式を簡潔に記述することが可能となります。

例)タグ名で複数のゲームオブジェクトをまとめて指定

if(接触したオブジェクトのタグが”盗賊”ならば){…}

2.下準備


まずは以下のような構成を用意しましょう。

各ゲームオブジェクトのコンポーネントは以下のようになっています。
※デフォルト値から変更した箇所のみ記載しています。
■3D Object > Plane
・Transform.Position の値変更

■3D Object > Cube_1
・Transform.Position の値変更

■3D Object > Cube_2
・Transform.Position の値変更

■3D Object > Cube_3
・Transform.Position の値変更

■3D Object > Sphere
・Transform.Position の値変更

・Sphere Collider の項目変更
Is Triggerにチェックを付けます。

・RigidBodyコンポーネント追加
(Add Component > Physics > RigidBody)
Use Gravityからチェックを外します。

・Scriptコンポーネント追加
(Add Component > New Script)
スクリプトには以下の内容を記述しておきましょう。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NewBehaviourScript : MonoBehaviour
{
    // 中に記述された処理が一定間隔で繰り返し実行される
    void Update() {
        // このオブジェクトのTransformコンポーネントのPositionの値を変更する
        // Update()が実行される度に、X座標の値を+0.01する
        this.transform.position += new Vector3(0.01f, 0, 0);
        }
    }
}

3.タグの設定


今回は、Cube_1とCube_3に”Enemy”というタグを設定し、どちらかがSphereと接触する度にランダムに色を変化させるような機能を実装していこうと思います。

タグの設定方法はいたって簡単です。
Cube_1のインスペクタービュー上部「Tag」のプルダウンから設定したいタグを選択します。
デフォルトでいくつかタグが用意されていますが、”Enemy”はないため新規で作成する必要があります。
プルダウン下部「Add Tag…」を選択してください。

以下のビューに切り替わりますので、ここで「Tags」項目の左下+マークをクリックします。
新規作成するタグの名前を入力し、Saveします。

新規作成したタグがリストに追加されます。

ヒエラルキービューでCube_1を選択し、Cube_1のインスペクタービューに戻ります。
「Tag」のプルダウンで”Enemy”が選択できるようになっているはずです。

同様に、Cube_3にも”Enemy”タグを設定してあげてください。

4.タグの使用


タグは設定しただけでは何の効力も持ちません。
タグはスクリプトから呼び出されることでその威力を発揮します。
という訳で、スクリプトから”Enemy”タグを適用したゲームオブジェクトにアクセスしてみましょう。

Sphereに適用したスクリプトを以下のように書き換えてあげてください。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NewBehaviourScript : MonoBehaviour
{
    // 変数cubesの定義:GameObjectの配列
    GameObject[] cubes;

    // 中に記述された処理がゲーム開始時に一度だけ実行される
    void Start()
    {
        // "enemy"タグが設定されたゲームオブジェクトの配列を取得し、変数cubesに格納する
        cubes = GameObject.FindGameObjectsWithTag("Enemy");
    }

    // 中に記述された処理が一定間隔で繰り返し実行される
    void Update()
    {
        this.transform.position += new Vector3(0.01f, 0, 0);
    }

    // ゲームオブジェクト同士が接触したタイミングで実行
    void OnTriggerEnter(Collider other)
    {
        // もし衝突した相手オブジェクトのタグが"Enemy"ならば中の処理を実行
        if (other.gameObject.CompareTag("Enemy")) {
            // GameObject型の変数cubeに、cubesの中身を順番に取り出す
            // foreachは配列の要素の数だけループします。
            foreach (GameObject cube in cubes) {
                // cubeのRendererコンポーネントのmaterialの色をランダムに変更する
                // new Color(赤:0~1, 青:0~1, 緑:0~1, 透明度:0~1);
                cube.GetComponent<Renderer>().material.color = new Color(Random.value, Random.value, Random.value, 1.0f);
            }
        }
    }
}

上記のスクリプトの中で、

GameObject.FindGameObjectsWithTag("Enemy");

と記述することによって、”Enemy”タグのついたゲームオブジェクト一覧(配列)を取得しています。

そして、OnTriggerEnter()の中で、

if (other.gameObject.CompareTag("Enemy")) {...}

と書くことで、”Enemy”タグの設定されたゲームオブジェクトと接触したときのみ、内部の処理を実行するよう記述しています。

<関連記事>
【Unity連載】条件分岐をしよう!(if文)

ここまで設定できたら、ゲームを実行してみましょう。

いかがでしょうか。
想定通りの結果になりましたか??

このように、タグを利用することで、
① 同じタググループのゲームオブジェクト一覧を配列で取得する
② 当たり判定等で処理の対象となるゲームオブジェクトを区別する

等の処理を簡潔に記述できるようになります。


以上、タグの簡単な設定方法と使用例の解説でした。
タグは作成数に上限が無く、また作り過ぎてデメリットがあるようなこともありません。
何となくグループ化できたら便利そうだな、と思ったら、気軽に設定してみると良いのではないでしょうか。

 
 

連載目次リンク

「初心者のための」Unityゲーム制作 目次
 

Unity実践編 - 目次リンク

実践Unityゲームプログラミング 連載目次