QueryちゃんをiPhone/AndroidをコントローラーとしてUnity秋葉原上空を飛行させる方法


はじめに
======

前回２つの合わせ技です。

* (A) [MacとUnity Free版を使ってZenrinさんの秋葉原上空をQueryちゃんがOculus DK2で飛ぶ、方法](http://qiita.com/mokemokechicken/items/e913558eba40f28dc9e2)
* (B) [iPhone/AndroidのブラウザからWebSocketを使ってUnityのゲーム操作を行う](http://qiita.com/mokemokechicken/items/16cd0921079d77f7e57c)

iPhoneやAndroidをリモコンとして、Unity内のQueryちゃんを操作したいと思います。

準備
====

* (A) の 「Unityの下準備」くらいまで行う
  * Scene はまたZenrinさんが付属しているSampleのシーンを使います
* (B) の `SmartPhoneInputController.unitypackage` を実行して、ProjectのAssetsに追加しておく

Projectの中身は下記のようになっていると思います。

![Sample_005339_08932_25_14_unity_-_QueryChan_-_PC__Mac___Linux_Standalone.png](https://qiita-image-store.s3.amazonaws.com/0/11124/19a8e44a-a2b7-4f1b-1652-acf88b791f68.png "Sample_005339_08932_25_14_unity_-_QueryChan_-_PC__Mac___Linux_Standalone.png")


Queryちゃんの動作を変更
===============

SmartPhoneInputControllerの配置
-----------

`Assets/SmartPhoneInputController/Prefabs/SmartPhoneInput` を Sceneに追加します。
また`SmartPhoneControllGUIText` も配置しておきます。

![Sample_005339_08932_25_14_unity_-_QueryChan_-_PC__Mac___Linux_Standalone.png](https://qiita-image-store.s3.amazonaws.com/0/11124/f160a7cf-768d-81f4-ecd7-70ce2dad8d59.png "Sample_005339_08932_25_14_unity_-_QueryChan_-_PC__Mac___Linux_Standalone.png")

FlyThroughController の修正
--------------

`Query-Chan_FlyThrough` に付いている `FlyThroughController` をダブルクリックして編集します。

![Sample_005339_08932_25_14_unity_-_QueryChan_-_PC__Mac___Linux_Standalone_と_ターミナル_—_screen_—_130×36.png](https://qiita-image-store.s3.amazonaws.com/0/11124/8402264f-6ace-1045-5b09-16baa920354c.png "Sample_005339_08932_25_14_unity_-_QueryChan_-_PC__Mac___Linux_Standalone_と_ターミナル_—_screen_—_130×36.png")

今回の修正は以下の様なものです。

* スマートフォン縦に持って、Screenを上に水平にした状態がニュートラルです。
* 左右にひねる、と 進行方向が回転します。
* 縦の先端を上に向けたり下に向けると、上下します。
* スマートフォンのScreenの上の方をTapすると前進（前に加速）して、下の方をTapすると減速します。
* 何も押してないとすこしずつ減速します
* あ、スマートフォンの「回転」はOSの設定でOffにしておいた方が良いです。

コードとしては`updateMove`メソッドを変更して、以下のようになります。

```csharp:FlyThroughController.cs(一部)
	void updateMove()
	{
		CharacterController controller = GetComponent<CharacterController>();
		
		// Rotate Right or Left
		var LR = SmartPhoneInput.PadGradX;
		var UD = SmartPhoneInput.PadGradY;
		if (Mathf.Abs(LR) < 0.1) {
			LR = 0;
		}
		if (Mathf.Abs(UD) < 0.1 ) {
			UD = 0;
		}
		if (LR != 0)
		{
			transform.Rotate(0, LR * ROTATE_SPEED, 0);
			if (LR > 0)
			{
				nowFlyingState = QueryAnimationController.QueryChanAnimationType.FLY_TORIGHT;
			}
			else if (LR < 0)
			{ 
				nowFlyingState = QueryAnimationController.QueryChanAnimationType.FLY_TOLEFT;
			}
		}
		else
		{
			this.transform.localEulerAngles = new Vector3(0, this.transform.localEulerAngles.y, 0);
			nowFlyingState = QueryAnimationController.QueryChanAnimationType.FLY_STRAIGHT;
		}
		
		// Rotate Up or Down
		if (UD != 0)
		{
			transform.Translate(Vector3.up * UD * ROTATE_SPEED *  Time.deltaTime);
			if (UD > 0)
			{
				nowFlyingState = QueryAnimationController.QueryChanAnimationType.FLY_UP;
			}
			else if (UD < 0)
			{ 
				nowFlyingState = QueryAnimationController.QueryChanAnimationType.FLY_DOWN;
			}

			if (this.transform.localPosition.y < groundCollider.transform.localPosition.y)
			{
				this.transform.localPosition = new Vector3 (this.transform.localPosition.x, groundCollider.transform.localPosition.y, this.transform.localPosition.z);
			}
		}
		
		// Move Forward
		Vector3 forwardSpeed = transform.TransformDirection(Vector3.forward * Time.deltaTime * speed);
		controller.Move (forwardSpeed);
		
		// Speed Control
		var acc = SmartPhoneInput.PadY - 0.05f;
		speed += acc * ACCELERATE * Time.deltaTime;
		speed = Mathf.Clamp(speed, 0, MAX_SPEED);

		if (speed == 0.0f)
		{
			nowFlyingState = QueryAnimationController.QueryChanAnimationType.FLY_IDLE;
		}
		
		// ChangeAnimation
		if (previousFlyingState != nowFlyingState)
		{
			QueryObject.GetComponent<QueryAnimationController>().ChangeAnimation(nowFlyingState);
		}
		
		previousFlyingState = nowFlyingState;
	}
```

実行
=====

実行すると、画面左上にURLが表示されるので、そこにスマートフォンのWebブラウザでアクセスすると、操作できるようになります。

![Sample_005339_08932_25_14_unity_-_QueryChan_-_PC__Mac___Linux_Standalone_と_ターミナル_—_screen_—_130×36.png](https://qiita-image-store.s3.amazonaws.com/0/11124/7e8a7476-2010-ddb9-96f8-5066f93f8832.png "Sample_005339_08932_25_14_unity_-_QueryChan_-_PC__Mac___Linux_Standalone_と_ターミナル_—_screen_—_130×36.png")



さいごに
=====

一応、自分の思い描いていたように作れたのですが、 **やっぱりなんか操作しにくい！** という感じです。
スマートフォンの左右エリアTapで左右回転も出来たほうが良いのかなぁ。でも、加速減速が間違えやすいからなぁ。

あと、やはり、 **弾かビームを出したい** ですね（＾＾