Unity5学習の際の覚え書き。

衝突判定の3つの基本イベント

OnCollisionEnterそのオブジェクトが別のオブジェクトに触れた時に一度だけ発生する。
OnCollisionStayオブジェクトが別のオブジェクトに接触している間、連続して発生し続ける。
OnCollisionExit接触しているオブジェクトが離れたときに一度だけ発生する。

衝突するのはコライダー(Collider)

オブジェクトの衝突判定は、各オブジェクトに組み込まれているコライダーのオブジェクトによって管理されている。
オブジェクトのメッシュなどによってチェックされているわけではない。
リジッドボディが組み込まれている場合は、これによっても判定される。

衝突イベント用メソッド

void OnCollisionEnter (Collision collision) { ... } ;
void OnCollisionStay (Collision collision) { ... } ;
void OnCollisionExit (Collision collision) { ... } ;

引数のCollisionクラスのインスタンス

衝突した相手の、下記のような値が保管されている
collider
衝突した相手のコライダーが保管される。値は、Colliderクラスのインスタンス。
contacts
衝突した接点の情報を保管。この値は、「ContactPoint」というクラスの配列になっている。
接点が複数ある場合もあるので、1つ1つの接点がContactPointインスタンスとしてすべてまとめられている。
gameObject
衝突相手のゲームオブジェクトを保管。値は、GameObjectインスタンス。
relativeVelocity
衝突相手の相対速度を保管。値は、Vector3インスタンスで保管される。
これにより、X,Y,Zの各軸方向の速度がわかる。
rigidbody
リジッドボディが設定されていた場合に、そのRigidbodyのインスタンスを保管する
transform
衝突相手のTransformインスタンスが保管される。
これにより位置や向きなどの情報を得ることができる。

衝突時の処理を行う

OnCollisionEnter他のColliderやRigidbodyオブジェクトに触れた時に呼び出される
OnCollisionExit他のColliderやRigidbodyオブジェクトに離れた時に呼び出される
OnCollisionStay他のColliderやRigidbodyオブジェクトに触れ続けている時に呼び出される

衝突時処理の例 (衝突してきた相手を削除するスクリプト)

private void OnCollisionStay(Collision c){
	if (c.gameObject.name == "Ball"){
		Destroy (c.gameObject);
	}
}

衝突時処理の例 (衝突されたら自分を削除するスクリプト)

private void OnCollisionStay(Collision c){
	if (c.gameObject.name == "Ball"){
		Destroy (gameObject);
	}
}

衝突対象の判定

衝突対象の判定にはタグが良い。
タグはオブジェクトのインスペクタから設定可能。
デフォルトのタグ以外に、任意のタグを追加可能。

衝突対象をタグ判定したスクリプト

private void OnCollisionStay(Collision c){
	if (c.gameObject.CompareTag("Ball")){
		Destroy (gameObject);
	}
}

衝突イベントを使ってみたスクリプト

public class myscript : MonoBehaviour {

	void Start () {
		GameObject.Find("GUI Text").GetComponent<GUIText>().text ="Collision Event sample";
	}

	void Update () {
		GameObject cube = GameObject.Find ("Cube");
		cube.transform.Rotate (1f, -1f, -1f);
		if (Input.GetKey (KeyCode.LeftArrow)) {
			GetComponent<Rigidbody>().AddForce (new Vector3 (-1f, 0, 1f));
		}
		if (Input.GetKey (KeyCode.RightArrow)) {
			GetComponent<Rigidbody>().AddForce (new Vector3 (1f, 0, -1f));
		}
		if (Input.GetKey (KeyCode.UpArrow)) {
			GetComponent<Rigidbody>().AddForce (new Vector3 (1f, 0, 1f));
		}
		if (Input.GetKey (KeyCode.DownArrow)) {
			GetComponent<Rigidbody>().AddForce (new Vector3 (-1f, 0, -1f));
		}
	}

	void OnCollisionEnter(Collision collision){
		// 衝突した相手がPlaneでなければ処理をする
		if (collision.gameObject.name != "plane") {
			// 衝突した対象(collisionオブジェクト)の色を変更している。
			collision.gameObject.GetComponent<Renderer>().material.color = Color.yellow;
		}
	}
}

オブジェクトを消す

アクティブ状態を調べる

オブジェクトが画面に表示されているかどうか(アクティブかどうか)は、GameObjectの「activeSelf」メソッドで調べることができる。

アクティブ状態を調べる

アクティブ状態の変更は、「SetActive」というメソッドで変更できる。

オブジェクトを非表示にして一定時間経つと再表示させるスクリプト

public class myscript : MonoBehaviour {
	int counter = 0;
	GameObject obj = null;

	void Start () {
		GameObject.Find("GUI Text").GetComponent<GUIText>().text ="Collision Event sample";
	}

	void Update () {
		GameObject cube = GameObject.Find ("Cube");
		// objの値をチェックし、何かのオブジェクトが保管されているなら、counterを増やして、
		// 100より大きくなっていたら元の状態に戻している。
		if(obj != null){
			if (counter++ > 100){
				obj.SetActive (true);
				obj = null;
			}
		}
		try {
			cube.transform.Rotate (1f, -1f, -1f);
		} catch (System.NullReferenceException e){}
		if (Input.GetKey (KeyCode.LeftArrow)) {
			GetComponent<Rigidbody>().AddForce (new Vector3 (-1f, 0, 1f));
		}
		if (Input.GetKey (KeyCode.RightArrow)) {
			GetComponent<Rigidbody>().AddForce (new Vector3 (1f, 0, -1f));
		}
		if (Input.GetKey (KeyCode.UpArrow)) {
			GetComponent<Rigidbody>().AddForce (new Vector3 (1f, 0, 1f));
		}
		if (Input.GetKey (KeyCode.DownArrow)) {
			GetComponent<Rigidbody>().AddForce (new Vector3 (-1f, 0, -1f));
		}
	}

	void OnCollisionEnter(Collision collision){
		if (collision.gameObject.tag == "Player"){
			if (obj != null) {
				obj.SetActive (true);
			}
			collision.gameObject.SetActive (false);
			obj = collision.gameObject;
			counter = 0;
		}
	}
}

シェーダー

ゲームオブジェクトを透明に表示するには「シェーダー」を変更し、表示する色などを調整する。
シェーダーというのは、オブジェクトを描画する方法などを定義したもの。

ゲームオブジェクトを作成すると、色やテクスチャーを設定すればそのままシーンに表示されるが、これはUnityに用意されているシェーダーがデフォルトでされており、「このオブジェクトをどういうやり方で描くか」が決まっていたから。
色の塗り方、光があたった時の反射や透明な状態の表示など、細かな描き方がシェーダーによって決められている。

デフォルトで設定されているのは、「Diffuse」という、不透明でもっとも一般的な描き方のシェーダー。
これを「半透明な、一般的な描き方」のシェーダーに変える。

Cubeに触れると不透明にするスクリプト

あらかじめ接触される側のシェーダーを変更しておく必要がある。
今回はインスペクターで「GUI/Text Shader」にしておいた。(それがたまたま動いたので)
public class myscript : MonoBehaviour {

	void OnCollisionEnter(Collision collision){
		if (collision.gameObject.name == "Cube"){
			collision.gameObject.GetComponent<Renderer>().material.color = new Color (1f, 0, 0, 0.1f);
		}
	}

	void OnCollisionExit (Collision collision){
		if (collision.gameObject.name == "Cube"){
			collision.gameObject.GetComponent<Renderer>().material.color = new Color(1f, 0, 0, 1f);
		}
	}
}

スクリプトでシェーダーを設定する

オブジェクトで設定されているシェーダーは、Materialの「shader」というプロパティとして管理されている。
これにはShaderクラスのインスタンスが保管されている。
使いたいシェーダーのShaderインスタンスを用意し、それをMaterialのshaderに設定してやれば、スクリプトでシェーダーを操作することができる。
シェーダーの設定
Shaderインスタンスは、Shaderクラスの「Find」とぴうメソッドを使って取り出すことができる。
引数にShader名を指定すると、そのShaderインスタンスを返してくる。

<Material>.shader = Shader.Find (シェーダー名);

(例)
obj.GetComponent<Renderer>().material.shader = Shader.Find("GUI/Text Shader");
すべてのPlayerタグのシェーダーを変更するスクリプト
※エラー吐くためダメ
public class myscript : MonoBehaviour {

	void Start () {
		GameObject.Find("GUI Text").GetComponent<GUIText>().text ="Collision Event sample";
		GameObject[] objs = GameObject.FindGameObjectWithTag ("Player");
		foreach (GameObject obj in objs) {
			Color c = obj.GetComponent<Renderer> ().material.color;
			c.a = 1f;
			obj.GetComponent<Renderer> ().material.color = c;
			obj.GetComponent<Renderer> ().material.shader = Shader.Find ("GUI/Text Shader");
		}
	}

	void Update () {
		GameObject cube = GameObject.Find ("Cube");
		try {
			cube.transform.Rotate(1f, -1f, -1f);
		} catch (System.Exception e){
		}
		if (Input.GetKey (KeyCode.LeftArrow)) {
			GetComponent<Rigidbody>().AddForce (new Vector3 (-1f, 0, 1f));
		}
		if (Input.GetKey (KeyCode.RightArrow)) {
			GetComponent<Rigidbody>().AddForce (new Vector3 (1f, 0, -1f));
		}
		if (Input.GetKey (KeyCode.UpArrow)) {
			GetComponent<Rigidbody>().AddForce (new Vector3 (1f, 0, 1f));
		}
		if (Input.GetKey (KeyCode.DownArrow)) {
			GetComponent<Rigidbody>().AddForce (new Vector3 (-1f, 0, -1f));
		}
	}

	void OnCollisionEnter(Collision collision){
		if (collision.gameObject.tag == "Player"){
			Color c = collision.gameObject.GetComponent<Renderer>().material.color;
			c.a = 0.25f;
			collision.gameObject.GetComponent<Renderer>().material.color = c;
		}
	}

	void OnCollisionStay(Collision collision){
	}

	void OnCollisionExit (Collision collision){
		if (collision.gameObject.tag == "Player") {
			Color c = collision.gameObject.GetComponent<Renderer> ().material.color;
			c.a = 1f;
			collision.gameObject.GetComponent<Renderer> ().material.color = c;
		}
	}
}

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Menu

【メニュー編集】
Wiki記法ガイド

リンク

ゲームバー大阪心斎橋

ゲームバー大阪梅田

ゲームバー大阪心斎橋

ダーツ&ダイニングバー大阪梅田

メニュー

Unity


スマホ操作

Unity - GameObject

Unity - 3DCG

メンバーのみ編集できます