読者です 読者をやめる 読者になる 読者になる

PSMoveでゲームを作る(2)

PSMoveについて、また少しわかってきました。

とりあえず、PSEyeなしではやはり位置トラッキングは難しいことがわかりました。

PSMoveには

加速度センサ(速度検知も可能)
地磁気センサ(PSMoveの向きを検知)
ジャイロセンサ(PSMoveの傾きを検知)

があるのですが、加速度センサでは位置トラッキングとしては精度が粗く、

地磁気センサでは、位置推定には使えず、

ジャイロセンサでは、PSMoveの動きを止めると値が0に戻ってしまいます。

加速度センサが一番使えるかもと思って、

acceleration*deltaTime =>速度を、

void FixedUpdate(){
transform.position = acceleration*deltaTime:
}

のようにしたわけですが、これだと、開始の瞬間が加速度0のため、PSMoveで位置トラッキングしたいオブジェクトが必ず原点に移動してしまいます。

別のオブジェクトの子にしてローカル座標として、なども試したのですが、ぶれも大きかったです。


そこで、結局方針を変えて、PSMoveはPlayerのコントローラとして使うことにしました。

PSMoveをジョイスティックのように地面と垂直に持ち、前後左右の傾きと同じ向きにPlayerが進むようにしました。

実際はOVRPlayerController.csにそれぞれ以下のように追加しました。

//enumで移動方向を追加
        public enum MoveDirection{MoveForward,MoveLeft,MoveRight,MoveBack,MoveJump,MoveDown}

//グローバル宣言で移動方向を追加
	private	bool moveForward = false;
	private	bool moveLeft  	 = false;
	private	bool moveRight   = false;
	private	bool moveBack    = false;

	private	bool moveJump = false;
	private	bool moveDown = false;

//途中の関数内で追加
public virtual void UpdateMovement(){
		bool moveForward = false;
		bool moveLeft  	 = false;
		bool moveRight   = false;
		bool moveBack    = false;
		bool moveJump = false;  //moveJumpとmoveDownは自分で追加
		bool moveDown = false;

 //元のGetKeyの下に追加。これを追加しないと、キーボードで一度でもWASDか上下左右の矢印を押すと、ずっとtrueで進み続けてしまう。また、moveJumpやmoveDownが効かなくなります。
             
		// WASD
		if (Input.GetKeyUp(KeyCode.W)) moveForward = false;
		if (Input.GetKeyUp(KeyCode.A)) moveLeft	 = false;
		if (Input.GetKeyUp(KeyCode.S)) moveBack 	 = false; 
		if (Input.GetKeyUp(KeyCode.D)) moveRight 	 = false; 
		// Arrow keys
		if (Input.GetKeyUp(KeyCode.UpArrow))    moveForward = false;
		if (Input.GetKeyUp(KeyCode.LeftArrow))  moveLeft 	  = false;
		if (Input.GetKeyUp(KeyCode.DownArrow))  moveBack 	  = false; 
		if (Input.GetKeyUp(KeyCode.RightArrow)) moveRight   = false; 
		if(Input.GetKeyUp(KeyCode.R)) moveJump = false;
		if((Input.GetKeyUp (KeyCode.V)) && !Controller.isGrounded) moveDown = true;
		//

・・・
}

//新規追加
public void setPlayerMoveDirection(bool flag, int directionEnum){
		
	switch(directionEnum){
	    case((int)MoveDirection.MoveForward):
		moveForward = flag;
		   break;
           case((int)MoveDirection.MoveLeft):
		moveLeft = flag;
	           break;
	  case((int)MoveDirection.MoveRight):
		moveRight = flag;
		   break;
	  case((int)MoveDirection.MoveBack):
		moveBack = flag;
		  break;
	  case((int)MoveDirection.MoveJump):
		moveJump = flag;
		  break;
	  case((int)MoveDirection.MoveDown):
		moveDown = flag;
		  break;		
	}			
}	

次にPSMoveを動かすスクリプト(ベースはUnimoveTest.cs)のUpdate関数に以下を追加しました。

//Forward
  if( move.Magnetometer.y >130 )   ovrPlayerController.setPlayerMoveDirection(true, 0);
  if( move.Magnetometer.y < 130 )  ovrPlayerController.setPlayerMoveDirection(false,0);
			
//Left
  if( move.Magnetometer.x >200 )   ovrPlayerController.setPlayerMoveDirection(true, 1);
  if( move.Magnetometer.x < 200 )  ovrPlayerController.setPlayerMoveDirection(false,1);
			
//Right
  if( move.Magnetometer.y >200 )   ovrPlayerController.setPlayerMoveDirection(true, 2);
  if( (move.Magnetometer.y < 200)&&(move.Magnetometer.y > 150) )  ovrPlayerController.setPlayerMoveDirection(false,2);
			
//Back
  if( move.Magnetometer.z >100 )   ovrPlayerController.setPlayerMoveDirection(true, 3);
  if( move.Magnetometer.y < 100 )  ovrPlayerController.setPlayerMoveDirection(false,3);			

まだ調整は必要ですが、各数値は実際にセンサの値を調べて、今回のケースで使えそうと判断したものです。

このスクリプトもOVRPlayerControllerにアタッチして、プロジェクトをコンパイルして起動すると、PSMoveを傾けることでOVRPlayerControllerが動きます。


移動を止めるときは、PSMoveを地面と垂直に持ち直して下さい。


次はここから弾を発射する処理を作りました。前回のスパイダーマンもどきと同様に、照準をOVRPlayerControllerのleftCameraでOnGUIで描画し、この照準の位置から弾を発射させます。


続きはまた後日書こうと思います。

広告を非表示にする