ユニティちゃんの表情・モーション・ポーズが眺めれるようになりましたがまだまだ使い勝手に満足できません。
特にカメラ! 眺めたいために作っているのなら、せめてもっと自由に眺めたい!
今回はカメラ周りをどうにかしようと足掻いてみます。
どうするか
さて、自由に眺めれるようにするにはどうしたらいいか。今の状態だと、ボタンを押すと近づいたり遠ざかったりすることができますが、それならボタンを増やして上下左右の移動や回転を入れれば良さそうです。が、それだとボタンが増えて邪魔な感じがしますね。それと、最終的にはスマホアプリにして、いつでもどこでも眺めれるようにしたいと最初に考えていました。
なので、ここはスマホでの操作を意識してタッチジェスチャーで動かしてみようと思います!
- カメラのズーム(拡大縮小)は、「ピンチ」
- カメラの移動と回転は、「スワイプ」
これらの機能を実装してみます。
カメラのズーム機能
まずはズーム機能をボタン操作からピンチ操作に入れ替えます。
ピンチ操作はタッチ情報2つを取得して、2つのタッチ位置の距離が縮むか離れるかを見ればいいかなーと考えながら調べていたら、ちょうど良さそうな公式チュートリアルがありました!
TouchController.csを作って、チュートリアルにあるコードを貼り付けます。このコードは、確認済みバージョンが4.3なのでUnity5以降を使っている場合は手直しが必要ですが、コピペして保存した後にUnityエディタに戻るとアップデートを促す以下のようなダイアログが表示されます。(Unity5.3.5で確認)
Go Ahead!を選ぶと自動で使えるように直してもらえます。スクリプトはMain Cameraに貼り付けます。
Inspectorを見てみるとカメラのレンダリングモード毎にZoom Speedを設定できるようになっています。とりあえずそのままにしておきます。
どんな感じか見たいのでチュートリアルのコードのまま一度実機で確認してみます。カメラ操作用のCanvasは一度disableに。手持ち端末はiPhoneなのでXcodeプロジェクトを出力して実行。
gifだとわかりづらいですが実機でピンチ操作をしています。きちんと拡大縮小できていますね!
カメラの移動機能
次はカメラ移動の実装。
カメラ移動はスワイプした方向にカメラを移動させるだけですが、ユニティちゃんを中心に円移動させることにします。RotateAroundでカメラを直接動かそうかと思いましたが、もっと簡単な方法を取ります。
空のゲームオブジェクトを作ってその中にMain Cameraを入れることで、GameObjectを回転させればカメラも一緒に回ってくれます!
GameObjectは0,0,0に置いて、Main CameraにアタッチしているTouchController.csを以下のように手直し。
using UnityEngine; using System.Collections; using UnityEngine.EventSystems; using System.Linq; public class TouchController : MonoBehaviour { // 回転速度 public float rotateSpeed = 5.0f; // 移動速度 public float moveSpeed = 0.5f; void Update() { if (Input.touchCount > 0 && Input.GetTouch (0).phase == TouchPhase.Moved) { if (EventSystem.current != null) { // UIを最初に触った場合はタッチでの操作をさせない if (EventSystem.current.IsPointerOverGameObject (Input.GetTouch (0).fingerId)) { return; } } // タッチ数で処理を変える if (Input.touchCount == 1) { // タッチ数が1つの場合の処理 // タッチを取得 Touch touch = Input.GetTouch (0); // 画面を横にスワイプしたら親オブジェクトをY軸で回転させる this.transform.parent.gameObject.transform.Rotate (0, touch.deltaPosition.x * rotateSpeed, 0); // 画面を縦にスワイプしたらカメラをY軸で移動させる this.transform.position += new Vector3 (0, -touch.deltaPosition.y * moveSpeed / 10, 0); } else if (Input.touchCount == 2) { // タッチ数が2つの場合の処理 // タッチを取得 Touch touchZero = Input.GetTouch (0); Touch touchOne = Input.GetTouch (1); Vector2 touchZeroPrevPos = touchZero.position - touchZero.deltaPosition; Vector2 touchOnePrevPos = touchOne.position - touchOne.deltaPosition; float prevTouchDeltaMag = (touchZeroPrevPos - touchOnePrevPos).magnitude; float touchDeltaMag = (touchZero.position - touchOne.position).magnitude; float deltaMagnitudeDiff = prevTouchDeltaMag - touchDeltaMag; // ピンチ操作時はカメラの距離を変える this.transform.localPosition += new Vector3 (0, 0, deltaMagnitudeDiff * moveSpeed / 10); } } } }
まず、EventSystem.current.IsPointerOverGameObject (Input.GetTouch (0).fingerId)で、最初にタッチしたところがUIだったらreturnして以降のタッチ操作をさせないようにしています。スクロールビューのバーを動かすだけでクルクル回ってたのが邪魔だったのでこうしました。
タッチ操作のほうは、Input.touchCountでタッチ数が取れるのでタッチ数で処理を分けています。
タッチ数が1つだったらカメラの回転と移動を、タッチ数が2つだったらピンチ操作を行います。先ほど確認したズーム機能もなんか気に入らなかったので、カメラ位置を移動させるように直しました。localPositionのZ軸を動かすようにしないとワールド座標のZ軸を移動してしまうので、カメラの親であるGameObjectが回転していたときにおかしな位置に移動してしまうので注意。
moveSpeedは思ったより移動が速かったのでかなり小さい値にしています。
ぐりぐりと動かしてみる
出来上がったのがこちら。
カメラをぐりぐりと動かせることでユニティちゃんをもっと眺めやすくなりました!
左右のスワイプは回転ですが、上下のスワイプはカメラ移動にすることで、下から眺めようとする煩悩を抑えることに成功しています。(重要)
ひとまず最初に予定していた内容のアプリを作ることができました。ユニティちゃんを触り始めて2週間ほどかかりましたが、やりたかったことができて満足です!
が、ちょっと思いついたことがあるので次回それを実装してから、ユニティちゃんを眺めたいので頑張るのを完了にしようと思います!
この作品は、『ユニティちゃんライセンス』で提供されています。 |
コメント