Unityでゲームをつくろう【#3 UIを使ってみる】

こんにちは。第二開発部のT.Nです。 今年Kentemに新卒で入社したUnity初心者が、同じUnity初心者へ向けて解説する記事、第三回目です。 前回はRigidbodyを使って球を飛ばしました。

前回:Unityでゲームをつくろう【#2 RigidBodyで物理演算をしてみる】 - KENTEM TechBlog

今回はUIを使ってみます。

UIとは?

UIとはボタンやテキストなどのユーザーが操作するためのインターフェースのことです。

ボタンを作成する

GameObjectを入れたときのようにHierarchy上で右クリックをし、ボタン(UI -> Legacy -> Button)を選択します。 (Button -TextMeshProというのがありますが、少し複雑なので今回はLegacyを使います)

するとHierarchyにはButtonだけでなくCanvas, EventSystemも作成されました。

・Canvas:UI要素が配置される領域です。UI要素は全てCanvas(コンポーネントがアタッチされたGameObject)の子でなくてはいけません。
・EventSystem:キーボードの入力や、タップなどからオブジェクトへイベントを送信するためのものです。

ボタンが押されたら球を飛ばす

前回では、プロジェクトを実行した瞬間に球が飛びました。
今回はButtonが押されたら球が飛ぶようにしてみます。

やることは非常に簡単です。

ゲームがStartしたら球を飛ばす

ボタンが押されたら球を飛ばす

にするだけです。

方法1 : Inspectorに直接イベントを付与する

前準備: 球を飛ばすメソッドを作成する

まずは球を飛ばすメソッドを作成しておく必要があります。 球を飛ばすコード自体は前回Startメソッドに作成済みなので、同じスクリプトに新たなメソッドを作り移植するだけです。(Startメソッドはアタッチしているゲームオブジェクトがシーンにロードされたとき、一度だけ実行されます)
今回はメソッド名をShootにしました。

using UnityEngine;

public class Sphere : MonoBehaviour
{
    private Rigidbody _rigidBody;

    public void Shoot()
    {
        _rigidBody = GetComponent<Rigidbody>();

        _rigidBody.velocity = new Vector3(15, 0, 0);
    }
}

ボタンクリック時のアクションを設定する

次にButtonコンポーネントを見てみると、On Click()という項目があります。ここにボタンがクリックされたら実行するメソッドを追加していきます。

  1. プラスをクリック
  2. クリック時に実行したいメソッドが書いてあるスクリプトがアタッチされているObjectをドラッグ&ドロップ
  3. No Functionをクリック
  4. Sphereをクリック
  5. 実行したいメソッドを選択

実行してみます

これでボタンが押された時に球を飛ばすことができました。

方法2 : コード上でイベントを付与する

先ほどの方法でも問題ありませんが、別の方法も試してみます。

前準備

SphereのスクリプトにShootメソッドを作るまでは先ほどと同じです。
次にボタン用のスクリプトを作成し、アタッチします。名前は「ShootButton」としておきます。

ボタンクリック時のアクションを設定する

先ほどのOnClickにShootメソッドを追加したように、クリックされた時に実行するメソッドを追加していきます。 追加するにはAddListenerメソッドを使います。書き方は以下の通りです。

Button.onClick.AddListener(クリックされた時に実行するメソッド)

まずはここまで書いてみましょう。

using UnityEngine;
using UnityEngine.UI;

public class ShootButton : MonoBehaviour
{
    private Button _button;

    private void Start()
    {
        _button = GetComponent<Button>();
        _button.onClick.AddListener(実行するメソッド);
    }
}

この"実行するメソッド"には球を飛ばすメソッド、つまりSphereクラスの中のShootメソッドを入れたいです。しかし、そのまま"Shoot"と書いてもButtonはShootメソッドの場所を知らないのでエラーとなってしまいます。

そこで[SerializeField]というものを使います。 [SerializeField]を使うことによって、private変数がエディタ上で操作可能となります。

using UnityEngine;
using UnityEngine.UI;

public class ShootButton : MonoBehaviour
{
    private Button _button;

    [SerializeField]
    private Sphere _sphere;

~

上記のように書くとエディタ上からprivate変数である_sphereを操作することができます。つまり、_sphere変数にSphereオブジェクトでインスタンス化されたSphereクラスを代入できるわけです。 (Sphereが連続して申し訳ありません...)

これでShootメソッドにアクセスできるようになりました。 あとは以下のように書けば、方法1と同じように実行できるはずです。

using UnityEngine;
using UnityEngine.UI;

public class ShootButton : MonoBehaviour
{
    private Button _button;

    [SerializeField]
    private Sphere _sphere;

    private void Start()
    {
        _button = GetComponent<Button>();
        _button.onClick.AddListener(_sphere.Shoot);
    }
}

今回は少し複雑だったと思います。 私も初めはよくわからなかったですが、何度も使っていると少しずつ理解できるようになりました。

KENTEMでは、様々な拠点でエンジニアを大募集しています!
建設×ITにご興味頂いた方は、是非下記のリンクからご応募ください。
hrmos.co