LotosLabo

プログラミング技術とか気になった情報を載せていきます

UnityのRaycastについて

Unityには「Raycast」という、ものがあります。

レイキャスト と読み、仮想的な線を利用して衝突検出をする機能です。


どういうものなの? というとことで最後の方にサンプルを作成してみましたので、プログラムと一緒に使いかたを紹介します。




基本的には、Physics.Raycast関数というものを使います。


第一引数にはレイキャストの原点の位置、第二引数は方向、第三引数には衝突情報、第四引数には検知を行う距離、第五引数にはレイヤーマスクをとります。

※第三引数まで必須です。



基本プログラム

任意の位置から任意の方向に向けて架空の線を出し、その線分上にあるオブジェクトを取得する。

RaycastHit hit;

if(Physics.Raycast( transform.position,Vector3.right,out hit, 10 ))
{
hit.transform.gameObject;
}

positionから右方向に10進んだ先までにオブジェクトがあればtrueが返される。

第三引数にoutで指定すると衝突したオブジェクトの情報が入る。


※ActionScript入門Wiki-Raycastを使用する-参照


実用例

RaycastHit hit;
if( Physics.Raycast( transform.position,Vector3.forward,hit ))
{
 if( hit.collider.tag == "enemy" )
 {
   print( "前方に見える" );
 }
} 

架空の線上に「enemy」タグのオブジェクトが検出されればtrueが返される。



■アプリケーション実装例


f:id:lo25131:20140722143352j:plain

架空の線上にテクスチャを使用して、線を見えるようにして、
線がオブジェクトに3秒間衝突し続けるとオブジェクトを爆発するようにしました。

レーザーのテクスチャはPhotoshopで作成してみました。本ブログにてDLできるように公開しておきます。

f:id:lo25131:20140722143701p:plain

DL



(構築方法)

まず用意するものを簡単に説明します。

 *GUITEXT
 ・説明テキストx2
 ・衝突時間テキスト


 *オブジェクト
 ・Playerオブジェクト
 ・床
 ・的になるオブジェクトx5


 *Laser素材


 *爆発パーティクル


 *爆発音


 *背景素材


 *制御スクリプト
 ・プレイヤーの向きを変更するスクリプト
 ・レーザーの制御スクリプト



※7月31日更新

■レーザーの表示方法

スクリーンショット等での説明はしませんのでわかりにくい場合は実際にプロジェクトファイルをダウンロードしてご確認ください。


①プレイヤーの近くにCreate Empty(空のオブジェクト)を作成します。

②先ほどの空のオブジェクトに、コンポーネントを追加します。

③ComponentのEffectsよりLine Rendererを選択します。

④Line RendererにLazerのテクスチャを追加します。

⑤うまく表示されるように値を調整

ParametersのStart WidthとEnd Widthを調整します。
私の場合は両方共0.03にしました。

⑥空のオブジェクトに、Lazerのテクスチャを適用する。


流れをまとめるとこのようになりました。


後はプログラムで制御していきます。


  • プレイヤー操作プログラム -
using UnityEngine;
using System.Collections;

public class Controls : MonoBehaviour
{
	public int speed;
	public float friction;
	public float lerpSpeed;

	private float xDeg;
	private float yDeg;
	private Quaternion fromRotation;
	private Quaternion toRotation;

	void Update()
	{
			xDeg += Input.GetAxis("Horizontal") * speed * friction;

			fromRotation = transform.rotation;
			toRotation = Quaternion.Euler(0,xDeg,0);

			transform.rotation = Quaternion.Lerp(fromRotation,toRotation,Time.deltaTime * lerpSpeed);
	}
}


確かリファレンスから持ってきたものだった気がします。
平行軸のキー入力により、プレイヤーを左右に傾きを変更するプログラムです。


  • レーザー制御及び -
using UnityEngine;
using System.Collections;

public class Weapon : MonoBehaviour 
{
	public GameObject laser; // レーザー
	public GameObject obj; // エフェクト

	private Transform enemy; // 敵
        private float score; // レーザー衝突時間
        private int hit_score; // 敵数


	void Update()
	{
		RaycastHit hit;
        
              // レーザー衝突処理
		if (Physics.Raycast(laser.transform.position, laser.transform.forward, out hit))
		{
			if(hit.collider.tag == "Enemy")
			{
				score += Time.deltaTime;
                // 三秒だが感覚的に2.2秒?
				if(score >= 2.2){
					Instantiate (obj, hit.point, Quaternion.identity);
					//hit.collider.gameObject.transform.positionでもいいよ
					Destroy(hit.collider.gameObject);
					audio.Play();
					hit_score += 1;			
				}
			}
			if(hit.collider.tag == "Test")
			{
				score = 0.0f;
			}
		}

		time.text = Mathf.CeilToInt(score).ToString();

		if(hit_score == 5){

			if(Input.GetKeyDown(KeyCode.R))
			{
				Application.LoadLevel (Application.loadedLevel);
			}
		
		}


	}
}


テキスト表示などのプログラムは割愛させていただきました。
ここではレーザーが敵に衝突し、3秒経過した後に敵の爆発と爆発音をつけています。



完成したアプリケーションがこちらになります。
https://dl.dropboxusercontent.com/u/252114885/Laser_test.html



また、プロジェクトもDL可能にしておきますので、これを応用して、いろいろなゲーム制作に使用していただけると幸いです。

DL


※7月31日更新

Line Rendererに付いている、LazerというC#プログラムは特に関係ないので外して構いません。