Aizu-Progressive xr Lab blog

会津大学のVR部であるA-PxLの部員が持ち回りで投稿していくブログです。部員がそれぞれVRに関する出来事やVRにちなんだことについて学んだことを書いていきます。

連絡はサークルTwitterのDMへお願いします。
「面白法人カヤックVR分室」としても活動しています。詳細はこちら

音ゲーのノーツ

学部1年の星野です。まだC#がよくわからず勉強中のUnity初心者です。そんな自分ですが少し前からUnityで音ゲーをつくっています。まだ完成はしていませんが、ほとんどの仕組みは完成したところです。作っている最中、ノーツ(音ゲーの時、リズムに合わせて流れてくるもの)を動かす仕組みを調べていた時、曲の再生時間を使ってノーツの座標を計算する方法がずれを少なくするためには良いとありました。ノーツの動きなんて「Time.deltaTime」で座標に一定の値を足してりゃできるだろうと考えていたので、大きな衝撃を受けました。そこで、どのくらいズレが生じるのか試してみたいと思いUnity上で検証してみました。(Unity初心者かつパソコン初心者の考えた検証方法なので間違っているかもしれません。)

検証

f:id:aizu-vr:20191223201014p:plain

  • 左の水色の長方形が判定ラインだとします。(座標は0,0,0))

  • 右にある2つの白い正方形をノーツだとします。(上の正方形の座標(15、2、-2)下の正方形の座標(15、-2、-2))

  • 上のノーツはTime.deltaTimeで、下のノーツは曲の再生時間で座標を計算して動かします。

  • 判定ラインに到着したとき(ノーツのx座標が0になったとき)その時の曲の再生時間を表示します。

今回は曲の再生から1.5秒経った時、判定ラインにくるようにしました。つまり、出力される時間が1.5に近ければ近いほど正確ということになります。

結果

f:id:aizu-vr:20191223204645p:plain

  • Time.deltaTimeによるノーツ 1.642653秒(ずれ0.142653秒)

  • 曲の再生時間で動かしたノーツ 1.514649秒(ずれ0.014649秒)

  • Time.deltaTimeによるノーツは時間のばらつきが大きいのですが、曲の再生時間で動かしたノーツは時間のずれはなく、毎回この時間でした。

以上の結果よりTime.deltaTimeでノーツを動かすことは音ゲーにとって致命的な大きなずれを生みうることが分かりました。 これからもUnityやC#の勉強を頑張っていきたいと思います。

面白法人カヤックインターン体験記 ~2019年夏~

こんにちは! A-PxL部員の橋本です。今年の夏、私は当部(A-PxL)でお世話になっているカヤックさんのVR部のインターンシップに参加させていただきました。インターンに行ってから少し期間が空いてしまいましたが、今回はそのレポートをしていきたいと思います。

インターンに参加した理由

自分の実力を試してみたかった

一番の理由はこれでした。私は今までUnityやArduinoなどのツールを扱ってコンテンツを作ってきました。しかし、コンテンツを作ってきた中で本当に自分に力がついてきていたのか、成長してきていたのかということについていつも疑問に思っていました。その疑問を払拭するべく今回インターンに参加することを決心しました。

カヤックという企業を知りたかった

会津大で開かれたカヤック式のブレストワークショップに参加したり、当部の部長になったことで実際にカヤックの社員の方とミーティングをしたりしていく中で、カヤックさんは私にとって一番身近な企業になっていきました。そんな経験をしていく中で、「もっとこの企業について知ってみたい」という思いが芽生えていったこともあり、今回はカヤックVR部署のインターンに参加することにしました。

インターンでの業務内容

インターンでの課題は「インターン期間中(7日間)にOculus Quest向けのVRゲームを1本作る」というものでした。

という訳で、Unityを使ってVRゲーム1本を7日間で作りました。ちなみに、このコンテンツは会社のプロダクトとは一切関係なく、私が所有するコンテンツです。

成果物

f:id:aizu-vr:20191104021810p:plain


JengaVR

どんなゲーム?

私には以前から誰もが簡単に操作できて楽しめるようなコンテンツを作りたいという思いがありました。そんなことを考えながら思いついたのが、「VR空間でのジェンガ」でした。ジェンガなら大多数の人がルールを知っているはずですし、コードレスなOculus QuestだからHMDを使い回すことも容易で複数人対戦も可能です。

工夫したところは?

このゲームでは、プレイヤーがジェンガブロックを抜き取る際はキューブを発射してブロックを抜き取ります。

2日目に実際に今回のプロジェクトがうまく動くのか検証することになり、「プレイヤーがジェンガブロックを細長い棒を使って押し出す」というプロトタイプを作ってみたのですが、物理挙動がネックとなってしまっていてまともに遊べたものではありませんでした。

何かいい解決策はないかとネットで調べていたところ、こんなものを見つけました。

gigazine.net

物理挙動が怪しくなるのは、常に小刻みに揺れているVR空間内のコントローラーと幾つものブロックが接触して積み重なっているジェンガタワーが接触することが原因です。つまり、プレイヤーが操作するコントローラを介することなく一瞬でブロックを抜き取ることができれば物理挙動の問題は解決できることになります。そして、その解決策が上記のジェンガピストルでした。この抜き取り方法にした結果、ジェンガを抜き取ることが容易になり問題なく遊べるようになりました。

面白いポイントは?

このゲームの最大の特徴は、巨大なジェンガブロックでジェンガができることです。ジェンガブロック1つの長さ(奥行き)は大体人の腕の長さくらいあります。ジェンガブロックのタワーを見上げることができるのは新鮮な体験ではないかと思われます。VRゲームでは大きい物体が目の前にあると「おぉ!」ってなりますからね。また、ブロックが大きいためプレイヤーがブロックを積む際は回り込む、しゃがむといった体の動作が必要になります。VRゲームでは、体の動きがあればあるほど没入感が増すと言われています。ブロックが大きいことがVRゲームとしての完成度を高めていると言えるのではないでしょうか。

また、ゲームオーバー時の演出として、空から爆弾が落ちてきて爆発してブロックが宙に舞うというのがあります。社員さんからのアイディアで、ゲームオーバー時の演出でVRならではの要素が欲しいとのことで追加した要素でしたが、これもなかなかに面白い演出となったと思っています。

作る時に苦労したことは?

なんといってもデバッグです。今回開発に使用したPCはmacでした。macでもOculus Quest向けにビルドして実行することは可能なのですが、デバッグの度にビルドで時間が取られてしまうのでかなりしんどかったです。そのため、なるべくデバッグでしんどくならないようにUnityエディターでも操作できるようなデバッグ用のプレイヤーを用意してあげるなどしてなるべく実機でのデバッグをしないようにしてあげました。

作る時にこだわったところは?

UI, UXです。プレイヤーがキューブを発射する際はレイを表示させてどの方向に飛んで行くかをプレイヤーに教えてあげる、ブロック抜き取り -> 積み上げのフェーズの移行の際にフェードアウト/インするようにする、ブロックを積み上げる際は抜き取ったブロックのすぐ近くにプレイヤーを移動させる、ブロック積み上げ成功判定までの時間をインジケーターで表示させる、なるべく複雑な操作を含まないように心がける、、、などなど、なるべくゲームを遊ぶことが少ない人でも簡単に操作ができるようにこだわって作りました。結果、とてもユーザーライクなゲームに仕上がったのではないかと思います。

学んだこと

プロトタイプを作って実現可能性を検証せよ!

今回ジェンガのゲームを作ると決まったときに懸念していたことはやはり物理挙動でした。最初は完成させることができるのかかなり疑問に思っていました。もし作れない場合は他にどんなゲームを作ろうかと保険を考えていたくらいです。とりあえず動くかどうかを確かめるべく試作第一号を作りあげて遊んだ結果、やはりダメだと分かりました。ではどうするかと考えた際に上記のジェンガピストルの記事と出会って、試作第二号を作った結果、これならいける! と確信することができました。その時の安心感は凄かったですね(笑)。

ちゃんと遊べるものを作れるのか不安になりながら開発をするのと、完成した結果ちゃんと遊べると確信を持って開発するのとでは心理的にかなり違いが生まれるものです。なんだか記事にして書くと当たり前な感じがしますが、事前検証というのはやはり大事です。特に、失敗することが許されないという環境では尚更大事になることを学びました。

まずは根本の部分を作れ!

3日目の出来事なのですが、まだ仕様をきちんと決める前にあまり重要ではない詳細な部分の実装を先走ってやってしまったということがありました。その日の最後にあった進捗報告会で社員さんに「その部分にはまだあまり拘らなくてもいいんじゃない?」と指摘されました。どうやら自分には、重要ではない部分に目がいってしまうという欠点があるようです。実は以前参加したことがあるハッカソンでも似たようなことをして失敗していました。同じ失態を2度もしてしまったことは悔しかったですね。結局、その日に書いたスクリプトは全てお蔵入りすることになってしまいました。そのプロジェクトの根本の部分は何なのかについてしっかりと見極めるようにしていく必要があります。

デザインパターンを意識してコーディングせよ!

今回のプロジェクトではUniRxを使用して開発していたのですが、社員さんにコードレビューをしてもらった時に「もっとデザインパターンを意識して書いた方がいい」というアドバイスをいただきました。確かに、UniRxを使っていることで処理の内容がわかり易くなったりしていることは間違いないと思うのですが、スクリプトの数が増えていくにつれて参照が複雑になって開発が大変になったりしていました(特にUI周り)。クラスの設計を行っていなかったというのもあるかもしれませんが、それにしてもかなり煩雑な設計になってしまったと思います。UniRxと相性がいいとされるMVP(MV(R)P)パターンについて勉強してみるといいとアドバイスいただきました。

また、軽くZenjectを使ってみたりもしました。今回はシングルトン撲滅のためだけに使いましたが、次に使うときはもっと活用してみたいですね(そのためには疎結合な設計についてさらに学ぶ必要がありますが...)。

MonoBehaviorを継承しないクラスを書くべし!

これもコードレビューしてもらった社員さんに言われたことです。MonoBehaviorを継承しないことによるメリットとしては、ゲームオブジェクトにコンポーネントとしてアタッチしなくても済むということが挙げられます。開発の規模が大きくなってくるとこれがかなり嬉しくなってきます。今後はなるべくMonoBehaviorを継承しなくても済む場面では継承しないように心がけていきたいです。Zenjectのサンプルゲームが見たところ参考になりそうですね。

何らかのアクションには必ずSEが必要!

これはテストプレイを社員さんにやってもらっていた時のことなのですが、その時はプレイヤーの見ているHMDの画面を見ずに操作方法のレクチャーをしていました。そのような状況では、例えばプレイヤーがものを掴む時に本当に掴めたかどうかを確認することは困難です。プレイヤーが「掴めた!」と言ったとしても、実は掴めていなかったりすることがあるかもしれません。しかし、SEがあることによってプレイヤーが今どんな操作をしているのかを画面を見なくても推測することができるのです。基本的にコンピューターゲームではプレイヤーからの操作に対するアクションにはSEがついているものだとは思いますが、今回改めてSEの重要性に気付くことができました。

必ず開発者以外の人にテストプレイさせろ!

ゲームオーバー時の演出として爆弾が降ってくるという演出を作りました。実はその前にもう1つ「ドラゴンの置物が巨大化してプレイヤーを飲み込む」というゲームオーバーの演出を作っていました。番犬●オ●オではゲームオーバーになった時は犬が起きて吠えますよね。あんな感じの演出を作りたかったという思いがありました。しかし、実際に社員さんに遊んでもらった際にゲームオーバーになった時、ドラゴンの方を向いていなくてドラゴンに食べられたことに気付いてくれなかったことがありました。VRゲーム開発の難しさとして、開発者がユーザーに見て欲しいと思っている方向をユーザーが見てくれないというものがあります。今回のドラゴンの演出はUXがダメだったということですね。対策としては、ガイドラインなどを示したりして対象物に視線が行くように何らかの方法で誘導することが挙げられますが、今回は演出を変更することを選びました。こういった発見は開発者では見つけられない部分だと思われます。そのため、開発者以外のテストプレイヤーを用いて観察して調整することが重要なのです。

ちなみに、任天堂宮本茂氏はゲームの開発中に社内からそのゲームに触ったことがない人を1人さらっていって、何の説明もなしにいきなりコントローラーを握らせてプレイさせて、その様子を後ろから眺めながら「お客さん目線」を見つけるらしいです。

カヤックの様子

とにかく社員さん同士の仲がいい! そう感じました。笑う時はその部屋にいる人全員でそのことについて笑ったり、社員さん同士であだ名で呼び合ったりと、とても朗らかな空気で溢れていました。おかげで毎日何かしらのことで笑うことができました。また、あまり慣れていない自分のことを気遣ってくれる優しい社員さんたちがたくさんいてくれたおかげで環境にもすぐに慣れることができたと思います。カヤックの説明会で聞いた通り楽しく働ける環境だったと思います。

また、鎌倉ということもあって観光地にすぐに足を運べるというのもいいですね! (江ノ島のたこせんべいうまかったなぁ...)

インターンを体験して

実は今までVRゲームを作って誰かに遊んでもらうという体験はありませんでした。しかし今回作ったゲームでは社員さんになかなかに楽しんでもらえたように感じられました。自分が作ったゲームで誰かが楽しんでくれるのを見たのは今回が初めてでした。ユーザーが楽しんでいる風景を見ることがゲーム開発者にとっては最高の瞬間ですね。本当に嬉しかったし、自信になりました。今回のインターンはとても意味のある濃厚な体験にできたと確信しています。それもこれもカヤックさんでインターンをしたおかげです。お世話になった社員の方々には本当に感謝しています。

私は大学院に進学することを考えているので就活はもう少し先になるのですが、今回の体験を大切にしてこれからも創作活動を続けていきたいです。

そして、この記事を読んだA-PxLの後輩達はカヤックインターンへ行きましょう! きっと忘れられない体験ができますよ!

いろんなノイズを触ってみた

学部2年の木村です. 最近ジオメトリーシェーダーでGPUパーティクル的なものを作ろうとしてパーティクルの動き方など決めるのに悩んでいたとき, ノイズを使ったらいい感じになったのでそのときに使ったノイズの紹介やそれぞれのノイズについての特徴を調べてみたいと思います.

いい感じにしたいやつ↓

ジオメトリーシェーダーで各ポリゴンの高さと模様をランダムに変えていて, このランダムの部分を他のノイズに置き換えていきます.

目次

ノイズとは

プログラミングをしている中で, 不規則な値が必要なときにランダムな値として乱数を使うかと思います. 下の画像のように白黒がバラバラで規則性はなさそうです. 最初の動画で使っていたのもこれです.

それに対してノイズはある程度の規則性を持っており, 雲や炎や岩の形状や模様など自然の表現によく使われているようです.

ブロックノイズ

ブロックノイズは, 格子状に区切ってそのままそのブロックを塗りつぶしています.

ブロックみがあります.

バリューノイズ

バリューノイズは, 格子状に区切ったときの周囲の格子点のランダムな値から補間した値を返します. 補間してるのでちょっと滑らかになってます.

ジオメトリーシェーダーで使ってみると山のような形が出てきました.

パーリンノイズ

パーリンノイズは, 映画「TRON」の制作の際ににリアルなテクスチャーを生成するために開発されたノイズで, 炎や雲の表現や, 地形の自動生成などに使われています.

パーリンノイズも途中まではバリューノイズと似ているようですが, 補間をする前に格子内の点と格子点へのベクトルとの内積をとり, その内積を補間に使っています. それによって格子点の値も滑らかなグラデーション状になっています.

低い山がたくさんになりました.

シンプレックスノイズ

パーリンノイズの改良版です.
格子でなくシンプレックス(?)を使うみたいです. 2Dなら三角形, 3Dなら四面体のようにn次元に対してn+1点のみ考慮するとのことですがよくわかりませんでした. とりあえず, 格子点を使わないからこれまでのノイズにあった正方形のパターンがなくなっています.

カールノイズ

カールノイズはパーリンノイズやシンプレクスノイズを基にさらに回転を計算し, 流体のような表現ができるノイズです.

かっこいい.

この例はシンプレクスをもとにしていますが違いがわかりにくいですね

セルラーノイズ

セルラーノイズはuv座標をタイル状に分割して各タイル内にランダムに点を置き, それらの点の中から最も近い点までの距離を返すノイズです.

最後に

使ったノイズは以上です! ノイズを使うと手軽にいい感じの表現ができそうなのでぜひ試してみて下さい!

あと, このノイズをVRChatで見ることもできるのでよかったらこちらのワールドへ!

参考

https://wgld.org/d/glsl/g007.html https://thebookofshaders.com/11/?lan=jp https://en.wikipedia.org/wiki/Value_noise https://catlikecoding.com/unity/tutorials/simplex-noise/ https://qiita.com/nyamadandan/items/2a8bc7a3639e7b5ce9c9 http://nn-hokuson.hatenablog.com/entry/2017/01/27/195659

Unity でARを簡単にやる二つの方法~Vuforia編~

こんにちは学部2年の國分貞史(ナメロウ)です。今回は最近ARにはまっているのでARアプリをUnityを使って簡単に作る方法を二つ復習がてらに書いていこうと思います。

今回はVuforiaを使ってARマーカーの上にオブジェクトを表示させる手順を書いていきます。

Vuforiaを導入するには

2019.2以前の場合はUnityのモジュール選択に

f:id:aizu-vr:20191019191537p:plain
Unityモジュール画面
と表示されているのでVuforia Augment Reality Suportにチェックを入れてインストールしてください。

2019.2~の場合はProject Managerに入っているのでそこからインストールしてください。

入れてからの設定

f:id:aizu-vr:20191019192915p:plain
Vuforia Configuration
Unityを開くとVuforiaの各種項目が追加されています。まずは自分のVuforiaアカウントとUnityプロジェクトを同期させましょう。以下のURLからVuforiaのアカウントを作成してください。

developer.vuforia.com

f:id:aizu-vr:20191019220732p:plain
Vuforia Developer Screen

Developタブを開くとこのような画面になります。それではGet Development Keyから自分のプロジェクトと同期させるためのlicence keyを作成します。LicenceNameには自由に名前を入力してください。作ったLicenceNameをクリックするとlicence keyが表示されるのでコピーしてください。そうしたら上の画像で赤く塗りつぶされている部分に貼り付けてください。
次にマーカーに使いたい画像をサーバーにアップロードしましょう。今回はサンプルにある画像を使わせてもらいます。Assets/Editor/Vuforia/ImageTargetTextures/VuforiaMars_Images/Astronaut_scaled.jpgを私は使います。

Webに行きAdd Database->Deviceを選択して作ってください。作成したDataBaseにAdd Targetを選択しSingle Imageを選択,Widthを100にして追加してください。 そしてDownload DataBaseを選択,UnityEditorを選びダウンロードしてください。ダウンロードしたUnity Packageはimportしてください。
ではUnityEditor上の操作をしましょう。

f:id:aizu-vr:20191019232542p:plain
package 導入後のUnityEditor編集後の画面

まずmain Cameraは使わないので消してHierarchy->VuforiaEngine->ARCameraを追加してください。これだけでスマホのカメラに接続できます。次にHierarchy->Camera Image->Camera Image Targetを追加します。これのInspectorのImage Target Behaviorを設定しましょう。

f:id:aizu-vr:20191019233057p:plain
CameraImageBehavior

  • Type:Predefined
  • DataBase:先ほど作ったDataBase

これで設定した画像をマーカーとして使用できます。また,このターゲットの下に子として配置したオブジェクトを読み込んだときに表示させることができます。今回は111のCubeをおきました。

ビルドの設定

OS事のビルドの設定,仕方は通常のスマホでのビルドと同じなので省きます(ただしVuforiaのバージョンごとにosの最低versionは決められているので注意してください。)ここでは共通して行わなければいけない項目について解説します。

f:id:aizu-vr:20191020020330p:plain
Project Setting
ProjectSettingを上の画像のようにVuforiaのところに設定してください。

結果

f:id:aizu-vr:20191020021314p:plain
AR画面1
画像は隠されているのでCubeは出ません。
f:id:aizu-vr:20191020021208p:plain
AR画面2

手を外すと認識されます。

どうでしたか,このように特にスクリプトを書かずとも簡単にARアプリを作ることができます。ここから快適なAR生活を始めましょう!

UniVRMのMToonシェーダーで簡単テクスチャアニメーション

 f:id:aizu-vr:20191001134758p:plainこんにちは。A-PxL所属で学部2年の山田大生です。

 最近UniVRMのMToonシェーダーで動くテクスチャが設定できることを知りまして。ちょうどVRM化できそうな人型モデルを持っていたのでやってみることにしました。

 そもそもUniVRMのMToonシェーダーとは何なのか。それはVRMモデルに対して使うことができる共通のシェーダーの1つです。元から完成されていて様々なパラメータも持っているのでシェーダーをかけない私にはとてもありがたいものです。

 早速そのMToonシェーダーを使ったものを紹介していこうと思います。

 まずはUniVRMパッケージを持ってきて、モデルにMToonシェーダーを割り当てていきます。とりあえず全部Mtoonにしてみました。

f:id:aizu-vr:20191001120244p:plain

Mtoonシェーダーは特に何も設定しなくても見栄えがよく、しかも簡単にアウトラインや光源を設定できるのでとても良いです。ほんとに。

 そして本題の動くテクスチャですが、Mtoonシェーダーの"UVCoordinates"枠で設定できます。要はメッシュのUVだけを動かしてアニメーションっぽくするUVスクロールというものですね。

 まずは左腕のリングと服のマント部分のマテリアルから設定しました。 そのテクスチャはこんな感じです。 f:id:aizu-vr:20191001122047p:plain

 透過したかったのでpng画像で。右側部分がリング、左側部分が服の表面のエフェクト用です。ずいぶん贅沢に使いました。

 そしてこのマテリアルのUVCoordinates枠の”Auto Animation”の"Scroll Y"の値を設定しました。ここではそのメッシュのUVをY軸方向にどれだけ動かすかを設定できます。"Scroll X"ではX軸方向ですね。"Rotation"はそのままどれだけUVを回転させるかですね。そして設定した結果がこちら。


MToonシェーダーでテクスチャアニメーション1

 無事うまくいきました。こんな簡単に動くテクスチャが作れるなんてすごい...。

 さらにもう1つ作りました。

 今度は服の襟字を動かしてみようと思いました。先ほどと同じように設定していきますが、この襟の文字のテクスチャは服のテクスチャと一緒になっているのでこのままだと服の模様も動いてしまいます。

 そこでマスクを使って動かしたい部分を指定することにしました。動かしたい場所を白、動かしたくない場所を黒にしたマスクテクスチャを別に用意します。 f:id:aizu-vr:20191001130235p:plain

上が服のテクスチャ。下がそのマスクテクスチャです。(余談ですけどSubstancePainterでテクスチャ出力するとメッシュ部分以外のところがぐっちゃぐちゃになるのは何なんですかね...?誰か教えてほし...) f:id:aizu-vr:20191001130238p:plain

マスクテクスチャを先ほどのUVCoordinates枠のAuto Animationの"Mask"に適応させるとこんな感じに。↓


MToonシェーダーでテクスチャアニメーション2

メッシュが悪いせいでガタガタですが、しっかり襟字だけ動きました。

 そんなところで今回はここで終了です。VRMモデルならほかのVRM対応ソフトでも使えるので良いですね。かっこいい動くテクスチャ付きのモデルで遊びたいものです。もっと工夫すれば複雑なものも作れるんじゃないかと。体を這う紋様とか作れたらかっこいいなぁ...。それはまた時間があったら...。

それでは。

会津大学VR部の部員が持ち回りで投稿していくブログです。特にテーマに縛りを設けずに書いていきます!