空飛ぶ箒

空飛ぶ箒とは

  • ワールド内に設置可能なオブジェクトで、椅子(VRC_Station)と箒(VRC_Pickup)で構成され、デスクトップモード/VRモードを問わず、プレイヤーはワールド内を飛行することができるようになります。

  • 本項で扱う空飛ぶ箒は、日計さん(@perceval_graal)のアイデアをブタジエンさん(@butadiene121)が具現化したもので、ブタジエンジンと呼ばれることもあります。

最初の動画

概要

原理
  • 箒に対して椅子をConfigurable Jointで接続することで角度を制御・追従させ、椅子に設定したConstant Forceを推進力として前進します。
    • それぞれのコンポーネントについては公式ドキュメントにリンクしてありますので、そちらを参照してください

問題点
  • 設定次第では酔いを引き起こすおそれがあるため、まずは初心者向けの設定で作成した後に調整していくことをおすすめします。

作り方

For those who can not read Japanese.
  • Welcome to this article. You can create a flying broom with google transrator and the video below.

VRChatで空飛ぶほうき(もどき)を作る方法 / How to make Flyingbroom in your world.

動画の通りに進めれば作成できますが、コメント欄にある2点を実施することをおすすめします。

以下、コメントより抜粋。
 椅子にオブジェクトシンクを追加(極めて重要 これで他プレイヤーからみたときのずれがなくなる)
 椅子の「Player mobility」をImmobilize For Vehicleに変更(がたつきをなくす)の2点

そのほか、各種設定や動画作成以降にVRCプレイヤー間で共有された情報は、以下を参照してください。



ワールド作成の初心者向け

床ができた状態からの説明です
  • 空のGameObjectの作成
空のオブジェクト.png
- 空のGameObjectにVRC_ObjectSyncを付ける
  • 作成したGameObjectのTransformのPositionを原点(0,0,0)にする

椅子の用意:動画の手順
  • Assets/VRCSDK/Prefab/Worlds/VRCChairをHierarchyにD&D
  • VRCChairのTransformのPositionを原点(0,0,0)にする
  • 必要に応じてTransformのRotaitionで向きを変える
  • PlayerMobilty:Immobilize For Vehicle
  • Ridgidbody、ConfigurableJoint、ConstantForce、VRC_ObjectSyncを追加、設定する
  • UseGravity:オフ

椅子の用意:自前のメッシュを使う場合
VRCChairのメッシュ部分.png
  • 椅子のメッシュを任意のメッシュに差し替える

椅子の設定:共通
  • 椅子の設定をできるところまで進める
  • 椅子をGameObjectにD&Dする(GameObjectの子になる)

箒の用意:動画の手順
  • Assets/VRCSDK/Examples/Scenes/Examples-Triggerをダブルクリック
TriggerCubeUseDown.png
  • TriggerCube-UseDownをコピー
  • Assets/作成中のワールドのUnityPackageをダブルクリック
  • Hierarchyにペースト
  • TriggerCube-UseDown/Canvasは削除
  • TriggerCube-UseDownのTransformのPositionを原点(0,0,0)にする
  • Positionの高さを調整する
プレイヤーがピックアップするには0.5程度の高さが必要です
  • TriggerCube-UseDownのTransformのScaleを変更して任意の形状にする

箒の用意:自前のメッシュを使う場合
  • 箒のメッシュをHierarchyに用意する
  • 必要なコンポーネントを追加し、設定をできるところまで進める

箒の設定:共通
  • RidgidbodyのUseGravityオフ、IsKinematicオン
  • VRC_TriggerのOnpickUpUseDown/UpにSetCompornentActiveを追加
  • ReciversにVRCChairをD&DしてCompornentにConstantForceを指定、Toggle動作にする
  • CustomをクリックしてOnpickUpUseDown/Upの片割れをAdd
  • 箒をGameObjectにD&Dする(GameObjectの子になる)

仕上げ
  • 椅子と椅子の設定を確認する
  • 初心者向けには、必要に応じて椅子側にConfigurableJointを追加してください
  • 出来上がり


要点
- 親のGameObject・子のほうき・椅子のそれぞれにVRC_ObjectSyncを付ける
  • すべて原点で作業してから親子関係を設定、任意の位置へ移動する

各種設定値と概要

椅子側
椅子側設定03210332.png
オブジェクト名は適宜読み替えてください

箒側
箒側設定03051710.png


初心者向け設定

初心者向け20180306.png
設定やプレイヤーの体調などの条件によっては酔いを引き起こすことがあります。
画像のように設定し、プレイヤーの視線と画面のずれを軽減することで改善が期待できます。

ほうき側は特に変更しなくてもかまいません。
また、ほうきの軸方向のangular motionをfreeにすることで酔いが軽減される場合があります。

運用面では、棒の先を見つめるように意識する、椅子や箒の先に目標物をつけることで進行方向をわかりやすくすると酔いにくくなります。

注意
  • 各種AngularをLockedにすると、固定されるどころか余計な力が働いて制御が難しくなってしまいます。
  • Low/High Angular X Limit に数字を入れると、かえって制御しにくくなってしまいます。


メモ

制作
- 椅子と箒はGameObjectの子にして、みっつそれぞれにVRC_ObjectSyncを付ける
  • 親子関係をつくるとき、椅子の向きを進行方向に揃えること
  • Buffer関係はすべてAlwaysBufferOne
  • Unityでは基本的に原点(0,0,0)で組み立ててから移動する
  • SkinedMeshを使う場合は自動であたり判定が付かないので、椅子になんらかのColliderを付けること
  • ConfigurableJointのAngular XYZ MotionはFreeで良い(つまり、Angular XYZ Limitも入力しなくて大丈夫)解説画像は修正済み

外観
  • 椅子と箒の機能を入れ替えれば、見た目どおり箒に座り、何らかのコントローラーを掴んで操作することができる
  • 椅子を魔法陣などにデザインすることで、椅子の見た目を解決することができる
  • 箒星のように尾を引く機能は、トレイルレンダラー等で実装できる
  • 椅子を半透明にするには、Materalsに適当なMaterialを作って椅子のメッシュに割り当て、Standardシェーダーを設定、Albedo項のカラーボックスをクリック、下の方にあるA(Alpha値)で透過率を指定できる

調整
  • 椅子側RigidBodyのDrag:0.8、ConstantForce:-30、AngularX/YZDrive:170 速いが扱いやすい設定
 Drag:0.8、AnglarDrag:500 あたりで旋回性能をさらに上げると良いケースもある
  • 動画ではOnPickUpUseUp/DownでConstantForceを制御しているが、Animationのほうが拡張性が高い
 具体的にはリニアな加速、外的要因による速度の増減などができるようになる
  • うまく掴めない、座れない
 Proximity(近接)で掴める距離を調整できる(数値を直接入力すると良い)
 20程度まで増やすと特にわかりやすくはなるが、VRだと反応が渋い
  • 椅子にSphereColliderを付けると床を滑れるようになる
 タイヤのように前後二つ付けるとバイクのような乗り物もできる(ただしそのままだと機首を上げると飛ぶのでUseGravityやConstantForceなど、何らかの工夫が必要)
  • 環境によってはトラッキングに悪影響があるため、X/Y/Z Driveは0のほうが良いケースもある
  • 椅子側RigidBodyのDrag(空気抵抗)を0にするとなかなか止まらなくなる 逆に、AnimationBool等でidle時にDragの値を大きくするとエンジンブレーキが組み込める
  • 椅子側RigidBodyのAngularDragは0で良い(旋回がもたついて酔いやすくなるのを軽減できる)
  • 椅子側ConfigurableJointのAngularXYZDriveは300から10000とかに思いきって増やしても大差がない
  • 酔いを軽減するには、プレイヤーの意図した通りに動くように調整すると良い

その他
  • 親のGameObjectにはObjectSyncなし、椅子とほうきが兄弟でObjectSyncあり、この状態ならTeleportToで呼び戻せる

課題

同期ずれ
  • 親子それぞれみっつにObjectSyncを付けてSpawnさせるとかなり安定するが、Ownershipの問題が生じるので、別項参照のうえワールドの合わせた解決策を講じてください
  • 直置きする場合は親のGameObjectには付けず、制御側と椅子側両方にObjectSyncをつけて妥協するのがおすすめ

椅子と箒の連結
  • ConfigurableJointのLinearLimitSpringを使うと前後にぎくしゃくする
  • ConfigurableJointのLock、FixedJoint、SpringJointで強力に接続すると荒ぶる

トラブルシューティング

箒が掴めない、椅子に触れない。
  • VRC_Triggerの設定が勝手に書き換わっている
  • ほうきのIsKinematicがオンになってない
  • ワールド直置きの場合、親のGameObjectにObjectSyncを付けるとワールドオーナー以外ほぼ掴めなくなる 参照:VRC_ObjectSync
  • MeshColliderを使うと判定の発生が渋くなるのでProximityを増やすかBoxcCllider等にする

ほかの人から見るとほうきとプレイヤーが離れて見える。
  • VRC_ObjectSyncを付け忘れている

椅子が勝手にすべっていく
  • ConstantForceのチェックを外し忘れている

自前のメッシュの座標について
  • Blenderで作成したメッシュをUnityに持ち込み、Position、Rotationを0,0,0にすると意図した角度にならない問題がある
  • Blenderでボーンを入れたうえでOriginを原点にし、位置や角度を調整してからFBXで出力する

ワールドで都度Spawnさせる方法

spawner.png
必要な部品
  • 生成したいGameObject(親のGameObject、子のほうきと椅子すべて)にObjectSyncを付ける。
  • Assets→右クリック→Create(ここでRenameすること)→Prefabをクリック。
  • Prefabに生成したいGameObjectをD&DしてPrefab化する。
  • SpawnObjectの呼び出し先として任意のPrefabを設定する
  • 必要に応じてSpawnerを出現先として設定する
  • 出来上がり

注意
  • 原則的に、Spawnさせたプレイヤー専用になりますが、稀にほかのプレイヤーも掴めることがあります。
  • GameObjectを付け忘れると正常に動作しません。
  • PrefabではなくGameObjectを指定すると、1回しか生成されず、移動もできません。

備考

掴めるプレイヤーを安定させる試み

問題
  • ワールド直置きで親のGameObjectにObjectSyncを付けるとワールドのOwner以外は基本的に掴めない
  • これをSpawnさせると時々掴めない個体がある

解決案1:Station
  • StationでOwnershipが移動していることが発見された
  • 親GameObjectをStationとして、OnStationEntered(OnInteractにUse/ExitStationをまとめても可)をトリガーとしたTeleportToを使ってGameObject(親子3つにObjectSyncをつけた箒と椅子)を呼び戻すことでOwnershipを移せるのではないか、という提案

結果とまとめ
  • 複数名でテストした結果、OnstationでOwnershipが移る個体と、同期ずれが大きくなって誰でもつかめる個体(箒の親につけたObjectSyncが壊れた?)と、OwnershipがOwnerから移らない個体が観測されました。

  • また、テスト環境ではメッシュの初期座標、呼び戻したときの座標などに拘わらず、椅子側が常に90度回転した状態で戻ってくる状況が観測されています。制御側に対してジョイントしているので向きは正常に戻るため、テスト環境では不都合はないのですが、複数のオブジェクトを呼び戻すといづれかの座標のRotationに問題が起こる可能性があります。

  • TeleportToの仕様(roバグ)により複数配置するときの座標管理が面倒なこと、箒から降りるときに(ExitPointかプレイヤー座標あたりに変な値が入っている?)プレイヤーが吹っ飛ぶことを考えると、VRC_Trigger SpawnObjectを使うのが今のところ最善のようです。ローカルで問題なく動作するならば、TeleportToで呼び戻すことにより制御と椅子の位置関係もリセットされますし、空中に放置されたりした個体をスイッチひとつで呼び戻せるところは実際便利ですので、TeleportToも選択しとしては検討に値すると思います。

解決案2:Stationの続き
  • https://twitter.com/butadiene121/status/974552205414952960
  • 正常個体と不良個体が完全なランダムではなく、決まった個体であることに着目した手法
  • 大量に複製した後、正常な個体のみをアクティブとして残す力技(10%程度が正常)
  • なお、非アクティブにした個体を削除すると正常な個体が変化するので削除はしないこと。
  • ワールド直置きで運用する場合は、選択肢の一つとして検討に値する。

解決案3:TakeOwnership
  • 制御側にAddしたVRC_TriggerでOnPickupを設定しActionを追加する+ボタンをクリック、EventFromScene→ObjectSyncの付いたオブジェクト一覧が表示されるので親オブジェクトを選択、TakeOwnershipが選択できる
  • これで誰でもピックアップできるようになる、はずだが挙動がStationを使った解決案とまったく同じで、Duplicateすると不良個体がまざり、解決するための方法も同様
  • おそらく、StationにはTakeOwnershipの機能が内蔵されていると思われる

親子にObjectSyncを付けた場合の複製

  • 組みあがったほうきをDuplicate、Prefab化してHierarchyに複数配置、親のObjectSyncを外してから複製して付け直し、いづれも同様の問題が起こる為、複製の方法ではなく最終的にSceneに配置された段階で優良不良が決定されていると思われる
  • そのため、必要数x10個ほど複製し優良個体を残す方法が有効(解決案2)

旋回性能について

  • RigidbodyのAngularDragが回転に対する空気抵抗で、これを小さくすると操縦桿の回転に対する椅子側の追従性が向上する
  • ただし、Drag(空気抵抗)を下げると旋回時にドリフトのように滑るようになるので他のパラメータと合わせた調整が必要
    • 例えば、本稿の設定例では500になっているが、100とか1にすると変化がわかりやすい
  • Angular X/YZ DriveのSpringに対してDamperの値を小さくすると操縦桿の回転に対する椅子側の追従性が向上する
    • 例えば、Spring:180に対してSpring:60等に設定するとハンドリングがクイックになる

要検証

旋回、追従
  • Driveの代わりにlimit springを用いる方法

Jointの向き
  • 箒と椅子、どちらにつけても体感できる違いが判らなかった

参考資料

ConstantForceを推進力とする部分は同じですが、Animatorを使うことでボタンを押して飛行船を操作する点が異なります。

応用例

応用例_01.png
  • 左:VRCChairをほうきのメッシュに差し替えたものと、制御側を本のメッシュとして作成したもの。
  • 右:VRCChairを自転車のメッシュに差し替えたものと、制御側を動かせる椅子+ハンドルとして作成したもの。
そのほか、車や飛行機など自由に差し替えて楽しむことが可能です。
もちろん、メッシュの形状などに合わせたConstantForceやDriveの値などの調整は必要になります。

VTOLタイプ
  • 前進、上昇と下降の3つをAnimationBoolで切り替えることで実現可能

ツインドライブタイプ(synqark氏制作)
  • 通常の箒/椅子に加えて、サブの制御用オブジェクトと、サブの推進用オブジェクトを追加したものです。
  • サブの制御側からPickUpUseUp/Downでサブ推進機のCFをオン/オフします。
  • 追加出力オブジェクトは椅子側にConfigurableJointで接続し、X/Y/ZmotionをLockedにします。
  • 追加出力オブジェクトからサブ制御にもConfigurableJointで接続し、AngularX/Y/ZMotionをLimitedにし、AngularX/YX/ZLimitは箒の制御と同様に177で埋めます。AngularX/YXDriveはとりあえず300で。数値は仕組みを再現するための暫定値なので、ワールドや乗り物に合わせて適宜調整してください。
  • 再現モデルでは追加出力オブジェクトにつけるCFの軸が変化していたので、作り方次第では軸を現物合わせで変更する必要があります。
  • すでにPublic化されていますので「testrun」でワールド検索すると出てきます

船(Melnus氏制作)
  • レシピと動画付き

バイク(ブタジエン氏制作)
  • ブタジエン氏制作のPublicワールド「Just Touring v2」に配置されている
  • 箒の応用で、CupsleColliderを車輪のように設定、ConstantForceで上から飛ばないように抑えている
  • v2でSynqark氏考案のSpawnシステム(OnEnterTriggerで多重生成を抑制)が採用された

縦型ツインドライブ(VoxelKei氏制作)
  • 両手の制御側と連動するよう椅子側にConfigurableJointで接続されたオブジェクトがあり、ConstantForceを推進力としている
  • 椅子にConstantForceはつかない
  • 椅子側をカスタムオーバーライドで直立させ、(おそらくFreezeRotationで)傾きも固定している
  • アレンジ例:https://twitter.com/adm_ygr/status/983107536399155201
  • アレンジ例(シングル):https://twitter.com/adm_ygr/status/983396427903582210
    • アレンジ例では右手制御側と椅子がConfigurableJointで連動、UseGravityが設定されている

配布モデルなど

箒モデルの配布があります。

とりあえず箒のモデルがほしいという方向けに用意したモデルです。

  • wrld_64599c91-16a1-4536-8fac-999c866c8ecf
screen_1920x1080_2018-03-13_16-09-48.991_.png
試作の箒がいくつかおいてあるテストワールドです。
まず触ってみたい方はこちらのワールドIDを使って体験することもできます。
このワールドの責任者および連絡先(@adm_ygr)
    • (Projectが壊れたのでこのワールドの更新はできなくなりました)

ワールドIDから起動できるリンクを作成できるサービス(https://twitter.com/kohack_v


コメント・情報提供

コメントを投稿するには画像の文字を半角数字で入力してください。


画像認証

  • 最終更新:2018-05-05 18:48:01

このWIKIを編集するにはパスワード入力が必要です

認証パスワード