ページ 11

Unity5 C#でのあたり判定について

Posted: 2016年8月24日(水) 16:53
by ito
ローグ風のダンジョン探索ゲームをUnityで実装したいと考えております。
Unityになれておらず、あたり判定について上手く理解できておりません。

やりたいこととしてはBoxCollider2Dがアタッチされている壁と当たった時に移動できなくしたいです。
スクリプトで上記の処理を書いているのですが、Update関数が終わってから
OnTriggerEnter2Dなどが呼ばれているため上手く実装できておりません。

こちら対処法がお分かりの方おりませんでしょうか。

Player・・・Rigidbody2D(Is Kinematicにチェック),BoxCollider2Dがアタッチ
Wall・・・BoxCollider2D(Is Triggerにチェック)がアタッチ

コード:

public class PlayerController : MonoBehaviour {

	float moveSpeed = 0.04f;
	Vector3 move = new Vector3 (0, 0, 0);
	Vector3 oldPos;
	bool moveFlag = true;

	void Init() {
		this.move = new Vector3 (0, 0, 0);
		this.moveFlag = true;
		this.oldPos = transform.localPosition;
	}

	// Use this for initialization
	void Start () {
		Init ();
	}
	
	// Update is called once per frame
	void Update () {

		//this.moveFlag = true;

		// キャラクターの移動
		this.move = new Vector3 (0, 0, 0);

		// 右
		if (Input.GetKey (KeyCode.RightArrow)) {
			this.move.x += this.moveSpeed;
		}

		// 左
		if (Input.GetKey (KeyCode.LeftArrow)) {
			this.move.x -= this.moveSpeed;
		}

		// 上
		if (Input.GetKey (KeyCode.UpArrow)) {
			this.move.y += this.moveSpeed;
		}

		// 下
		if (Input.GetKey (KeyCode.DownArrow)) {
			this.move.y -= this.moveSpeed;
		}

		if (this.moveFlag) {
			this.oldPos = transform.localPosition;
			transform.Translate (this.move);
		}
	}

	void OnTriggerEnter2D(Collider2D other){
		//this.moveFlag = false;
		transform.localPosition = oldPos;
		this.move = new Vector3 (0, 0, 0);
	}

	void OnTriggerStay2D(Collider2D other){
		//this.moveFlag = false;
		transform.localPosition = oldPos;
		this.move = new Vector3 (0, 0, 0);
	}

}


Re: Unity5 C#でのあたり判定について

Posted: 2016年8月25日(木) 04:21
by hide
まず、フィールド初期化後にInitでもう一度入れなおしている部分があったりと不安になるプログラムなのですが、
変数に関するその辺の基本的な知識は問題ないですか?

BoxCollider2Dを使ったものを普段触ってないので間違ってたらスルーしてくださいな。
BoxCollider2Dがアタッチされている壁と当たった時に移動できなくしたいです。
OnTriggerEnter2D等が呼ばれるのであれば、その瞬間にメンバ変数にフラグをたたて
フラグが立っていたらUpdateでキャラクターの移動をしないようにすれば即実装できそうには見えます。
ただ、それが望む動きかはちょっとわかりません。

Unity2DでRidgitBodyのKinematic使うのであれば、直接transformを動かさずに
RidgitBody2D#AddForceを使って、物理エンジン側に任せるのがよくあるやり方な気がします。
こっちは値をちゃんと入れれば物理っぽい動きをするはずです。
オフトピック
ローグライクなのに、物理エンジンであたり判定をするのはどういうゲームデザインなのか若干気になったりします。
マス目が基準なら自分で判定したいところな気がしますが、物理エンジン将棋とかあったしありなのかも・・・???

Re: Unity5 C#でのあたり判定について

Posted: 2016年8月25日(木) 15:10
by ito
hide様

ご回答ありがとうございます!
C++についてはある程度理解しているのですが、C#が初でして申し訳ございません。
Unityの関数がどういう流れで動いているのか上手くつかめていないのが問題ですね。

わかりにくい仕様で失礼しました。
ローグライク風と記載しましたが、マップがローグライク風のダンジョンとなっております。
移動に関しましては壁に当たらない限り360度移動できるようにしたいです。

各種セルが64px、プレイヤーが48pxとプレイヤーの方が若干小さめに設定しております。
こちらUpdateが呼ばれてからOnTriggerEnter2Dがよばれているみたいでして、
OnTriggerEnter2Dでフラグを立てても1フレーム遅れてしまい上手く実装できておりません。

そのため、当たったら移動をとめ、前のフレームの座標に戻すといった処理にもしてみたのですが、こちらもうまく実装できていなくて・・・。
わからないことだらけでも申し訳ないです・・・。

Re: Unity5 C#でのあたり判定について

Posted: 2016年8月25日(木) 21:43
by hide
それで、rigidbodyのAddForceはやってみましたか?このやり方は嫌、ということ?
あと、壁にIsTriggerつけると、トリガとしてしか機能しないので、この場合は外します。
Kinematic使うのであれば、直接transformを動かさずに
間違って記憶してたので、訂正。 IsKinematicつかうものはtransformですね。記憶がボロボロである。

Re: Unity5 C#でのあたり判定について

Posted: 2016年8月25日(木) 22:47
by ito
AddForceのやり方も試してみたのですが、滑らかな動きになってしまいまして・・・。
移動スピード3などで固定したいと考えております。

そこでUpdata内に以下の処理をいれてみたのですが、今度はすり抜けるようになってしまいました。
OnTriggerEnter2Dなどは当たった時に呼ばれているので、コンポーネントのアタッチ自体は問題なさそうなのですが・・・。

コード:

		// 右・左
		float x = Input.GetAxisRaw ("Horizontal");

		// 上・下
		float y = Input.GetAxisRaw ("Vertical");

		// 移動する向きを求める
		Vector2 direction = new Vector2 (x, y).normalized;

		// 移動する向きとスピードを代入する
		rigidbody.velocity = direction * speed;

Re: Unity5 C#でのあたり判定について

Posted: 2016年8月26日(金) 02:25
by hide
velocityを一定にしようが、AddForceでやろうが、特にすり抜けたりしないとおもいますが・・・
単純にisTriggerつけっぱなしになってるとかないですか?