今日は GAME ON へ行って PlayStation VR を体験した。The London Heist をしたのだが、流石にトラッキングは滑らかで自然だった。ちょっと HMD が重いかな?
今日の作業は以下
- DK2 モードを切り替え可能に
- 2つ目のステージとギミックを作成
- ステージ遷移の仕組みを作成
- 3つ目のステージとチェックポイントの仕組みを作成
3月13日
DK2 モードを切り替え可能に
初日に書いたように、DK2 と Gear VR では得られる回転の軸方向が反対のような挙動をするので、開発の簡便性のために、インスペクタから DK2 と Gear VR での適切な動作を切り替え可能にする。
BarController.cs に以下の修正を加える。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public bool DK2Mode; //切り替え用チェックボックス float XSensitivity = 7f; //左右の感度調整を可能に float YSensitivity = 5f; //上下の感度調整を可能に void Start () { //以下を Start 関数に追記する。 if (DK2Mode == true) { XSensitivity = XSensitivity * -1; //DK2 モードがオンの時、X軸を反転 } else { YSensitivity = YSensitivity * -1; //オフの時、Y軸を反転 } } void Update () { //Update 関数は最終的に以下のようになる。 pos = transform.position; cameraRotation = MainCamera.transform.rotation; pos.x = cameraRotation.y * XSensitivity; pos.y = cameraRotation.x * YSensitivity; transform.position = pos; } |
これで、ボタン一つで DK2 とGear VR の動きをチェンジできる。負荷もなし。ただし、これだとステージ毎に切り替えなきゃいけないので、数が増えてきた時に大変。そのうち単一のゲームマネージャで切り替えられるようにしないと。
2つ目のステージとギミックを作成
2つ目のステージには、プレイヤーを邪魔するギミックを入れる。今回は iTween Visual Editor というアセットを使用して、簡単にアニメーションを組む。
動かしたいブロックに iTweenEvent.cs をアタッチし、アニメーションの設定をする。
こんなもんで以下のように動きます。
ステージ遷移の仕組みを作成
Unity 5.3 より、シーン読み込みの命令が新しくなりました。名を SceneManager という。
上の GIF アニメで、赤いブロックがあることにお気づきでしょう。このブロックには「Finish」というタグを割り当てており、これに衝突した時に次のシーンへ遷移するようにします。
またまた BarController.cs にコードを追記します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
using UnityEngine.SceneManagement; //SceneManager 用の名前空間 public class BarController : MonoBehaviour { //シーン番号を管理 static int SceneNumber; void OnCollisionEnter (Collision collision) { //衝突時に、衝突相手の情報を取得するようにします。Collision 型の collision インスタンスです。 if (collision.gameObject.CompareTag ("Finish")) { //相手に Finish タグがついていた場合に ++SceneNumber; //シーン番号に1を加算し SceneManager.LoadScene (SceneNumber); //その番号のシーンを読み込む } else { _renderer.material.SetColor ("_Color", ChangeColorTo); //Finish でなければ今までどおり色を変えるだけ } } } |
簡単でした。今回、読み込むシーンを整数で指定していますが、どのシーンがどの番号になるかは、「File」→「Build Settings…」で管理されています。
ドラッグで順番を変えたりできるので、大量にレベルが生まれ、かつ一方通行であるパズルゲームなどでは割と使い勝手がいい気がします。
整数の代わりにシーンの名前をそのまま指定しても遷移できます。
3つ目のステージとチェックポイントの仕組みを作成
時間もあるし、調子よく進んでいるのが気持ちよくなって続きのステージを作ります。
首の可動範囲なんてものは限られています。広大な VR の世界を旅するためにはやはり移動を行うことが必要です。
3つ目のステージでは、チェックポイントに触れると一時的に棒のコントロールから開放され、視点移動を行う仕組みを作る…つもりだったのですが、棒の移動をカメラの回転からしか取っていないことが災いして、視点移動をしたはずなのに、棒の位置は初期のままという深刻なバグに遭遇しました。
よって、とりあえず今はステージの方を動かす(^^;)という怠惰な作戦に出ることにします。
まず、3つ目のなが~いステージを作成し、チェックポイントとなるブロックを置きます。これに CheckPoint タグを付加します。
空のゲームオブジェクトを作り、ステージを構成するブロックを全てその子オブジェクトとします。
またまた BarController.cs に追記します。OnCollisionEnter を以下のように書き換えます。コメントが有るのが追記部分です。
1 2 3 4 5 6 7 8 9 10 11 12 |
void OnCollisionEnter (Collision collision) { if (collision.gameObject.CompareTag ("Finish")) { ++SceneNumber; SceneManager.LoadScene (SceneNumber); } else if (collision.gameObject.CompareTag ("CheckPoint")) { //タグが CheckPoint の時、 Destroy (collision.gameObject); //ぶつかったオブジェクト(チェックポイント)を削除し、 MainCamera.GetComponent<PlayerController> ().enabled = true; //再びユーザー操作でバーを掴む機能をオンにし、 enabled = false; //自分自身(棒を動かすスクリプト)を停止します。 } else { _renderer.material.SetColor ("_Color", ChangeColorTo); } } |
更に、新しいスクリプト CheckPointController.cs をチェックポイントブロックに追加し、ここにステージの移動プログラムを書きます。BarController.cs にまとめて書いてしまわない理由は、チェックポイントの数が増えてきた場合に、チェックポイントのブロックごとに移動先を指定した方が管理が容易だと考えられるためです。それに、そろそろ BarController.cs がロングになってきた気がするし…
1 2 3 4 5 6 7 8 9 10 11 12 |
using UnityEngine; using System.Collections; public class CheckPointController : MonoBehaviour { public GameObject Level; //Level 親オブジェクトをインスペクタで指定 public Vector3 NextLevelTransform; Level 親オブジェクトの移動先を指定 void OnDestroy () { Level.transform.position = NextLevelTransform; //親オブジェクトを移動 } } |
お気付きの通り、これだと一瞬で移動したような感じになってしまいます。本当はフェードなり何か酔わなさそうでかつ移動したことがわかりやすい方法を試すべきなのですが、取り敢えず今日はここまで。
まとめ
BarController.cs の全体はこちら。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
using UnityEngine; using System.Collections; using UnityEngine.SceneManagement; public class BarController : MonoBehaviour { //シーン番号を管理 static int SceneNumber; // 衝突時の挙動 public Camera MainCamera; public Color ChangeColorTo; public bool DK2Mode; float XSensitivity = 7f; float YSensitivity = 5f; Renderer _renderer; void Start () { _renderer = GetComponent<Renderer> (); _renderer.material.EnableKeyword ("_Color"); if (DK2Mode == true) { XSensitivity = XSensitivity * -1; } else { YSensitivity = YSensitivity * -1; } enabled = false; //自分を最初に無効化する。カメラの PlayerController から有効化することで操作可能にする。 } void OnCollisionEnter (Collision collision) { if (collision.gameObject.CompareTag ("Finish")) { ++SceneNumber; SceneManager.LoadScene (SceneNumber); } else if (collision.gameObject.CompareTag ("CheckPoint")) { Destroy (collision.gameObject); MainCamera.GetComponent<PlayerController> ().enabled = true; enabled = false; } else { _renderer.material.SetColor ("_Color", ChangeColorTo); } } void OnCollisionExit () { _renderer.material.SetColor ("_Color", new Color (1, 1, 1)); } // 頭の動きを棒に反映させる Vector3 pos; Quaternion cameraRotation; void Update () { pos = transform.position; cameraRotation = MainCamera.transform.rotation; pos.x = cameraRotation.y * XSensitivity; pos.y = cameraRotation.x * YSensitivity; transform.position = pos; } } |
これでかなりゲームっぽくなってきました。しかし、現状ゲームのコアの面白さの部分に解釈の余地というか、プレイヤーが方法を選択する、発明する余地とか、そういうのがすっぽり無いため、進め方にバリエーションが出るような要素追加を将来したいなあと思うのでありました。
“Avoid The Walls 開発日記 3” への1件のフィードバック