【Oculus】OVRPlayerControllerで自由に空を飛ぶ方法【ゆるふわコピペ】【SDK0.4.4】 - ReDo

2014年12月13日

【Oculus】OVRPlayerControllerで自由に空を飛ぶ方法【ゆるふわコピペ】【SDK0.4.4】

yukihane-party.png

おはようございます。youten@ゆきはね13式サンタさんがかわいすぎるんじゃああああです。

このエントリはOculus Rift Advent Calendar 2014の12/13のエントリです。

<確認環境>
Win8.1 MSI GS60(GTX870M)Extend Mode
Unity Free 4.6.0p1
http://unity3d.com/unity/qa/patch-releases
Oculus SDK 0.4.4 Beta
https://developer.oculus.com/downloads/

ovrplayer1.png

<本エントリの目的>
Oculus Rift SDKのPrefabsには固定向けのOVRCameraRigと、動作キャラ用のOVRPlayerControllerというものがあります。
GamePad等で自キャラを自由に動かしたい際には、OVRPlayerControllerを設置する必要があるのですが、Toscanyデモがごとく、FPSな視点で地上を歩く想定した作りになっており、「空中を自由に飛び回りたい」と言った際には私の様なUnity初級者にはなかなかハードルが高いスクリプトです。

バージョンが固定できるのであれば1回つくって入れ替えてしまえば済むのですが、今後に備えて備忘録代わりに理解したことをメモっておくことにしました。

<OVRFlyingPlayerController.cs>
本エントリで変更した初期値・コードを最初っから適用した空飛ぶカメラのためのOVRFlyingPlayerController.csもおいておきます。
OVRFlyingPlayerController.cs
flying.png
チマチマ編集が面倒な際などに、OVRPlayerContollerスクリプトと入れ替えの上、本エントリを参考にお使いください。

sphere1.png

1. Inspectorのプロパティで初期位置を設定。

ovrplayer2.png

OculusUnityIntegration.unitypackageをダブルクリックし、Importします。
適当にCube床とSphereオブジェクトを配置した後で、OVR>Prefabs>OVRPlayerControllerをHierarchyに配置します。

カメラの初期位置がちょっと離れているので、Positionは0,0,-2、Rotationは0,0,0に修正します。
おもむろに再生するとOVRPlayerControllerが重力にしたがって無限に落下します。

OVRPlayerControllerを選択し、Inspectorから「OVRPlayer Controller(Script)」のGravity Modifier(重力)を0に、Use Profile Heightのチェックを外します。

ついでに、自由に飛び回るのに小さな妖精にでもなったつもりで、Character ControllerのRadiusとHeightを0.2, 0.2ぐらいに縮めておきます。

もう一度再生すると、少なくとも落ちなくはなっていると思います。


2. 「接地していたら」条件をすべて無効にしよう。

ここからは実際にScriptを編集していきましょう。OVRPlayerControllerは名前の通りのOVRPlayerController.csというスクリプトに概ね関連する機能が集められています(他のスクリプトは移動に関してはあまりいじる必要はないでしょう。)

「Controller.isGrounded」というのがそのままコントローラが接地していたら、という条件です。地面についていない限り前後左右に移動できないつくりになっていますので、L217-L219あたりをコメントアウトしましょう。

また、FPS的なゲーム性を考慮して「前に進むときに比べて横や後ろに移動するときは遅くする」という機能がありますが、これも自由に飛び回るには邪魔なので、こっちはInspectorから「Back And Side Dampen」というプロパティを、比率なので1.0に設定します

    // No positional movement if we are in the air
    //if (!Controller.isGrounded)
    //  MoveScale = 0.0f;

これで、キーボードではWASD、XBOX360コントローラでは左スティックで前後左右には自由に移動できるようになったと思います。


3. 左右回転をもう少しなめらかにしよう

首を振れば左右キョロキョロはできるのですが、キーボードではQ/E、XBOX360コントローラであればLB/RBで回転します。
が、これもFPS的に「1回押したら指定角度まわる」という感じで気持ち悪いです。

XBOX360コントローラの右側スティックの様な回り方が理想だと思いますので、キーボード向けにQ/Eをそう直してしまいましょう。
InspectorのRotation Ratchet(回転角度単位)を初期の45(度)から1とか2あたりにしてしまいます。
スクリプトはfire1回だけ判定するInput.GetKeyDownを「押している限り」にするためにInput.GetKeyに変更します。実際にはL260-265が以下のようになります。

    //Use keys to ratchet rotation
    if (Input.GetKey(KeyCode.Q))
      euler.y -= RotationRatchet;
    
    if (Input.GetKey(KeyCode.E))
      euler.y += RotationRatchet;

これで、Q/Eキーによる回転がなめらかになっていると思います。


4. 上下移動を入れよう

続けて、高さ上下移動を入れます。上下に関しては、もとのスクリプトがリアリティを重視しているため、基本的には重力にそって落ちたり、接地しているときのみジャンプできたり、の様な仕組みが入っているのですが、そのへんを一切無視して、いいから上下に移動できるようにします。L178-L179にController.Moveという移動が入ってますので、その手前にキーに応じた上下移動を足しましょう。

    // up/down
    if (Input.GetKey (KeyCode.Z))
      moveDirection.y = 0.01f;
      
    if (Input.GetKey (KeyCode.X))
      moveDirection.y = -0.01f;
    
    // Move contoller
    Controller.Move(moveDirection);

これでZ/Xキーでup/downができるようになったと思います。

XBOX360コントローラにも同様のものを入れたいのですが、ここで個人的な好みによりLB/RBの両肩キーを、回転から上下移動に入れ替えたいと思います。LRはVRGamepadController.Button.LeftShoulder、BRはVRGamepadController.Button.RightShoulderという定義名になってますので、以下のL250付近をまずざっくりとコメントアウトし

    Vector3 euler = transform.rotation.eulerAngles;
    
    //bool curHatLeft = OVRGamepadController.GPC_GetButton(OVRGamepadController.Button.LeftShoulder);
    
    //if (curHatLeft && !prevHatLeft)
    //  euler.y -= RotationRatchet;
    
    //prevHatLeft = curHatLeft;
    
    //bool curHatRight = OVRGamepadController.GPC_GetButton(OVRGamepadController.Button.RightShoulder);
    
    //if(curHatRight && !prevHatRight)
    //  euler.y += RotationRatchet;
    
    //prevHatRight = curHatRight;

さっきのup/downにLB/RBキーの条件も加えてやります。

    // up/down
    if (Input.GetKey (KeyCode.Z) || OVRGamepadController.GPC_GetButton(OVRGamepadController.Button.LeftShoulder))
      moveDirection.y = 0.01f;
    
    if (Input.GetKey (KeyCode.X) || OVRGamepadController.GPC_GetButton(OVRGamepadController.Button.RightShoulder))
      moveDirection.y = -0.01f;
    
    // Move contoller
    Controller.Move(moveDirection);

ここまでくればだいたい自由自在に飛べるようになったと思います。

5. すり抜けよう

すでに気づいてる方も多いと思いますが、これだけでは地面などの他のオブジェクトはすり抜けられません。妖精さんであればむしろ正しいのですが、ここは幽霊になってみましょう。Unity的にはお互いに物理的に干渉しない別Layerを設定するだけです。

ghost1.png

Edit->Project Settings->Tags and Layersを選択し、User LayerにGhostというLayerを追加します。

ghost2.png

Hierarchyに戻って、OVRPlayerControllerのLayerをGhostに変更します。子孫も一緒に幽霊になるかい?と聞かれますので、Yes, Change Childrenを選択しましょう。

ghost3.png

最後に、Edit->Project Settings->Physicsを開き、Layer Collision Matrixを編集し、物理世界と幽界が干渉しないようにします。一応幽霊同士は触れるようにしましょうか。

地面をすり抜けてどこまでも下がることができたら成功です。

yuka.png


それでは皆様、自由に壁・地面・天井になって良いクリスマスをおすごしください!

コメントする