閃光絵巻ラボ

脱出ゲームの作り方などの技術系のブログです。

Unityで脱出ゲームの作り方(5)「3Dオブジェクトをクリックで取得」

      2015/08/02

20150531120526222+

これまでのパートでUIボタンのクリックはできました。
このパートでは上の画像の、3Dの赤スイッチを押せるようにします。

3Dオブジェクトをクリック判定する

3Dオブジェクトをクリック判定するには、クリック動作を検出しなければなりません。

下準備です。クリック検出させるためのレイヤーを作ります。(後にスイッチをそのレイヤーに入れます)
右上辺りのLayers > Edit Layersを選択し、
20150531120544218+

User Layer 8に新しいレイヤーの名前を入れます。(8でなくてもOKです)
名前は自由ですが、ここでは「clickable」としておきます。

20150531120502219+
スイッチの3DオブジェクトにComponent > Physics > Box Colliderをいれて名前をredSwitchとかにします。
Box Colliderを追加すると黄緑の線の箱ができ、これがコライダー(当たり判定)になります。
20150531120526222+
そしてredSwitchのレイヤーをclickableにします。
20150531120539223+

それではクリックを判定するC#を書いていきます。

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System;
using System.Collections;

public class GameSystem : MonoBehaviour {

	public GameObject mainCamera; //カメラの定義
	public EventSystem eventsystem; //イベントシステム(いろんなことに使う)の定義

	//クリックでレイ(光線)とばす
	public Ray ray;
	public Ray rayItem;
	public RaycastHit hit;
	public GameObject selectedGameObject;

	/*------------
	管理
	------------*/
	public string standName; //現在の立ち位置


	// Use this for initialization
	void Start () {
		standName = "centerN"; //現在の立ち位置 = 北向き
		eventsystem = GameObject.Find("EventSystem").GetComponent<EventSystem>();
	}
	
	// Update is called once per frame
	void Update () {
		/*--------------
		画面クリック処理
		--------------*/
		if(Input.GetMouseButtonUp(0)){ //左クリック
			if(eventsystem.currentSelectedGameObject==null){// UI以外(3D)をさわった
				searchRoom(); //3Dオブジェクトをクリックした時の処理
			}else{ // UIをさわった
				switch(eventsystem.currentSelectedGameObject.name){
					case "turnLBtn":
						turnL();
						break;
				}
			}
		}
	}

	public void turnL () {
		switch(standName){
			case "centerN":
				GameObject.Find("mainCamera").transform.rotation = Quaternion.Euler(0, 270, 0);
				GameObject.Find("mainCamera").transform.position = new Vector3(-1, 7, -20);
				standName = "centerW";
				break;
			case "centerW":
				GameObject.Find("mainCamera").transform.rotation = Quaternion.Euler(0, 180, 0);
				GameObject.Find("mainCamera").transform.position = new Vector3(-1, 7, -20);
				standName = "centerS";
				break;
			case "centerS":
				GameObject.Find("mainCamera").transform.rotation = Quaternion.Euler(0, 90, 0);
				GameObject.Find("mainCamera").transform.position = new Vector3(-5, 7, -20);
				standName = "centerE";
				break;
			case "centerE":
				GameObject.Find("mainCamera").transform.rotation = Quaternion.Euler(0, 0, 0);
				GameObject.Find("mainCamera").transform.position = new Vector3(-6, 7, -26);
				standName = "centerN";
				break;
		}
	}
	public void searchRoom(){
			selectedGameObject=null;
			ray = Camera.main.ScreenPointToRay(Input.mousePosition);
			if (Physics.Raycast(ray, out hit, 10000000,1 << 8)) {
				selectedGameObject = hit.collider.gameObject;
						switch(selectedGameObject.name){
							case "redSwitch":
								Debug.Log("レッドスイッチを押した");
								break;
						}
			}
	}
}

 

今回もちょっと難し目ですね( ;^ω^)
ray(光線)が新たに登場です。このrayはクリックしたところからまっすぐレーザーのように撃たれ、最初に当たったオブジェクトを取得します。これが3Dオブジェクトの取得の仕方ですね。

searchRoomというvoidを用意し、レイを飛ばします

ray = Camera.main.ScreenPointToRay(Input.mousePosition);

 

ここの「8」という数字が重要です。さきほど作った「clickable」レイヤーは8番目のレイヤーでしたね。なので8を入れると、レイは8番目のレイヤーにあるオブジェクトにぶつかります。

if (Physics.Raycast(ray, out hit, 10000000,1 << 8)) {

 

ここでぶつかったオブジェクトが何なのかはhit.collider.gameObjectで取得できます。ここではselectedGameObjectに代入しました。

selectedGameObject = hit.collider.gameObject;

 

あとはselectedGameObject.nameでswicth文を作れば処理を書き分けられます。

switch(selectedGameObject.name){

プレビューで赤スイッチをクリックし、デバッグに「レッドスイッチを押した」と出れば成功です。
20150531200514226+

 

 

スイッチクリックでカギを出す

赤スイッチをクリックでカギが出てくるようにしましょう。
カギの3Dオブジェクトを用意してUnityに読み込みます。(3Dオブジェクトの追加方法はその1,その2を参考にしてください)

↓このへんに置きました。
20150531200514226++

カギは開始時には非表示にしておく必要がありますね。どうやって非表示にしましょう?

1つはインスペクターのチェックマークを外す方法ですが…
20150531200520228+これを開始後にGameObject.Find(“key”).SetActive(true);で表示させようとするとエラーになってしまいます。
はじめから消えているオブジェクトはGameObject.Findが使えないんです。
なのであらかじめカギは変数に入れておいてゲーム開始と同時に非表示にします。

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System;
using System.Collections;

public class GameSystem : MonoBehaviour {

	public GameObject mainCamera; //カメラの定義
	public EventSystem eventsystem; //イベントシステム(いろんなことに使う)の定義

	//クリックでレイ(光線)とばす
	public Ray ray;
	public Ray rayItem;
	public RaycastHit hit;
	public GameObject selectedGameObject;

	//アイテム
	public GameObject item_key;


	/*------------
	管理
	------------*/
	public string standName; //現在の立ち位置


	// Use this for initialization
	void Start () {
		standName = "centerN"; //現在の立ち位置 = 北向き
		eventsystem = GameObject.Find("EventSystem").GetComponent<EventSystem>();
		item_key = GameObject.Find("key");
		item_key.SetActive(false);
	}
	
	// Update is called once per frame
	void Update () {
		/*--------------
		画面クリック処理
		--------------*/
		if(Input.GetMouseButtonUp(0)){ //左クリック
			if(eventsystem.currentSelectedGameObject==null){// UI以外(3D)をさわった
				searchRoom(); //3Dオブジェクトをクリックした時の処理
			}else{ // UIをさわった
				switch(eventsystem.currentSelectedGameObject.name){
					case "turnLBtn":
						turnL();
						break;
				}
			}
		}
	}

	public void turnL () {
		switch(standName){
			case "centerN":
				GameObject.Find("mainCamera").transform.rotation = Quaternion.Euler(0, 270, 0);
				GameObject.Find("mainCamera").transform.position = new Vector3(-1, 7, -20);
				standName = "centerW";
				break;
			case "centerW":
				GameObject.Find("mainCamera").transform.rotation = Quaternion.Euler(0, 180, 0);
				GameObject.Find("mainCamera").transform.position = new Vector3(-1, 7, -20);
				standName = "centerS";
				break;
			case "centerS":
				GameObject.Find("mainCamera").transform.rotation = Quaternion.Euler(0, 90, 0);
				GameObject.Find("mainCamera").transform.position = new Vector3(-5, 7, -20);
				standName = "centerE";
				break;
			case "centerE":
				GameObject.Find("mainCamera").transform.rotation = Quaternion.Euler(0, 0, 0);
				GameObject.Find("mainCamera").transform.position = new Vector3(-6, 7, -26);
				standName = "centerN";
				break;
		}
	}
	public void searchRoom(){
			selectedGameObject=null;
			ray = Camera.main.ScreenPointToRay(Input.mousePosition);
			if (Physics.Raycast(ray, out hit, 10000000,1 << 8)) {
				selectedGameObject = hit.collider.gameObject;
						switch(selectedGameObject.name){
							case "redSwitch":
								item_key.SetActive(true);
								break;
						}
			}
	}
}

これで赤スイッチをクリックするとカギがパッと出てきます。
これでも十分OKなのですが、ちょっと動きが物足りないかも?
カギが天井から降ってくるなど、アニメーションが付いてるともっとゲームらしくなりますよね。
それを次回でやってみましょう。

 »第6回へ続く

 - Unityで脱出ゲームの作り方

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

  関連記事

Unityで脱出ゲームの作り方(8)「アイテムを選択(装備)する」

アイテムリストクリックでアイテムを装備する アイテムリストのカギをクリックしたら …

Unityで脱出ゲームの作り方(3)「部屋の中を移動する・下準備編」

このパートでは脱出ゲーム定番の移動ボタンを追加します。 画面上に固定で表示するU …

Unityで脱出ゲームの作り方(2)「UnityにSketchupの3Dの部屋をインポート」

第2回からはUnityという今話題のゲーム作成ソフトを使っていきます。 とても高 …

Unityで脱出ゲームの作り方(4)「部屋の中を移動する・UIでカメラ回転編」

第4回はカメラ回転のスクリプトを実際に書いていきます。 上の画像のようにぐるりと …

Unityで脱出ゲームの作り方(7)「アイテムリストを作る」

前回まででスイッチを押すとカギが降ってくるようにしました。 ここで落ちてきたカギ …

Unityで脱出ゲームの作り方(6)「物体を滑らかにアニメーションで動かす」

第6回は物体のなめらかなアニメーション(トゥイーン)を実装します。 脱出ゲームに …

Unityで脱出ゲームの作り方(1)「3Dの部屋を作る」

Unityで脱出ゲーム講座 初回は3Dの部屋づくりからはじめます。 このパートで …