【Unity】Selectableコンポーネントでオブジェクトが選択可能になる

Selectableコンポーネント Unity

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

このページでは、

「オブジェクトを選択できるようにしたい!」

「Selectableコンポーネントってなに?」

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

Unityでは、配置したゲームオブジェクトやUI要素を選択できるようにするSelectableコンポーネントという機能があります。

このSelectableコンポーネントは、マウスやキー操作でオブジェクトが選択できるようになり、選択した際の色を変更したりアニメーションで動きを付けたりというイベント処理を作ることができます。

例えば、キャラクターのスキンを複数から選ぶという処理や、いくつかのメニューからいずれかを選択する際などに、Selectableコンポーネントが便利に使えます。

そこでこのページでは、UnityのSelectableコンポーネントについて、どんな機能なのか、また使い方までをまとめていきます。

この記事を書いた人

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

Selectableコンポーネントとは?

まずは、Selectableコンポーネントがどういう機能なのかについて紹介していきます。

ゲームオブジェクトやUI要素を選択可能にする機能

Selectableコンポーネントとは、ゲームオブジェクトやUIを選択できるようにするための機能です。

マウス操作で選択できるだけでなく、キーやコントローラーによる操作でも選択できるようになるのが、Selectableコンポーネントの特徴です。

例えば、ゲーム内で複数のキャラクターから1体選ぶという処理を考えてみます。

それぞれのオブジェクトをマウスでクリックして選ぶのであれば、Raycastメソッドで処理を作ることもできますが、キー操作やコントローラーでは選択することができません。

そこで、選択したい全てのオブジェクトにSelectableコンポーネントを付けてあげることで、マウスだけでなく、キーボードの矢印キーやWASDキー、コントローラーの十字キーなどでも、どのキャラクターにするかを順番に選択できるようになります。

このようにSelectableコンポーネントを付けたゲームオブジェクトやUI要素は、プレイヤーの操作によって選択することができるようになります。

なお、UI要素の中にあるButtonDropdownなどは、すでに選択可能なものになっているため、Selectableコンポーネントを紐づけることはできません。

選択した時のイベント処理も作れる

Selectableコンポーネントは、ゲームオブジェクトやUIを選択できるようにするだけでなく、選択した時のイベント処理を作ることもできます。

もう少し具体的に言うと、Selectableが付いているオブジェクトにカーソルが触れた時選択した時押した時などに、

  • 色を変更する
  • 画像を変更する
  • アニメーションで動きを付ける

という処理をSelectableコンポーネント内で作ることができます。

例えば、「GAME START」「SETTINGS」というTextMeshProで作った文字を以下のように配置しておきます。

これらにSelectableコンポーネントを付けて、選択した時などに色を変更する処理を設定しておくと、

上記のように、それぞれがフォーカスされると色が変更される処理が行われるようになり、どれが選択されているのかがすぐに分かるようになります。

EventTriggerと組み合わせて使える

Selectableコンポーネントでも、前述の通りイベント処理を作ることができますが、EventTriggerと組み合わせて使うことができます。

EventTriggerとは、発生させたいイベントを登録しておくことができるコンポーネントで、指定したトリガーが発生したらその処理が実行されるという機能です。

このEventTriggerの中に、選択できるものを使った際のイベントが準備されていて、これらはSelectableコンポーネントが付いているオブジェクトに対して使うことができます。

特に、ゲームオブジェクトにSelectableコンポーネントを使う場合、Selectable内でのイベント処理を設定できないものもあるため、EventTriggerを使う方が便利です。

また、EventTriggerだと自分でメソッドを定義して紐づけることができるので、独自の処理を行いたい場合などで活用できます。

Selectableコンポーネントの基本的な使い方

ここからは、Selectableコンポーネントの基本的な使い方について紹介していきます。

ゲームオブジェクトやUI要素にSelectableを紐づける

まずは、選択できるようにしたいゲームオブジェクトやUI要素にSelectableコンポーネントを紐づけていきます。

Selectableコンポーネントを紐づける場合は、オブジェクトを選択した状態でインスペクターウィンドウの「Add Component」をクリックします。

コンポーネントの一覧から「UI」の中にある「Selectable」を選択します。

これで、ゲームオブジェクトやUI要素は選択できる状態となっています。

なお、Selectableを付けたゲームオブジェクトをマウス操作でも選択させる場合は、オブジェクトにColliderコンポーネント、またカメラオブジェクトにPhysicsRaycasterコンポーネントを紐づけておく必要があります。

Selectableコンポーネントの設定項目

Selectableコンポーネントが紐づけできたら、インスペクターウィンドウから設定を行っていきます。

Selectableコンポーネントの設定として、

  • Interactable:選択できるようにするかどうか
  • Transition:選択した時などのイベント処理を設定する
  • Navigation:キー操作で次に選択するオブジェクトの順番を指定

という上記の3つの設定があります。

Interactable:選択できるようにするかどうか

Interactableは、ゲームオブジェクトやUI要素を選択できるようにするかどうかを決めている項目です。

このInteractableにチェックが入っていると選択できますが、チェックが入っていない場合は選択自体ができなくなります。

Interactableの設定は、スクリプトから変更してあげることで、特定の条件下でのみそのオブジェクトを選択できるようにすることができます。

Transition:選択した時などのイベント処理を設定する

Transitionは、選択された時などにどのようなイベント処理を行うかを設定できる項目で、

  • None:Selectable上では処理を行わない
  • Color Tint:色を変更する処理
  • Sprite Swap:画像を変更する処理
  • Animation:アニメーションで動きを付ける処理

という上記の4つから選択することができます。

None:Selectable上では処理を行わない

Noneは、そのオブジェクトが選択されたとしても、何のイベント処理も行わないという設定になります。

例えば、選択時のイベント処理はEventTriggerで行うといった場合、Selectableコンポーネントとしてはオブジェクトが選択できるようになればいいだけなので、Noneを指定すれば問題ありません。

Color Tint:色を変更する処理

Color Tintは、UI要素などが選択された際などに、色を変更するイベント処理を行う設定です。

  • Target Graphic:変更処理を行う対象
  • Normal Color:何もしていない時の色
  • Highlighted Color:カーソルを合わせた時の色
  • Pressed Color:押した時の色
  • Selected Color:選択されている時の色
  • Disabled Color:選択が無効状態の時の色
  • Color Multiplier:色が変更される時に乗算する値
  • Fade Duration:色が変更される時の秒数

例えば、UI要素のTextMeshProにSelectableを付けて、TransitionをColor Tintにして、以下のように設定します。

すると、カーソルを合わせたり、クリックして選択する度に、色が変わるようになります。

他にも、UI要素のImageを使って、以下のように色を変化させることができます。

また、このColor Tintは、元の対象のVertex colorの値に指定した色を乗算させる形で変更させているようで、Vertex colorに黒を指定していると、Color Tintにどの色を指定しても変化しなくなりますので、注意しておきましょう。

なお、Target GraphicにはUI要素の対象しか設定できないため、ゲームオブジェクトを対象にすることができません。

Sprite Swap:画像を変更する処理

Sprite Swapは、UI要素などが選択された際などに、スプライト画像を切り替えてイベント処理を行う設定です。

  • Target Graphic:変更処理を行う対象
  • Highlighted Sprite:カーソルを合わせた時の画像
  • Pressed Sprite:押した時の画像
  • Selected Sprite:選択されている時の画像
  • Disabled Sprite:選択が無効状態の時の画像

例えば、UI要素のImageを使って、それぞれのイベント毎に画像を準備して、Selectableコンポーネントに設定してみます。

すると、以下のように選択したりカーソルを合わせると、画像が切り替わるようになりました。

Animation:アニメーションで動きを付ける処理

Animationは、UI要素やゲームオブジェクトが選択された際などに、アニメーションで動きを付けてイベント処理を行う設定です。

  • Normal Trigger:何もしていない時のアニメーション
  • Highlighted Trigger:カーソルを合わせた時のアニメーション
  • Pressed Trigger:押した時のアニメーション
  • Selected Trigger:選択されている時のアニメーション
  • Disabled Trigger:選択が無効状態の時のアニメーション

それぞれのTriggerの項目部分に名称を入れておき、「Auto Generate Animation」を選択すると、自動的にその名前のAnimationと切り替えを行うAnimator Controllerが作成されます。

この状態で、メニューの「Window」から「Animation」の中にある「Animation」を選択します。

以下の赤枠部分で、それぞれのイベント時のAnimationファイルが作成されているので、選択してアニメーションの動きを設定していくことができます。

例えば、カーソルを合わせた時は回転を行い、選択した時はScaleの値を変動させるようにするアニメーションを付けてあげると、

上記のような動きを簡単に付けることができるようになります。

Navigation:キー操作で次に選択できるオブジェクトを指定

Navigationは、キー操作を使って次に選択するオブジェクトを指定することができる項目です。

Selectableコンポーネントを付けたオブジェクトやUI要素が複数ある場合、WASDキー矢印キーコントローラーなどを使って順番に選択できるようになりますが、この順番を指定するのがNavigationの役割です。

  • None:キー操作による選択を無効にする
  • Horizontal:水平方向(横)にだけ次のオブジェクトを選択
  • Vertical:垂直方向(縦)にだけ次のオブジェクトを選択
  • Automatic:自動で次のオブジェクトを選択
  • Explicit:手動で上下左右のキーに合わせてオブジェクトを指定

基本的には「Automatic」にしておくことで、以下のように選択できるオブジェクトが並んでいる順番で、キー操作を使って選択することができます。

ただし、例えば、一番右上に配置しているオブジェクトを選択している状態で、Dキーもしくは右矢印キーを押したら左下のオブジェクトに移動させたいと思っていても、Automaticではフォーカスするオブジェクトが変わりません。

これを右上のオブジェクトにだけ、「Explicit」手動で次に選択するオブジェクトを指定してあげることで、Dキーもしくは右矢印キーを押したら、左下のオブジェクトに移動させるということができます。

以下は、左下のオブジェクトも同様に「Explicit」で設定していて、横の移動だけですべてを選択できているのが分かります。

また、「Visualize」をクリックしておくと、シーン画面上にNavigationによる動きを可視化することができます。

複数のオブジェクトを選択できるようにする処理

ここでは、以下のように3つの車のオブジェクトを配置しておき、Selectableコンポーネントを使ってそれぞれを選択できる状態にして、スペースキーを押したらその車だけを移動させるという処理を作ってみます。

まず、3つのオブジェクトにSelectableコンポーネントを紐づけておき、TransitionをAnimation、Navigationを「Automatic」にしておきます。

選択した際のイベント処理である「Selected Trigger」のアニメーションを作成していて、ここでは選択したら以下のような動きになるように設定しています。

次に、車を選択した状態でスペースキーを押したら、その車が出発するという処理を作っていきたいので、車のオブジェクトに以下のスクリプトをアタッチしておきます。

using UnityEngine;
using UnityEngine.EventSystems; // EventSystemを使う際に記述
using UnityEngine.UI;   // Selectableを使う際に記述

public class CarController : MonoBehaviour
{
    Selectable selectable;  // Selectable型の変数を宣言
    GameObject selectObj;   // 選択したオブジェクトを取得する変数
    bool isStarting = false;    // 車を移動させるかどうかを判定する変数

    void Start()
    {
        selectable = GetComponent<Selectable>();    // Selectableコンポーネントを取得
    }

    void Update()
    {
        // スペースキーを押した場合
        if (Input.GetKeyDown(KeyCode.Space) && !isStarting)
        {
            selectObj = EventSystem.current.currentSelectedGameObject;  // 現在選択されているオブジェクトを取得
            selectable.interactable = false;    // オブジェクトを選択できないように変更

            // 選択されたオブジェクトの場合
            if (selectObj == this.gameObject)
            {
                isStarting = true;  // 変数の値を変更
            }
        }

        if (isStarting)
        {
            transform.Translate(0.02f, 0, 0);   // 車を移動させる処理
        }
    }
}

Startメソッド内の13行目で、GetComponentメソッドを使ってSelectableコンポーネントを取得しています。

なお、Selectableコンポーネントをスクリプトで使う際は、3行目のように以下の記述が必要となります。

using UnityEngine.UI;

そして、スペースキーを押した場合の中の21行目で、現在選択されているオブジェクトを取得しています。

選択中のオブジェクトを取得する場合は、EventSystemの機能で以下のように記述することで取得できます。

EventSystem.current.currentSelectedGameObject

ちなみに、EventSystemの機能を使う際も、2行目のように以下の記述が必要となります。

using UnityEngine.EventSystems;

この取得したオブジェクトがその車のオブジェクトである場合は、bool型の変数を使って、33行目で画面の右に向かって移動するという処理を作っています。

次に、ゲーム起動時に一番上に配置している車が選択されている状態で始めたいので、ヒエラルキーウィンドウからEventSystemのオブジェクトを追加して、インスペクターウィンドウの「First Selected」の項目に車のオブジェクトを設定しておきます。

あとは、ポインターとなる指のオブジェクトに対して、以下のスクリプトをアタッチしておきます。

using UnityEngine;
using UnityEngine.EventSystems; // EventSystemを利用する際に記述

public class FingerController : MonoBehaviour
{
    GameObject selectObj;   //  現在選択しているオブジェクトを取得する変数

    void Update()
    {
        // 選択しているオブジェクトがnullの場合
        if (EventSystem.current.currentSelectedGameObject == null)
        {
            gameObject.SetActive(false);    // オブジェクトをオフにする処理
        }

        // 変数のオブジェクトと異なるオブジェクトが選択されている場合
        if (selectObj != EventSystem.current.currentSelectedGameObject)
        {
            selectObj = EventSystem.current.currentSelectedGameObject;  // 選択されているオブジェクトを取得

            if (selectObj != null)
            {
                transform.position = selectObj.transform.position + new Vector3(-2.2f, -0.6f, 0);   // 選択されているオブジェクトの左側に移動させる
            }
        }
    }
}

19行目で選択されているオブジェクトを取得して、23行目でそのオブジェクトの左側に指が移動するように処理を記述しています。

ちなみに、スペースキーを押すと車のオブジェクトは選択できないようになるため、currentSelectedGameObjectの値がnullになったら、13行目でSetActiveを使って非アクティブ化するようにしています。

これでゲームを実行してみると、

それぞれの車を選択することができ、スペースキーを押したらその車が出発するという処理を作ることができました。

まとめ

このページでは、UnityのSelectableコンポーネントについて、どんな機能なのか、また使い方までをまとめていきましたが、いかがでしたでしょうか?

Selectableコンポーネントとは、オブジェクトやUIを選択することができる機能で、マウスやキー操作で選択できるようになります。

また、Selectableを使うことで、カーソルを合わせた時や選択した時のイベント処理を同時に作ることができます。

ゲーム内で複数のオブジェクトや文字などの選択処理を作る場合に、Selectableコンポーネントが非常に便利に使えます。

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

コメント