NOOB UNITY

初心者がUnityでなんかしちゃうぞBlog

【5分でわかる】クリッカーゲームを作りながらEventSystemによるオブジェクトのクリック判定取得を学ぼう

Unityに生まれたからには、誰もが一度は望む動作

「オブジェクトをクリックしたことを検知」

EventSystemとは、それを実現するイケてる機能なのであるッ!

オブジェクトへのクリック判定を取りたくなる時期が必ずある

反抗期ならぬ、判定期です。嘘です。

ユウ(@YuuUnity)です、こんばんは。 さて、Unityでゲームを作り始めると絶対にいつかは通る道として、オブジェクトへのクリック判定を取りたいというときがあります。 よくあるクリッカーゲームや、タップしたオブジェクトをどうにかしたい場合など、色々なことが考えられますよね。画面全体へのタップはUpdateでマウスのClickを監視すれば良いのですが特定のオブジェクトだけってなるとちょっとハードルが上がった気がします。

でも大丈夫。そんな問題を解決してくれる方法があるのです。

クリッカーを作るぞ

f:id:yuu9048:20190517010547g:plain

前から思っていたのですが、前回のルパンのようになにかゲームっぽいものを題材に説明したほうがわかりやすそうなので今回は犬クリッカーゲームを作ります。

  • 画面に犬が表示されている
  • 犬をクリックすると「1わんっ!」「2わんっ!」などと回数とともに吠えてくれる機能
  • 犬以外をクリックしても特に反応しない

という超面白そうなゲームです。ぜひ一緒に作りましょう!

下準備

犬とカメラの準備

2Dでプロジェクトを作り、犬の画像はどこかから探して準備しておきましょう。 探してきた犬画像はヒエラルキーにドラッグしてシーン上に配置しておきます!

f:id:yuu9048:20190517002217p:plain

まずはMainCameraに対してPhysics 2D Raycasterコンポーネントをアタッチしておきます。読んで時の如く、レイキャスト用のコンポーネントです。クリックしたことを判定するためにくっつけておきます。

テキストの追加

EventSystemが必要となるのですが、これはGUICANVASを追加すると自動的に準備してくれたりするので便利です。今回はちょうどテキストを使う予定なので、UIからTextをクリックしてUIパーツを追加してみましょう。

f:id:yuu9048:20190517002627p:plain

すると、CANVASとTextが追加されます。同時にEventSystemさんも準備されました。

f:id:yuu9048:20190517002745p:plain

f:id:yuu9048:20190517003010p:plain

テキストが見づらい位置にあるので少し調整して、準備はバッチリです!

プログラムするぞ編

さて下準備ができたところでプログラムを書いていきたいと思います。ここで整理しておきますが今回やりたいことは下記の通りです。

  • 画像がクリックされたらクリック回数を増やしてテキストを更新する
  • 画像以外がクリックされたら特に何も起こらない

なので、最低でも1個のスクリプトさえあれば実現できそうなのがわかります。つらつらと書いてみましょう。

Test.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; //UIを使うために必要
using UnityEngine.EventSystems; //イベントシステムを使うために必要

public class Test : MonoBehaviour , IPointerClickHandler { // クリックを取得するためのインターフェースを実装
    [SerializeField] Text countText; // Textをアタッチ
    int count;

    void Start() {
        countText.text = ""; // テキスト初期化
    }

    // このスクリプトがアタッチされたオブジェクトがクリックされたときの処理
    public void OnPointerClick(PointerEventData eventData) {
        count++; // 吠えた回数を増加
        countText.text = count + "わんッ!"; // テキストを更新
    }
}

f:id:yuu9048:20190120165309j:plain

なんか見たこと無い文字列があるぅうう!!

一番怖いやつですね。でも大丈夫です。簡単です。

まずは上の行から見ていきましょう。

using UnityEngine.UI; //UIを使うために必要
using UnityEngine.EventSystems; //イベントシステムを使うために必要

usingで色々と必要なものを取り込んでいます。今回はTextを使うのでUIを読み込んでいるのとクリックした判定を取るためにEventSystemが必要なのでそれも取り込んでいます。 正直それだけなので特に細かい説明も必要ないかなと思います。下準備みたいなものだと思ってください。

public class Test : MonoBehaviour , IPointerClickHandler { // クリックを取得するためのインターフェースを実装

さぁ、見慣れないものがでてきました。IPointerClickHandlerです。ハンドラー? なんか手的なもの? とか色々はてなが浮かびますがほぼ名前の通り「ポインタークリック」ということでクリックされたときに呼ばれる処理のアレです。

この機能っていうのはUnityのEventSystem側で最初から準備されているものなので、usingしてあげればスクリプトに記述して使うことができるようになるっていう寸法です。インターフェースなので実装してあげるだけで利用できるので簡単です。 ただしこれだけでは機能しないのでインターフェースのメソッドを実装していきます。

    // このスクリプトがアタッチされたオブジェクトがクリックされたときの処理
    public void OnPointerClick(PointerEventData eventData) {
        count++; // 吠えた回数を増加
        countText.text = count + "わんッ!"; // テキストを更新
    }

さて、ここが今回のきもとなる部分です。OnPointerClickというのがクリックされた時に呼ばれるメソッドで先程のIPointerClickHandlerインターフェースを実装した際に定義する必要のあるメソッドでもあります。インターフェースを実装したならこのメソッドがないと怒られるのでちゃんと作りましょう。

PointerEventData eventDataというのがなんだか怖いしややこしそうですが、なんのことはない。クリックした際に色々もってきたイベントデータが色々入っています。クリックされた位置とかも取れるはずなのでそれらを使うとまた違った遊びも実現できます。が、今回は割愛します。

メソッドの中身は超シンプル。カウントを増やして、それをテキストに反映しているだけです。やだ…私のスクリプト簡単すぎ…?と思うかもしれませんがこれで動くのでOKです。 さて、あっさりと完成したこのスクリプトをさきほど配置した画像にアタッチしてあげましょう。

クリッカー堂々の完成です!

遊ぶぞ編

さっそく遊んでみましょう。o(´∀`)oワクワク

f:id:yuu9048:20190517005645g:plain

f:id:yuu9048:20190517005844j:plain

なんと動きません。ふざけるな!不良品じゃないか!

あれ…なにか忘れているような気がします。

修正するぞ編

上の方で触れていましたが、Raycastのコンポーネントをつけていました。つまりそれってRayを発射してコライダーにあたらないといけないわけですよね。 …コライダーってつけてありましたっけ? ……いいえ、つけてませんでした。

茶番はこれぐらいにして、画像にコライダーをつけておかないとクリックの判定が取れないので駄目だったというオチです。さっそくBox Collider 2Dをつけてみましょう! 実際のコリジョン判定は必要ないのでTriggerで大丈夫です。

f:id:yuu9048:20190517010133p:plain

さぁ、今度こそ遊んでみましょう。

f:id:yuu9048:20190517010547g:plain

やった、動きました!

画像をクリックしたときだけ数字が増えています。 クリッカーゲームをあっという間に完成させてしまいました! というようにEventSystemさんを使うとクリックの取得などはあっというまに秒殺KO。即実装できてしまうということがわかりました。

今回のクリック以外にもマウスボタンをクリックして下げたとき IPointerDownHandler や、下げたあとに上げたとき IPointerUpHandler を取得するハンドラーもあったりしますし ドラッグの開始を取得するIBeginDragHandler だったり ドラッグ中を取得する IDragHandler や、ドラッグ終了を取得する IEndDragHandler などもあります。

とにかくイベントシステムを使うとプレイヤー側の入力をより簡単に取得することができるようになるので使い勝手が良好です。 ぜひ、クリッカーゲームの改良でもよいですし違うゲームの作成などにもこちらの機能を使ってみてください!