LoginSignup
14
15

More than 5 years have passed since last update.

UnityでButton的な何かを作る

Last updated at Posted at 2014-07-10

はじめに

Unityでボタンを使う場合、OnGUI()関数を使うやり方があるが、そうではなくGameObjectをタッチしたときになんらかのアクションを起こすようにしたい。
そのためのスクリプトを書いてみた。

基本方針

画面をタップするのは指1本(複数の場合もあるがここでは考えない)なので、Rayを撃つのは1回のみにとどめたい。
具体的には、前に書いた記事:Unityで画面をタップした時のRayの撃ち方を考えてみたの仕組みをそのまま使って、ボタン以外のものをタッチしたときと同じ仕組みで動作するようにする。

実装

実際に書いたスクリプトが以下。

必要なスクリプトをプロジェクトに準備しておく

あらかじめプロジェクトに、以下の2つのスクリプトを含めておく。

TapBehaviourは前の記事で書いたものとほぼ同じ。ButtonBehaviourが新たに書いたもの。

TapBehaviour.cs
using UnityEngine;

public interface TapBehaviour {
    // タッチしたときに呼ばれる。
    void TapDown(ref RaycastHit hit);
    // タッチを離したときに呼ばれる。
    void TapUp(ref RaycastHit hit);
}
ButtonBehaviour.cs
public interface ButtonBehaviour {
    void TouchDown();
    void TouchUp();
}

MainCameraにスクリプトを貼り付ける

MainCameraからRayを撃って、タップされた場所にTapBehaviourインターフェースを持つオブジェクトがあれば、イベントハンドラを呼び出すようにするために、MainCameraに次のスクリプトを貼り付けておく。

TouchHandlerも前の記事とほぼ同じもの。

TouchHandler.cs
using UnityEngine;
using System.Collections;

public class TouchHandler : MonoBehaviour {
    public float distance = 100; // Rayの届く距離

    void Update () {
        // タッチされたとき
        if(Input.GetMouseButtonDown(0)){
            // メインカメラからクリックしたポジションに向かってRayを撃つ。
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit = new RaycastHit();

            if (Physics.Raycast(ray, out hit, distance)) {
                GameObject selectedGameObject = hit.collider.gameObject;
                TapBehaviour target = selectedGameObject.GetComponent(typeof(TapBehaviour)) as TapBehaviour;
                if(target != null){
                    target.TapDown(ref hit);
                }
            }

            // 指を離したとき
        }else if(Input.GetMouseButtonUp(0)){
            // メインカメラからクリックしたポジションに向かってRayを撃つ。
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit = new RaycastHit();

            if (Physics.Raycast(ray, out hit, distance)) {
                GameObject selectedGameObject = hit.collider.gameObject;
                TapBehaviour target = selectedGameObject.GetComponent(typeof(TapBehaviour)) as TapBehaviour;
                if(target != null){
                    target.TapUp(ref hit);
                }
            }

        }
    }
}

ButtonにしたいGameObjectにスクリプトを貼り付ける

次に、実際にボタンにしたいGameObjectに、以下の2つのスクリプトを貼り付ける。
GameObjectはタッチに反応する前提なので、なんらかのColliderを持っている必要がある。

Button.cs
using UnityEngine;

public class Button : MonoBehaviour, TapBehaviour {

    private ButtonBehaviour handler = null;

    // タッチしたときに呼ばれる。
    public void TapDown(ref RaycastHit hit) {
        if(handler != null){
            handler.TouchDown();
        }
    }

    // タッチを離したときに呼ばれる。
    public void TapUp(ref RaycastHit hit) {
        if(handler != null){
            handler.TouchUp();
        }
    }

    void Start(){
        handler = gameObject.GetComponent(typeof(ButtonBehaviour)) as ButtonBehaviour;
    }
}

Button.csは常に同じもので良いので、変更の必要はない。

SomeButtonBehaviour.cs
using UnityEngine;
using System.Collections;

public class SomeButtonBehaviour : MonoBehaviour, ButtonBehaviour {
    public void TouchDown(){
        // ここにボタンが押されたときの処理を書く。
    }

    public void TouchUp(){
        // ここにボタンが離されたときの処理を書く。
    }
}

こちらのSomeButtonBehaviour(名前は変えてかまわない)が、実際の処理を担当する部分。
各ボタンごとにスクリプトを用意してやって、やりたい処理を書いていく。

補足

このままだと、TapBehaviourを使うのと大差ないが、
・テキストを表示して、押されたら背景色が変わるボタン

・テクスチャを表示して、押されたらテクスチャを変化させるボタン
など、一度作れば再利用可能なボタンを作るのが目的。

14
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
15