
NeosVR開発記録
はじめに
Unity(C#)エンジニアがNeosVRで基礎学習で作ったものと、その後の作品を記録したものである。
開発中の写真撮影をする習慣があまり無いため、後から撮影したものも多い。

基礎学習
ゲーミングキューブ
見た目に変化があり、少ないLogixノードで作れるということで、最初に手を付ける。
初めてのノードプログラミング。
ノードの追加方法やパッキング方法を学ぶ。

音のなる箱
Pulseと言う概念を理解するために持ったら音が再生される箱を作成。

とりあえずゲームを1つ作ってみる
Unityの基礎学習のために、ブロック崩しを作ることはよくあると思う。
ゲームは、小さな機能を多く持ち、モチベーションを維持して様々な学習を行うことが出来るものであると考えている。
他人の開発作業を見ていて、GetPixcelに相当する機能が作れるということから、スプ〇トゥーン風のペイント銃を使った色の塗りあいバトルゲームを作成することにした。
他開発環境であれば、ワールドとして作ることが望ましいものであることは承知の上で、NeosVRでは持ち運べるアイテムとして作成をした。
他人の開発ワールドで作業したり、わからない所を聞くときにその場で取り出せたり、完成後の配布が容易になるなど、様々なメリットがあった。
必要そうな機能を書き出し、簡単そうなところから順に手を付けた(つもり)。
初作品であり、NeosFesta2への投稿作品。
タイマー
戦闘時間を制御する開始、停止、リセットだけの簡単なタイマーを作成。
ストップウォッチのアイテムがあったため、参考にして作成した。
後に、既に塗られているところに上塗りするためのシステムをタイマー連携させた。
弾の出る銃
トリガーを引くと弾となるプレハブを複製して射出するシステムの作成。
ここまでは簡単だったが、その後の弾道計算などでかなり複雑になることに・・・
RigidBodyが無いため、重力などから算出して物理挙動しているように見せる必要があるため、初期学習には向いていなかった。

銃の魔改造
ここから異常に難易度アップし、色んな人に助力いただいた。
プレイヤーに当たるとその人が倒された判定をする機能の追加。
(HPシステムは更なる複雑化必須だったため、難易度の都合で一撃必殺)
自分が撃った全ての弾の弾道計算の追加。
弾が消える前に銃アイテムが消されたときに、弾が残らないようにするなどの異常処理。
高頻度で複製する弾にLogixを入れないように出来る限り銃本体に処理させるように変更。
などなど
色を塗る方法(カメラフィルターとUV座標)
カメラフィルターを使ってエリアごとに色の強さを変更する方法の検討。
UVメッシュ座標の取得方法の検討。
カスタムシェーダーを使用できないNeosVRでは、SetPixcelに相当するものが存在しなかったため、平衡投影のカメラで撮影したRenderTextureをステージのテクスチャとして使用することにした。
NeosVRに存在するLogixとComponentを組み合わせてUnityから移植するような作業の連続になった。
マップはメッシュの実面積の割合をそのままUVの面積にすることで、どこを塗っても基本的に同じだけの面積が塗れるようにした。
つまり、自作の3Ðマップ。
ノードは少なく、Unity知識が大半の為、Logixノード学習初期にすることではないなと思った。

スコア計算(GetPixcel)
UV座標を100×100マスに分割し、GetPixceに相当する処理を行う。
RGBAが取得できるため、RedとBlueの2色に限定し、その座標のRとBの値によってどの程度色が塗られているかを判定するようにした。
自力で100×100マスの走査をForループする際の処理が書けず、大いに手伝ってもらったという思い出がある。
この辺りから、DynamicVariableでそれぞれの処理を分割し、連携を始めている。
DynamicVariableについても、当時はあまり資料が無かったため、色々とお世話になったと思う。

点数のビジュアル化
点数を割合に直し、Scaleに対応させただけ。
とりあえず完成したもの
数は多く見えるが、同じ処理が繰り返されているだけで、後から見返すとそれほど多くは無い。
設計不足で行き当たりばったりの開発をしたため、機能毎に分けきれなかったり、再利用できずに同じノードを多数繋いだりした部分があるだけだった。

銃の中に弾の挙動計算を出来る限り委託したため、ちょっと多めで、1フレーム内で弾の数だけループする処理が含まれることもあり、デバッグが非常に難しい。
後から手を加えたりしたくない部分。

弾にはLogixから読むことが出来るパラメータとしてTimeを持っているが、Logixノードは未使用。撃った数だけ増え続けるので最小限に抑えた。
Slot数は増え続けるが、弾の着弾毎にテクスチャベイクやメッシュベイクをすると負荷が高すぎたので没。

床などに当たった弾をUV上に移動した後のRenderTextureなど。
時間経過で奥行き方向に移動することで後から塗った色に上塗りできるようになっている。

ちょっぱやワールド作成に参加
稀に突発的に発生する数時間でワールドを作るイベントに何度か参加した。
基本的に1からLogixを組むことは少なく、既存アイテムの改良をして配置することが多いが、足りないモデルやちょっとしたギミックはその場で作る。
最適化や保守性などは度外視で、それぞれの人が自分が出来ることをして、人数で殴るパワークリエイトスタイル。
1人で作ったらどれほどかかるか分からない規模の完成品ができるため、満足度が高い。何を作ったかも覚えていない。


魔法スキル詠唱システムにスキルを追加
他人の作成したLogixの解析
SAOに登場する魔法を音声認識させて発動させることができるアイテムの改良。
前に倣えで魔法の種類を3つ追加。
内2つを合体させるなど機能の拡張。
Chromeの音声認識からNeos内に文字列として投げてくれる部分と既存魔法には手を加えず、比較的低コストで拡張できて、満足度は高かった。

ソードスキルシステム
魔法を作ったら、ソードスキルも作りたくなるのは自然な流れ。
プレモーション位置で指定秒数構えた後、刃の方向に一定速度以上で振ると単発ソードスキルが発動する。
プレモーション位置に合わせて構えるには多少の修練が必要。
もちろん、システム的モーションアシストは発生しないので、刃の方向へは自らの意思で振る必要がある。


当時はまだ動画編集に手を出していなかった様子。
無編集動画のみ残っていた。
他人を酔わせるためのハンマー
ランダム方向にランダム速度で予測できないグラグラとさせるだけのアイテムを作成。VR酔いし易い人にとっては危険物。
Logixは深夜テンションで一晩で作ったはずなので、処理の分割などせず1繋がりのノード群。
ユーザーをワールド固定したSlotに入れて揺れが収まったら元の場所に返すなど、他人のアバターの視界を揺らすためのシステムが結構多めだった。
1軸の揺れでは全然酔わなかったため、3重構造くらいにしてランダム性を高めている。
ここで初めてロコモーション(移動設定)の強制変更に触れたと思う。

ランダムマップ生成(処理が重いため未完成)
ランダムマップ生成を試みたが、配列が無いので文字列で代用した結果、20×20マス程度の初期化だけでも10秒以上かかってしまうなど、実用に耐えられないものになってしまったため没。

東京23区マップ
ProjectPLATEAUで公開してくれているマップをいれて、そこにプロジェクト投影しただけのもの。必要部分のみ切り取って使えるようにしたかったため、ベイクせずに入れたもの。Logixは未使用。

Join同意書アイテム
ワールドに入ってきた人に、別レイヤーで配信中や動画撮影中であることを伝えるギミックを表示するアイテムの作成。
配信者などが安心して生配信できるようになることを目的としたアイテム。
いつか必要になるくらいNeosが賑わってほしいと願って作ったが、今のところ必要とされていない。

魔法用スプライトマップ製作機
パーティクルモリモリで魔法を作ったら重かったので、軽量化するため、SpriteTextureを自動撮影してくれるアイテムを作成。
自分で使う専用のため、いくつか軽度のバグ(仕様)が残っていたはず。


ルーンメイジロッド
OrbusVRの魔法職を模して造られた文字認識で魔法が撃てる杖の作成。
文字認識部分は他の人に作って貰った外部API連携を使用している。
自分が何を改造したか忘れた。

ランダムピックアップ
ランダム文字列が欲しかったので、ルーン文字26文字からのランダムピックアップを作成。
重複有りのランダムピックアップをして複製するだけ。
UIXを使用して、何文字のランダムオブジェクトとして生成するのか指定できるようにしてみた。

たったこれだけ。
非プログラマにはForループが少し理解しにくいかもしれないが、
初期学習にも良さそう。

壁を避けて向かってくる敵AI
コライダーを避けて追って来てくれる敵AIの作成。
コライダー1つなら良い感じに避けてくれるが、2つ以上のコライダーに挟まれたりすると狙った挙動をしてくれない。
また、雑魚1体の移動ギミックとしては処理が多すぎる。

ねるねるねるね作成RTAストップウォッチ
駄菓子会で突如ねるねるねるね作成RTAが開催された。
その場でノードを取り出しただけ。
わかっている人達がその場で使うだけなら、動けば良い。UIXなんてものは無かった。
難しいことはしていないし、日常の一コマではあるけど、無ければその場で作れる環境っていいよね。Neosっていい環境だよね。と言うだけ

魔法のインストーラー(習得システム)対応
他の人がアドオンシステムを作ってくれたので、魔法を習得するようなイメージでインストールシステムに組み込みをしてみた。
それぞれのシステムをモジュール化したりしたので、整理が結構大変だった。


魔法で的当てゲーム
NeosFesta3への投稿作品。
これまでに作ったものを多数かけ合わせてゲーム性を追加。
そもそも文字認識で魔法を撃つことが難しいので難易度が異常だった。


壁を避けて向かってくる敵AIを少し改造して、敵の弱点属性など、バンバン倒される雑魚に適切なパラメータなどを付与したもの。

ソードスキルの改良とインストーラー対応
魔法と同様にソードスキルも習得できるようにインストーラー対応。
何度も同じ動作を行うことで、オリジナルのソードスキルを習得出来たりしそうだなと言う妄想。実現はしていない。

AerialGuardian(MMC)
初の大規模チーム開発。
PvEのタワーディフェンスゲームを10人以上で開発。
会議・モック・開発などほとんどの作業が共有空間での作業。
全体を見ながら、シーン遷移とパラメータの受け渡しなど、皆が作ってくれたものを繋げる部分をメイン担当した。

シーン遷移周りのロジック。
後で見返したり、他人が読んだりすることを前提に比較的綺麗に並べた。
シーン遷移で初期化などの各処理を呼び出すDynamicInpulseを管理するLogix群。

他の人が作った敵のロジック。
移動ロジックだけじゃないけど、壁を避けたりしなくても敵1体に対してこれくらいのロジックは必要・・・
いっぱい出現させると重い。

GAS連携のプレイヤー明記リスト(MMC)
いつかNeosが繁栄して、10000人埋まることを夢見て、
黒鉄宮の石碑を模した1万人までプレイヤー名リストを明記できるファンワールドを作成。
特定の所有アイテムを破棄すると死亡判定とし、永遠に名前に取り消し線が引かれるというギミック入り。
100人ちょっとしかアクセスされていないので、これだけしか記名されていない。現在は新規ワールドに埋まり、GAS連携部分がいつの間にか壊れてしまっていたので動作していない。いつか直したい。

1万人明記されたらこんな感じになるはずだった。

お好み焼きを切り分けるシステム
コライダーヒット時にスライサーで任意の場所をカットするだけのシステム。
Neosのスライサーでは断面が空洞になってしまう。悲しい。

心拍連動集弾システム
AerialGuardianで使用した銃を抜き出してきて、GGOで登場する心拍に応じて集弾性能が変化する銃の作成。
心拍センサーの値から鼓動の速さを割り出し、鼓動に合わせて照準が拡縮する。それだけだと早くても最小に収縮した時に撃てば良いだけになってしまうので、心拍数によって、最大最小サイズも可変にした。
弾はトリガーを引いた瞬間の照準内のどこかランダム方向に射出する。
人によって通常時の心拍数が異なるので、ゲームに組み込むにはかなり不公平感があったが、面白いとは思う。
安価なVR機器に心拍センサーが標準搭載されたら採用するゲームは出てくるかもしれない。

心拍連携と照準だけならLogixはこれだけ。
他の部分はそのまま流用。(ワールド側に一部処理が入っていて抜き出すのは少し大変だったけど)

パンを焼くシステム
週末に数時間で作るグローバルなクリエイタージャムイベント。
小麦がお題だったため、気合入れて作った。
小麦粉を捏ねて成型して窯に入れて焼くとバタールみたいなものが作れるようにした。
状態遷移でシェイプキーを弄ったり、オブジェクトの表示を入れ替えたり、マテリアルを差し替えたりする。正規手順有りのお料理的なもの。



ボウリング
実験的物理挙動が実装されたので、ボウリングのシステムを作成。
ボールを物理挙動させて投げる部分など最初期のベースは他の人が作ったものだったりする。
特に設計などせずに思いついた所から実装していった結果、
ピンが倒れた判定や、スコア計算システム、10フレーム目の挙動など、思ったより大変なことが多かった。
投げた人に物理計算をさせているので、割といっぱい並べても動作に支障は無かった。
並べるピンの数は最大6列(21本)まで増減可能にして倒した時の爽快感UPなど、おふざけモード搭載。
ボウリング大会を開催して完成後も比較的楽しんだ。
ただし、Neosの民はおとなしく1Gプレイさせるのは困難。

ゴルフ的な感じで遊べるように曲がりくねったレーンも作成。
テキトーにゆがませただけの計算されていないカーブなのでストライクを取るのは結構難しい。
システムには一切手を加えていない。

無限シリーズ
無限羊羹
楊枝で切った場所で切断可能で、挿して食べることが可能だが、時間経過でいつの間にか元の長さまで戻っているという、無限に食べられる羊羹。
スライサーと異なるところは、キューブのスケールでカットしているため、断面が存在すること。
ただし、伸縮してしまうため、テクスチャは当てられない。
意外とLogixは多め。


無限フルーツポンチ
掬って食べられるようにしたが、減ることは無いので無限に食べられるフルーツポンチ。
フォトグラメトリで撮影したフルーツポンチを適当なお皿に盛り付け、掬ったり食べられるようにした。
コライダーHitで表示非表示を切り替えているだけ。

心拍連動イライラ棒
心拍連動アイテム第2弾。
ランダム迷路生成コンポーネントで生成したコースの壁に棒が当たらないようにスタートからゴールまで持っていく簡単なゲーム。
心拍に応じて勝手に棒が微振動するギミックが含まれている。
何のために作ったのか忘れた。

マネ壁(MMC)
多人数のチーム開発2回目(?)
迫ってくる壁に当たらないように穴のポーズをとるゲームの作成。
フルボディトラッキングで遊べるゲームが欲しいと需要で作った。
シーン遷移やモデリングなどは他の人に任せ、当たり判定システムや、壁生成ギミックなど、ゲームのメインロジックを担当した。
4人くらいで作ったのでそれなりに時間はかかった。
ケモノが多いため、当たり判定はアバターのメッシュではなく、トラッキングしているポイントだけにするなど、ユーザーのニーズに合わせた設計にできたと思う。


視力が良くなるかもと言われていたものを試作
現実でこんな視界になるメガネをかけたら視力改善効果があるという論文を見かけたので試作。
邪魔だったので使っていないので効果のほどは不明。

オーディオソースリサイクルシステム
Neosではオーディオソースの上限に達して音が聞こえなくなることが割と発生するため、頻発するSE用にいくつかのオーディオソースを使いまわすようなシステムを作成。
導入が面倒で結局ほとんど使っていない。
プラットフォーム側でよしなにしてほしい内容。

ペイントシューターV2
最初に作った作品の大改修。
ステージの作り直し、銃の作り直し。
チームシステムや銃の種類など機能の追加など、某ゲーム発売日を締切として決め、できる限りの改修を行った。
速度重視で開発したので、細かいことは覚えていない。

LegendarySushiMaster(MMC)
大規模チーム開発3回目。
と言っても、Logixは自らは触らず、3Ðモデル作成や全体的な雑用に回ってみた。ほとんどの処理を外部で行い、InputとViewだけNeos内でLogixで組んでいる感じ(らしい)。

湾曲HPバーの検討
湾曲したHPバーを試してみた。
敵のHPを画面固定ではなく、空間上に置くとき、ペラペラな2ÐHPを採用されているVRゲームが多い。
ペイントシューターや壁を避ける雑魚敵は円柱で3ÐのHPバーを採用していたが、斜めから見た時に直感に反するのでHPと感じていた。
結論。見にくい。形状も工夫してみたが、残りHPが直感的に見えない。
NeoGurrah
剣戟ゲームの模倣と改良
Swords of Gurrahについて
UE4で作られたVR剣戟アクションゲーム。
いくつかの公式ルールがバグで遊べないが、
毎週金曜日、日本ユーザーが剣道などのような形で戦う1対1でPvPを行う修練の場を設けてくれている。
Asiaサーバーが用意されており、ラグも比較的少なく、快適に遊ぶことが出来る。
現在のVR機器では触覚フィードバックの都合上、鍔迫り合いを表現することが非常に難しいが、刀身が折れるというシステムにより、納得感のある近接戦闘が楽しむことが出来る。
NeoGurrah製作の動機など
人が少ないことが課題だと感じたため、非公式ファンメイドアイテムとして戦闘システムをNeosに再現し、気に入ってくれた人に本家Swords of Gurrahを布教するために作成した。
戦闘システム挙動と、基本武器のGreenSwordの形状は本家から拝借。
モデルやテクスチャ、SEなどはGameSynthで自作。
ある程度システムができた段階でSwords of Gurrah開発者にファンメイド作品制作の許可を貰った。(想像以上に好意的な反応をいただいた)

武器挙動の実装
トリガーで刀身がガードモードに変化する挙動
何かに当たると刀身が折れる挙動
他人へのダメージ判定チェック
刀身の形状に沿った当たり判定の作成
追加仕様・改修
頭部への当たり判定チェック
本家では刀身の速度からダメージ計算しているが、FPSの安定しないNeos上では固定値ダメージでの実装にしたため、頭部のみダメージボーナス判定を入れた。
剣のサイズを一定にする
公平性の為、アイテムを装備した時にアバターサイズにアイテムがスケーリングされてしまうNeosの仕様に抗う挙動を追加した。
意図していないコライダーに当たる問題の解決
壁や床に当たることは意図した仕様だが、ネームプレートなどにも意図せず当たってしまうため除外判定など
鞘に刀を納める挙動
コライダー判定で鞘に納めようとすると刀身が折れてしまい、除外もできなかったため、独自に距離の算出をして、近ければ吸い付くようなロジックを作成。
当たり判定抜けを減らす方法の検討
次項に続く

HPバー挙動の実装
剣の種類は増やす構想があったため、可能な限りHP側に多くのロジックを実装した。
被ダメ時に視界を点滅させたりHPに応じて視界が少しずつ暗くなるなどのHPに関するギミックも独自に実装した。
移動速度を落としたり、スティック移動を禁止するロコモーションもここに仕込んだ。
HPバーは左腕に吸着するように作ったが、観戦者や対戦相手が見やすいように、頭の上にも大きく表示することにした。

大会開催に向けて作ったものなど
2名の剣士により、2振りの刀とサーベルの3Ðモデルを提供して貰えたため、多くの高品質なモデルを使用することができた。
ガードモード同士が当たった時のヒット音は実際の模擬刀でサンプリングして、提供して貰えたため、よりリアルな音を使用することができた。
ライトセイバーは他ワールドで作成可能なものを使用した。
アバターによって、手のコライダーを狙われてしまうため、当たり判定をガード判定に変更するアイテムや、身長の低いアバターで床を斬ってしまうため、床の当たり判定を消すアイテム、全員の最大HPを再設定しなおしたり回復させるボタンなど、運営用アイテムも作成した。
普段NeosVRをプレイしない人が多く参加してくれたが、
足りないものがあったり、何か不都合があれば、その場でアイテムを出したり、作ったりすることが主催者以外でも可能なので、人数の問題がクリアできればNeosVRはイベント開催に向いていると感じた。




当たり判定抜けを減らす方法の検討
刀のような反りのある刀身の当たり判定を正しく行いたいという理想と、ガードなどをすり抜けてしまう理不尽を減らすための妥協点の模索。
Neosで実装する都合上、ネットワークには関与できず、FPSが安定していないユーザーが多いというデメリットと、P2P通信による低遅延通信のメリットを生かすにはどうしたらよいか様々な検討を行った。
没案)早く振れない剣
そもそも剣を重くして、早く振れないようにすればほとんど抜けない。
ただし、実際の動きから遅れて付いてくる形になるので、不一致感が発生してしまう。
両手剣など、もう少し重そうな剣であれば納得感は出るが、
Neosのラグの少ない環境でやるのは勿体無い。
没案)未来予測位置にもコライダーを置く
現在フレーム、次フレームの予測、2フレーム先の予測、2フレーム先の予測をSmoothLeapで追従する
と言う挙動の4つ分のコライダーを設置してみる。
現在フレームからも、前フレームからの移動量と同じ移動量を行ったと想定した位置を次フレームの予測位置として、ビジュアルより先に当たり判定を発生させる。
今回の場合は4つ分を計算しているので、負荷は4倍以上。
もちろん早く振れば隙間が空くのですり抜ける。

没案)現在のフレーム位置から1フレーム前の位置までレイキャストを飛ばす
刀身に沿って仕込むことで解決するかと思ったが、BoxRayなどの挙動が出来ないため、判定の間をすり抜けてしまう問題が稀に発生した。
また、数が多すぎると、滅茶苦茶重くなってしまった。

没案)動的トライアングルメッシュコライダー
刀身の先端と根本、数フレーム前の先端と根本の4点を2つのトライアングルメッシュを動的に作成し、同様にトライアングルメッシュコライダーを作成した。
理論的にはすり抜けないはずだが、高速で振ると普通にすり抜けることが判明。
自信がホストのワールドで他人がつかんだりしていない細い棒などでもすり抜けが発生したため、ネットワークの問題ではないと考えている。
恐らくNeosのコライダー演算処理順の都合でこのような挙動になってしまったのだと思う。
または、片面三角ポリゴン2枚であることに問題があるかもしれないため、いつか、厚みを持った4ポリゴンで挑戦して見ても良いかもしれない。


採用案)凸包の組み合わせ
凸包の組み合わせによる形状に沿ったコライダーのみで、ワールドに居る人全てのユーザーの視点(コライダー判定)で誰か1人でも当たった処理をしていたら当たったことにするようにした。
Neosの凸包コライダーはポリゴンの表面のみ当たり判定を持つメッシュコライダーと異なり、スフィアやボックスと同様にポリゴンの内側に入り込んでいる場合も当たり判定ができるというメリットを持つため、刀身の形状に沿った当たり判定の作成が可能。
負荷はスフィアコライダーの32倍程度高いと言われているので、今回は未来予測位置にもコライダーを発生させる案との両用は諦めた。
常時アバターに付けて携帯するようなアイテムではないので全員に負荷がかかる点については妥協するものとした。
NeosVR自体の動作の軽量化に有効な視界外のユーザーのIK処理をカットするMODなど、相性の悪いものは存在する。
また、FPSの著しく低い人が居る場合や、ネットワークの問題で同期がとれていない人がワールドに居る場合なども誤作動を起こしやすい。

セイバースピン練習用ペン(剣)
剣を振り回していたらセイバースピン部の活動に興味を持ったので、基本技を教えてもらったが、3ビートと言う技が上手くできないため、練習用に先端の軌跡を描くペンを作成。
トラッカーを付けた棒を回すため、描く為のトリガーが引けないという問題があったため、鞘に近づけるとトグル式でオンオフできるシステムを作成。
綺麗に回せるようになると、この3つの円の軌跡がほぼ重なるようになるらしい。
まだ始めたばかりなので背中側で回している時に上まで回っていなかったり、斜めになっていたり、前に持ってくるときに円がゆがんでしまっていることが動画などを撮って見返さなくても一目瞭然。
リアルワールドでは実現できない練習法。
以上。
最終更新2023/08/10