<2018/6/9 VRGOの記事から移動>
今回は、Oculus Goのコントローラを傾けることで航空機を操縦するような制御をしてみました。
AirStrikeStarterKitというassetをベースに、自分でカスタマイズした空戦ゲームのプロジェクトを使いました。
元々は、昨年の2月くらいにiPhone向けのゲームとして作っていたのですが、あまりに操作性が悪いので放置していました。
前回のGoのタッチパッドを使った操作は、ググったら割と素早く検索できました。
今回もサクっと出てくるだろうと思ってたのですが、自分でコレだ!と分かるページをググるのに苦労しました。
やっと見つけたのが、Oculus公式のGearVR向けTech Notes(Aircraft Controls Using the Gear VR Controller)でした(英語)
英語ですが、GIF動画とサンプルコードを交えて非常に分かりやすい解説でした。
結局、以下のコードが最大のヒントになりました。
1 2 3 4 5 6 7 |
var controller = OVRInput.GetActiveController() & (OVRInput.Controller.LTrackedRemote || OVRInput.Controller.RTrackedRemote); if (controller != OVRInput.Controller.None) { var rotation = OVRInput.GetLocalControllerRotation(controller); FlightStickSimulation.CalculateYawPitchRoll(rotation, out yaw, out pitch, out roll); OVRInput.Axis2D primaryAxis = OVRInput.Axis2D.PrimaryTouchpad; throttle = OVRInput.Get(primaryAxis, controller).y; } |
controllerを取得した後、GetLocalControllerRotation()で回転角度を取得し、それをTechNotesで使われているフライトシミュレータのメソッドに引数で渡しています。
たまたま、AirStrikeStarterKitも似た様なメソッドがあったので、ここがGoコントローラの傾きを検知するメソッドだなと気づきました。
また、最後の2行はタッチパッドのy軸方向を使って、スロットル(ジェットの強弱)にしているのもそのままパクらせてもらいました。
AirStrikeStarterKitでは、ピッチ(x軸)、ヨー(y軸)、ロール(z軸)で渡す様になっていたので、以下の様に少し改造しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
if (OVRPlugin.productName == "Oculus Go") {//Goの時だけ //アクティブなcontrollerの取得 var controller = OVRInput.GetActiveController() & (OVRInput.Controller.LTrackedRemote || OVRInput.Controller.RTrackedRemote); if (controller != OVRInput.Controller.None) {//コントローラが存在すれば //取得したコントローラーから傾き(回転)角度の所得 var rotation =OVRInput.GetLocalControllerRotation (controller); //取得した角度をバラして飛行機の操縦用に調整(assetの調整なので、ここは自分のプロジェクトにあった調整をする) pitch =rotation.x *SpeedPitch;//ピッチ roll =rotation.z *SpeedRoll;//ロール yaw =rotation.y *SpeedYaw;//ヨー //取得したバラの角度をフライトシミュレータのメソッドの引数として渡す AddRot.eulerAngles = new Vector3 (pitch + ((1 - normalFlySpeed) * 0.5f), yaw, roll); } } |
多分、上記をFixedUpdate()に突っ込んで、Cubeか何かのオブジェクトに入れて、最後のAddRot.eulerAngles =の部分をtransform.Rotate()の引数に、Vector3()でpitch,yaw,rollの角度を現状の角度に加算するように渡したら、Goのコントローラで3DoFに回せるんじゃ無いかと思います。
上記、実際にUnityでシーン作って試したら、「角度に加算」なんて適当なこと書いてたことが判明したので、ちゃんとサンプルコード用意しました。
実際には角度を渡してやるだけでOKです。ただ、素のままだと遅いので、サンプルコードでは4倍で回してます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
void Start () { } void FixedUpdate(){ if (OVRPlugin.productName == "Oculus Go") {//Goの時だけ //アクティブなcontrollerの取得 var controller = OVRInput.GetActiveController() & (OVRInput.Controller.LTrackedRemote || OVRInput.Controller.RTrackedRemote); if (controller != OVRInput.Controller.None) {//コントローラが存在すれば //取得したコントローラーから回転角度の取得 var rotation =OVRInput.GetLocalControllerRotation (controller); //取得したコントローラーから傾きの取得:(傾きを使う場合は下の*4fは要らない) //var rotation =OVRInput.GetLocalControllerAngularAcceleration (controller); //回転させる:xがpitch、yがyaw、zがroll transform.Rotate (new Vector3 (rotation.x *4f, rotation.y *4f, rotation.z *4f)); } } } |
<追記>上記のコードを新規のC#スクリプトに書き込んで、適当にCubeオブジェクトと置いたらスクリプトを貼り付けます。
あとは、Oculus Utilityのassetに入っているOVRCameraRigをPrefabからシーンへ設置して、Cubeが見える位置に設置して完成です。
ちょっとジンバルロックしますが、とりあえずGoのコントローラの傾きを取得してオブジェクトを回すことができます。</追記>
で、空戦ゲームに組み込んだ結果、想像以上に楽しい遊びになりました!
Oculus GoとUnityがあったら、映画のワンシーンを再現みたいな感じで永遠に遊べそうですね。
ただ、AirStrikeStarterKitベースでは少々処理が重かった様で、まずTerrainがあるとガクガク、あと激しく首を振るとたまにと黒い枠が見えました。
残念ながら、このままではOculusストアではリジェクトされちゃいますね。
このコントローラは、ヘリに付けても楽しく遊べました。