FC2ブログ
ヽ|∵|ゝ(Fantom) の 開発blog? ホーム »Unity
カテゴリー「Unity」の記事一覧

【Unity】【C#】Android で VRM(VRoid)を動的に読み込む  


 VRM Live Viewer にも利用しているが、元々は「プラグインを使って VRM を Android で読み込めるか?」という実験をしてみたら、スンナリと行けてしまったので次々とアイデアが浮かび、VRM Live Viewer をリリースするまでに至ってしまったという…(タイムスタンプを見ると、試しにライブステージ導入してから、アプリリリースまで4日しかかかってない←夢中になるといつの間にかアプリを完成させてしまうことも多い(笑))。


 まぁせっかくなので、VRMVRoid を Android でも読み込み、利用する方法を書いておこう。ちなみに VRM は VRChat やバーチャルキャストで使われるアバターフォーマットではあるが、リアルタイムで読み込むことができるので、あらかじめモデルをアプリに入れてビルドする必要もなく、読み込みもそれほど時間はかからないので、応用範囲は広いと思う。

 私は Unity4 の時代から MMD を Unity で動かしたり、一般公開されているモデルを実験で使ってたりしてたが、Unity ではいつもキャラのバリエーションが少ないな~と感じていたので、VRM で動的に読み込めるのは画期的だとさえ思う。例えば RPG でもアクションでも、好きなキャラで遊べるゲームとかも作れそうだしね(もちろん、大きさやコライダの判定などの問題もあるが、あくまで可能性として(笑))。アイデアは常に新しい発想から生まれるので、既成概念に捕らわれずに色々やってみると良いと思う。それがいつか新たな作品に繋がる。

 今回はあくまで Android で VRMVRoid を読み込む方法だけだが(どちらも "~.vrm" で扱うとして)、私が試したところ、一度 Unity 内に読み込んでしまえば、プラットフォームに関係なく扱えると思うので(見た目はシェーダなどのせいで多少変わることもあるが)、ひとつの方法として覚えておけば色々活用できるだろう。ちなみに VRM Live Viewer は Android版と Windows版を出しているが、ファイル読み込みやダイアログなどプラットフォーム固有のもの以外は全て同じだ。実際にシーン1つだけでビルドしている。つまり複数のプラットフォーム対応も簡単にできることがわかる。


(※) Unity 5.6.3p1 - 2018.2.1f1 / UniVRM 0.40 - 0.43 / VRoid Studio 0.1.1 - 0.2.8 / Windows10(x64) / Galaxy S7 Edge (Android 7.0) で確認



■UniVRM をインポートする

 Unity で VRM を読み込むには UniVRM というオープンソースが必要となる。ライセンスは「MIT License」となるので、その辺りは各自で確認して欲しい。ちなみにライセンス形態にも色々あるが、MIT License は比較的緩いライセンスだ。ついでに参考資料も載せておこう。

(参考)
GPL, LGPL, BSD などのOSSライセンスの違いと注意点まとめ
知らないと損をする6つのライセンスまとめ



 なお、新規プロジェクトで Android プラットフォームでビルドして試すなら、パッケージをインポートする前に「File>Build Settings...」であらかじめ「Switch Platform」で Android プラットフォームに切り替えておいた方が良いかも知れない。UniVRM に内包されているシェーダ(MToon 等)を再コンパイルしたりするのに結構時間がかかる(笑)。


 プロジェクトの準備ができたら、まずは UniVRM をダウンロードしよう。今回はアプリに動的に VRM を読み込むので UniVRM の本体「UniVRM-x.xx_xxx.unitypackage」(xxx はバージョンなど)の他に「UniVRM-RuntimeLoaderSample-x.xx_xx.unitypackage」のインポートも必要になる。本体「UniVRM-x.xx_xxx.unitypackage」を先にインポートしてから、ランタイムローダ「UniVRM-RuntimeLoaderSample-x.xx_xx.unitypackage」をインポートしよう。とりあえず VRM の動的読み込みに必要なものはこれだけで良い。






●API のアップデートが促されたら、「Go Ahead!」する




■VRM を動的に読み込んでみる

 UniVRM のインポートが終わったら、次にプロジェクトビューで「Assets/VRM.Samples/Scenes」で、シーン「VRMViewer」を開いてみよう。ビューワ自体は PC 用なのだが、これを改造することにより、Android 等他のプラットフォームの読み込み方法もわかると思う。



 ちなみに「VRM Live Viewer」はこのシーンを元ベースとしている(見た目もたいして変わってないのでわかると思うが(笑))。他の VRM 利用アプリを見てみると、たぶん同じようにこれを改造してるものが多い気がする。エクスポートできるアプリを作るなら、シーン「VRMRuntimeExporterSample」あたりを見てみると良いと思う。せっかくのオープンソースなのだから、遠慮なく使わせて頂こう(笑)。


 このシーンでは左上部にある「Open」ボタンを押すことにより、VRM を動的に読み込んで、シーン上にモデル(アバター)をロードすることができる。ただ、Windows 上なら 「PC, Mac & Linux Standalone」プラットフォームになってればそのまま使えるが、Android では無視される。この辺りから少し改造していこう。


1.スクリプトとしてはヒエラルキーで「Canvas」をクリックして、インスペクタで表示される「Viewer UI」にそのコードが書かれている。これを編集しよう。グレーアウトしてる「Script>ViewerUI」をダブルクリックすれば、Visual Studio で開かれる(シングルクリックなら、プロジェクトビューで移動できる)。



2.「ViewerUI.cs」を開いたら、検索で「OnOpenClicked」を探してみよう。これが前述した「Open」ボタンのイベントハンドラとなっている。ここのコードを見てみるとプリプロセッサディレクティブ(#if~文)でプラットフォームが分けられている。とりあえず Unity エディタ上でもテストできるようにディレクティブ(UNITY_EDITOR_WIN)を付け加えておこう。

void OnOpenClicked()
{
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
var path = FileDialogForWindows.FileDialog("open VRM", "vrm", "glb", "bvh");
#else
var path = Application.dataPath + "/default.vrm";
#endif
・・・(略)・・・
}

 ちなみに「UNITY_EDITOR_WIN」とは「Unityエディタ上でかつ Windows である場合の条件」である。プラットフォーム依存コンパイルを上手く使えば、複数のプラットフォームを分別することも可能だ。まぁしかし、コードは見づらくなるので、機能まるごとみたいな場合は、クラスごとに用意するという手もある。今回は一部を改造して使うので、この方法でやっていこう。

プラットフォーム依存コンパイル


3.「UNITY_EDITOR_WIN」を入れたら、グレーアウトしていた文字が見えるようになったと思う。しかし「FileDialogForWindows.FileDialog」の方にエラーが出たかも知れない。まぁ、これも同じプラットフォーム依存なので、「FileDialogForWindows」部分にカーソルを合わせ、「F12」を押せば、クラスがまるごとグレーアウトしてるのがわかる。手順2と同じように「UNITY_EDITOR_WIN」を #if~文に追加しよう。

#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
using System;
・・・(略)・・・
#endif

namespace VRM
{
public static class FileDialogForWindows
{
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
#region GetOpenFileName
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class OpenFileName
{
・・・(略)・・・
}
・・・(略)・・・
#endif
}
}


 これでコンパイルが通るようになったと思う。一旦、Unityエディタに戻ってプレイしてみよう。「Open」ボタンを押して適当な「~.vrm」を読み込んで見ると良い。VRMニコニ立体で多く配布されているので、いくつかダウンロードしておくと良いだろう。「ニコニ立体ちゃん」ことアリシア・ソリッドはとても軽いのでテストするにはもってこいだ。自分で作った VRoid でも可能だが、髪の毛などメッシュが多いものほど、生成に時間がかかるようだ(なので「VRM Live Viewer」では非同期読み込みの方を利用している。非同期読み込みを使うには「.NET4.x」にする必要があるので、ここでは割愛)。

ニコニ立体ちゃん (VRM)





■VRM の動的に読み込みを Android に対応させる

 VRM を動的に読み込みに成功したなら、後は Android に対応させるだけだ。ファイル選択などはプラットフォームに依存するので、先に出てきた「FileDialogForWindows」のようなものが必要になるが、Unity の標準機能には無いので、ここではプラグインを使うことにする(自分で作ったものがあれば、それでも良い)。



 ここで紹介するプラグインは元々私がブログで公開していたものだが、様々なアプリで利用して貰えてるようなのでアセットストアにも提出したというものだ(既に GooglePlay 等で公開されてるアプリなどにも利用されている。「〇〇というアプリを作ってるんですが、使わせて貰って良いですか?」と聞かれるようになったので、気兼ねなしに使えるようにアセットストアにも出したという経緯もある)。AssetStore版GoogleDrive版に機能的な違いはないので(AssetStore版 はアセットストアの規約に合わせただけ)、どちらを利用しても構わない(※ここでは AssetStore版を例にしている)。



 セットアップは以前の記事にあるので、そちらを参照して欲しい。AssetStore版GoogleDrive版では一部ファイル名やパス、素材が違うくらいで、内容的には同じだ。注意点は「Plugins」フォルダを「Assets」直下に移動し、「Plugins/Android」フォルダにあるサンプルのマニフェストファイル(AndroidManifest.xml)を用意しておくということだ(テストだけなら、"AndroidManifest_demo.xml"[AssetStore版]、または"AndroidManifest_test.xml"[GoogleDrive版]を複製してリネームすれば良い)。

AssetStore版のセットアップ
GoogleDrive版のセットアップ


1.プラグインのインポートとセットアップの準備が済んだら、プロジェクトビューの検索で「StorageOpenFileController」のプレファブを見つけよう。見つけたら、これをヒエラルキーに置き、後述のコードを書くことにより、Android でもファイルの情報を受け取れるようになる。本来なら Android でストレージの読み取りなどにはパーミッションなども必要になるが、前述のデモのマニフェスト("AndroidManifest_demo.xml"など)を使ってる分には既に含まれている(「READ_EXTERNAL_STORAGE」または「WRITE_EXTERNAL_STORAGE」が必要。デモにはそれ以外の権限も含まれているが、通常は不要な権限は削除した方が良い→ユーザーにインストを拒否られる確率が高くなるため)。

(パーミッション)
READ_EXTERNAL_STORAGE(ファイル読み取り権限)
WRITE_EXTERNAL_STORAGE(ファイル読み書き権限)



2.次に「StorageOpenFileController」で取得したファイル名を受け取るハンドラを、元のコード「ViewerUI.cs」の「OnOpenClicked」に追加しよう。書き方は前述のコードに追加する形となる。Android の場合ディレクティブは「UNITY_ANDROID」となるので、それを追加し、「StorageOpenFileController」でストレージを開くコードを Android プラットフォーム用に書いておこう

プラットフォーム依存コンパイル

using FantomLib;

・・・(略)・・・

void OnOpenClicked()
{
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
var path = FileDialogForWindows.FileDialog("open VRM", "vrm", "glb", "bvh");
#elif UNITY_ANDROID
var path = "";
StorageOpenFileController storageOpenFileController = FindObjectOfType<StorageOpenFileController>(); //ここはインスペクタで登録できるようにしても良い
storageOpenFileController.Show(); //実機ではエクスプローラのようなもので、ファイル選択ができるようになる
#else
var path = Application.dataPath + "/default.vrm";
#endif
if (string.IsNullOrEmpty(path))
{
return;
}
・・・(略)・・・
}

※この例はやっつけ的なコードなので、「StorageOpenFileController」をインスペクタで登録できるようにしたり、任意にまとめたりして使って下さい(笑)。


3.ランタイム時では「StorageOpenFileController」は閉じられてから、コールバックで結果(選択されたファイルパス名)が返ってくるので、「UNITY_ANDROID」ディレクティブ内ではパスを空(path = "")にしていることに注意して欲しい。これはすぐ下にある「string.IsNullOrEmpty(path)」で一旦終了することを意味する。

 なので、取得したパスを受け取るハンドラを作成する必要がある。ここでは簡略のため、元の「OnOpenClicked()」内のコードを一部まるっとコピーして、もう1つ「OnStorageOpenFile()」というメソッドを定義した(メソッド名は任意)。

public void OnStorageOpenFile(string path)
{
if (string.IsNullOrEmpty(path))
{
return;
}

var ext = Path.GetExtension(path).ToLower();
switch (ext)
{
case ".gltf":
case ".glb":
case ".vrm":
LoadModel(path);
break;

case ".bvh":
LoadMotion(path);
break;
}
}

※UniVRM v0.40 以前は拡張子分岐は無いが、同じように「LoadModel(path)」を呼べば良い。

 実際には「StorageOpenFileController」をインスペクタで登録できるようにしたり、拡張子による分岐などは重複してるので「OnOpenClicked() → OnStorageOpenFile(path)」へ行くように書き換えても良いだろう。その辺りはお任せする(笑)。とりあえずはコード自体はこれで良い。


4.後はヒエラルキーに戻って「StorageOpenFileController」のコールバック「OnResult」に先程の「OnStorageOpenFile(String)」に登録しよう。これで一応完成である。ただし、実機でしか確認できないので、Android ビルドして動作確認してみよう。



5.「File>Build Settings...」を開いてシーン「VRMViewer」を追加してビルドしよう。ビルドに関してはいくつか注意点があるので、以下を参照して欲しい。

「要求 API Level」の設定
シーンを追加してビルドする
Unity 2018.1.0~1.6 での Gradle ビルドにおいて、「Cannot read packageName from~(パス)\AndroidManifest.xml」と出る。




 ここまでできれば、例えば以前の「VRoid(VRM)を動かす」のようにして、ゲームに使うことも可能だろう。1つ1つの技術は結構手間のかかるものだと思うが、プラグインも含め、全て無料でできるので、これを使わない手はない(笑)。今までにない新たな利用法を考えてみるのも良いだろう。

●実機(Android)で「ニコニ立体ちゃん (VRM)」を読み込んでみた所

ニコニ立体ちゃん (VRM)
(c) DWANGO Co.,Ltd. ニコニ立体ちゃんライセンス


 今回はただ VRM を読み込んで動的にアバターを召喚(笑)しただけだが、実際にスマートフォンで利用するには画面解像度・回転の対応やピンチなど、使い勝手を良くした方が良いだろう。プラグインにはそういったスマホらしい操作(ピンチ・スワイプ・ロングタップ等)の例も入っている。VRM Live Viewer の Android 版はまさにその使用例なので、動作確認にインストして動かしてみるのも良いだろう(またはプラグインのデモもQRコードからインストできるようにしてあるので参考に)。











(関連記事)
【Unity】VRM(VRoid)をライブステージで踊らせるアプリを作ってみた
【Unity】VRoid(VRM)をインポートして動かす
【Unity】AssetStore版 FantomPlugin のセットアップ
【Unity】Androidのトーストやダイアログ、通知、音声認識、ハード音量操作など基本的な機能を使えるプラグインを作ってみた


スポンサーサイト

category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: VRM  VRoid  Unityプラグイン  C# 
tb: 0   cm: --

【Unity】VRM(VRoid)をライブステージで踊らせるアプリを作ってみた  


 VRM には Unity で動的にモデルをインポートできる「UniVRM」というオープンソースが公開されているので、そのサンプルビューワと「ユニティちゃんライブステージ!」プロジェクト(オープンソース)を組み合わせて、VRMVRoid)を動的に読み込んでダンスさせるアプリを作ってみた。一応、音楽も BVHモーションファイルも動的に読み込めるので、やろうと思えば自由な曲でダンスもできるかも知れない。

 アプリは当初、プラグイン利用の実験も兼ねて、Android で作っていたのだが、そもそも VRMVRoid)自体の利用が PC 中心(主に VRChat や バーチャルキャスト)であろうと考えて、急遽 PC でも見れるように Windows版 もビルドしてみた(Mac は持ってないのでスマン(笑))。

 なので、PC 版は曲を一部機能が付いてないなど、まだ実装されてない部分もあるが、ただダウンロードした VRM または、自分で作った VRoid などを踊らせてみるだけなら十分可能なので、暫定版としてリリースするのも良いと考えた。

VRM Live Viewer ver.0.29β(ベータ版)


>>Windows 版(x64) をダウンロード
(Google Drive を利用。画面右上にあるダウンロードアイコンを押す)


(Google Drive を利用)


Android 4.4以上
※「提供元不明アプリのインストール」許可が必要です。


VRM をリアルタイムに読み込ませて観ることができる
>>アクシアVRM(縞パンver.)は、Google Drive からもDLできます。


 簡単な操作説明やヘルプはアプリにも入れてあるが(ボタンを押すと出る)、既知の不具合なども一緒に、マニュアル代わりにここにも載せておこう。今後のオープンソースプロジェクトのバージョンアップやバグフィックスなどによっても修正は入るとは思うが、現在までの状態を確認するのにも良いかも知れない。

 とは言え、まずは単純に楽しんで貰えれば良いと思う。VRM の配布は「ニコニ立体」に多くアップロードされているが、有名キャラやオリジナルキャラは Web上でも公開されているので、そういったものもついでに掲載しておいた。もしツイッターでもメールでも(アドレスは「ReadMe.txt」を参照)、連絡してくれれば、このページにもリンクを貼っておこうと思う(PC ではともかく、スマホで直接ダウンロードできるものはほとんど無いため、アプリ内でもできるだけ紹介したいと考えている)。


(※) Unity 2018.2.1f1 / VRoid Studio 0.1.1 - 0.2.8 / UniVRM 0.40 / Windows10(x64) / Galaxy S7 Edge (Android 7.0) で確認



■操作説明

(Windows 版)
[ドラッグ] カメラ回転
[ホイール] カメラ遠近
[中ボタンでドラッグ] カメラの視点移動
[画面端でスワイプ, Tabキー] パネルの開閉
[Esc] アプリ終了

(Android 版)
[ドラッグ] カメラ回転
[ピンチ] カメラ遠近
[指3本でドラッグ] カメラの視点移動 (※先に中指と薬指を画面に置き、人指し指でドラッグすると細かい操作がしやすい)
[画面端でスワイプ] パネルの開閉
[バックキーを2回押す] アプリ終了

[VRM 読込] VRM(3Dモデル)をアプリにロードします。
[BVH 読込] BVH(モーション)をアプリにロードします。ただし、「Y-up 右手座標系」(OpenGL系、Maya, Daz3D など)の座標系になります。「Z-up 右手座標系」(3ds Max など)の場合は、見た目がおかしくなります。[>>3Dツールごとの座標系など]

●モーション
[BVH] 読み込んだ BVH を再生します。デフォルトではPC版に同梱されている「test.bvh」と同じものが使われます。
├[Y:180]にチェックを入れると、モデルが180度回転します(※BVHは正面が逆向きのものもあるため)。このオプションはファイル名ごと(フォルダ名は含まない)で記憶されます。
└[Loop]にチェックを入れると、ループ再生します。このオプションはファイル名ごと(フォルダ名は含まない)で記憶されます。
└[Speed] BVHモーションの再生速度を変更できます。音楽から遅れていくときなどは、少し再生速度を早めると合わせることもできます(端末の処理速度・データにもよるが、約 1.01~1.018 倍くらい。私がテストしてる実機は 1.016 倍にしてる)。通常の速度は 1.0 です。また、30fpsのデータを再生すると早送りのように見えるので(当アプリは60fpsが基準)、その場合は、0.5 にするとちょうど良い感じに見えます。このオプションはファイル名ごと(フォルダ名は含まない)で記憶されます。
[CRS] ユニティちゃんライブステージ -Candy Rock Star- のモーションを再生します。プリセット曲(Unite In The Sky)のダンスモーションです。余談ですが「CRS」(Candy Rock Star の略)はユニティちゃんのライブステージでの衣装の名前ですが、「CRS」という略記はプロジェクト名などにも使われているため、関連するものにはよく利用されます。
[T-Pose] Tポーズに固定します。

●ブレンドシェイプ
(リップシンク)
┌ [None / Key] なし / キーボードで口パク操作できます(PC版のみ)。
├ [AIUEO / CRS] "あいうえお"の口パクをします(※プリセット曲が再生されてないとき)。プリセット曲(Unite In The Sky)が再生されているときは曲のリップシンクが再生されます。
└ [Mic LipSync] マイクから音声を認識して口パクします。
マイク感度設定を開きます。
[Auto Blink] 目パチをします。
[Look At Me] 目でカメラを追います(※目のボーンが入ってるモデルのみ。T-Pose だとわかり易い)。

●背景
(ドロップダウン) 背景を変更します。現在は何も無い(Plane)とユニティちゃんステージ(CRS Stage)のみです。

●音楽
[Start](= Sync Start) オンになっているとき、音楽再生ボタンを押すとモーションを最初から再生します。
[Stop](= Sync Stop) オンになっているとき、音楽停止ボタンを押すとモーションを停止し、最初のフレームに戻します。音楽なしでモーションを再開したいときは、モーションの[BVH]または[CRS](トグルボタン)をもう一度押すと再開できます(CRSの口パクのみはCRS楽曲再生で再開されます)。
プレイリストを開きます。再生する曲・再生方法などを選択できます。
プレイリストに曲を追加します。対応するファイルの種類は「wav」「ogg」です(Android版では「mp3」も可)。
曲の再生モードを切り替えます。「1曲停止」は曲が終わると停止、「1曲ループ」はループ再生(シームレスループ曲に向いています)、「全曲ループ」は曲が終わるとプレイリスト中の次の曲へ行き、全曲終わるとリスト最初の曲へ行きます。「シャッフル」は曲が終わるとプレイリスト中の曲でランダムに再生されます。PC版はまだリスト機能がないため(1曲のみ追加可)、「全曲ループ」「シャッフル」に関してはあまり効果はありません。
再生ボタンを押してから遅延して開始する時間を設定します(秒)。設定は曲のファイル名ごとに記憶されます。BVH モーションなどにタイミングを合わせたいときなどに使います。
※「曲リストから削除」はプレイリストのダイアログ内に移動しました(Android版のみ)。

●マイク感度の設定 (Mic Sensitive)
[Level] マイクからの入力値がリアルタイムで表示されます (0~1)。バーが赤いときは認識されない音量で、緑で認識されます。それらは以下の「Threshold」の値で分別されます。
※「Mic LipSync」のときのみ測定可能です。
※ハードウェア(PC等の録音[マイク]レベル)の設定にも依存します。
[Threshold] このレベルより下の場合、認識しません。主に雑音のカットに使います。
[Gain] 元のレベルを定数倍します。元の入力レベルが小さすぎたり大き過ぎたりする場合など調整するのに使用します。

※スマートフォンの場合はマイクとスピーカーが一体となっているので、購入時付属の「マイク付きイヤホン」またはヘッドホン等を利用すると声を認識しやすくなります(「Threshold」を調整すれば、ある程度は音楽付きでも認識できます)。


●その他
オプション設定を開きます。パネルの不透明度やマイク感度などの各設定へ移動できます。
「操作説明/ヘルプ」が出ます。
パネルなどを閉じます。

[画面左下のアプリ名] クリックするとクレジット「CREDIT」(ライセンス等)、内部ライブラリのバージョンなどが出ます。



■試験的に実装している機能

 掲載時点での試験的に実装している機能です。これら機能は今後、大幅な仕様変更や削除される場合もあります(要望が多いものは正式な機能として残します)。お試し機能くらいに考えておいて下さい。

(※PC版のみ)
 以下のキーはショートカットキーのように利用できます。何らかの設定パネルが開いているとき、またはデータなどのロードしているときは無視されます。

●ショートカット的なもの
[V] VRM 読込(ファイル選択)を開く
[B] BVH 読込(ファイル選択)を開く
[N] 音楽 読み込み(ファイル選択)を開く
[M] 音楽のリストを開く
[J] 音楽の遅延再生の時間設定を開く(※変更・削除される可能性があります)
[G] BVHモーションの再生速度設定を開く(※変更・削除される可能性があります)
[L] マイク感度の設定を開く(※変更・削除される可能性があります)
[K] パネルの透明度設定を開く(※変更・削除される可能性があります)
[H] 操作説明・ヘルプを開く(※変更・削除される可能性があります)

[0](テンキー) 音楽の再生
[.](テンキー) 音楽の停止
[*](テンキー) CRS の楽曲とモーションの再生(※変更・削除される可能性があります)
[7](テンキー) リップシンクを「None / Key」にする(※変更・削除される可能性があります)
[8](テンキー) リップシンクを「AIUEO / CRS」にする(※変更・削除される可能性があります)
[7](テンキー) リップシンクを「Mic LipSync」にする(※変更・削除される可能性があります)

●一度読み込んだファイルの記憶機能

 VRM, BVH, 音楽ファイルなど、現在読み込んでいるファイルのパスを記憶し、キーを押すことにより、ファイル選択を開かずに読み込みを開始します。ファイルが見つからなかった場合は無視されます。

・記憶するときは [Shift]キー+以下の各キー
・読み込みするときは、記憶したキー

で利用できます。キーボード上では横並びの10個になります。

「VRM」 の記憶キー:[F1]~[F10]
「BVH」 の記憶キー:[1]~[9][0] (フルキー)
「音楽」 の記憶キー:[Q][W][E]…[P]
(※変更・削除される可能性があります)

●カメラの操作
[←][→][↑][↓] カメラ視点を動かす
[Ctrl]+[←][→][↑][↓] カメラ視点を中心に旋回
[+][-](テンキー) カメラのズームイン・アウト
[Z][C][S][X] カメラ視点を動かす第2キー(※変更・削除される可能性があります)
[Ctrl]+[Z][C][S][X] カメラ視点を中心に旋回第2キー(※変更・削除される可能性があります)
[A][D] カメラのズームイン・アウト第2キー(※変更・削除される可能性があります)

●リップのマニュアル操作(※変更・削除される可能性があります)
※「AIUEO/LipSync」 がオフのときのみ
(全てテンキー)
[1] あ
[2] い
[3] う
[4] え
[5] お
●実は「あ、あ、マイクおっけー!」以外は、「あ」「え」「お」の3つを適当に連打してるだけ(笑)。
歌詞のひと区切りの最後や、伸ばしてる所だけ合わせれば、意外とそれっぽく見える(笑)。



■PC 版の補足説明

・現在、PC版はプレイリスト(曲リスト)が利用できません(1曲のみ追加可)。「全曲ループ」「シャッフル」に関してはあまり効果はありません(実際には機能自体は実装されているが、UI 作るのが大変なので、後で作ろうと考えている)。



■既知の問題(不具合など)

 現在わかっている不具合を挙げておきます。しかしながら、仕様上アプリからは修正できないものもあるので、その場合はご了承下さい。

※分類
[×] 仕様上、修正は難しい
[△] 修正には調査が必要(場合によっては修正できるかも?)
[-] それは仕様だ。問題ない(笑)
[○] 解決済み


[×] モーションを途中で切り替えると位置がずれる。
→ CRS のダンスモーションは相対的に移動してるため、タイミングによってはステージの中心からずれることがあります(特に重い処理などで一時的に止まってしまう時間が長いときなど)。その場合は曲を最初から再生するか、「T-Pose」で中心に移動する方法があります。

[×] VRoid を読み込むとギラギラする。
VRoidVRM が利用してる NormalMap やシェーダーの差異(独自のシェーダを使っている?たぶんUnlit系のシェーダを設定できるようになれば解消されると思うのだが…?)のようです。VRoid のバージョンアップに伴い、少しずつ良い感じに変換されるようになっています(特に VRoid Studio 0.1.x で作ったものは、かなりギラつく→ 0.2.x で再エクスポートすると少し良くなる)。今後も pixiv に期待しましょう(もしくは要望を出すとか(笑))。

[-]「Look At Me」が効いてない気がする
→ ダンスのように大きく首を動かすモーションでは特にわかりずらいです。「T-Pose」にして試してみて下さい。
また、目にボーンが入ってないモデルでは視線を動かせません。あと、常に「こっちを見る」ギミックが入っているモデルも効果がありません(その場合は逆にオフにしても「こっちを見る」感じになります)。

[○] モデルによっては一部欠けて表示される(特にバックスクリーンカメラ)。[ver.0.19 にて Fix]
→ モデルによってはメッシュの連結(親ボーンのリンク)とバウンズが上手くマッピングできず、各パーツの bounds がカメラの表示領域から外れ、カリングされてるようでした。少し負荷は上がりますが、カメラ領域外にいるときもカリングされないように修正しました(このアプリでは1体なので、負荷より表示を優先すべきと考えた)。

[○] BVH モーションがだんだん音楽から遅れていく。[ver.0.22 にて、再生速度調整機能を追加]
→ 特に他の形式から BVH に変換した場合など、フォーマットによる誤差(BVH はフレームベース[1フレームごとにデータがある]だが、フォーマットによっては時間ベース[一定間隔ごとにデータがあり、間は自動補間する]で作成されているデータもある。MMDなど)、ものによっては実機との負荷の影響もあり、少しずつ遅れていくようです(例えば BVH が 60fps で作られていたとしても、実機で確実に 60fps 出るわけではないので、少しずつずれていく)。再生システムを変更することも考えましたが、既存のデータの見え方も変わってしまうため、独自に再生速度を調整できるようにし、より汎用的に利用できるようにしました(再生速度操作によってスローモーションや早送り再生も表現できる)。BVH のデータと現実時間の遅延誤差は実機の処理能力にもよりますが、再生速度(Motion Speed)を約 1.01~1.018 倍くらいにしておくと、音楽とも合うようです(内部処理が55fpsくらい出ている場合。実際には端末ごとに平均的な値を見つけるしかない。私がテストしている実機の場合 1.016 倍くらいが丁度良いことが多い)。再生速度はファイル名ごと(フォルダ名を含まない)に記憶されるので、ちょうど良い値を見つけておけば、いつでも再現できるようにしてあります。

[○] BVH を読み込んだが、動かない。[ver.0.24 にて Fix]
→ エクスポートした3Dツールの座標系の違いで読み込めなかったり、見た目がおかしくなったりするようです。当アプリで読み込める BVH は「Y-up 右手座標系」(OpenGL系、Maya, Daz3D など)の座標系になります。「Z-up 右手座標系」(3ds Max など)の場合は、見た目がおかしくなります。[>>3Dツールごとの座標系など]
また内部ライブラリのバージョンアップでも修正されました(当アプリでは v0.24β以降)。
参考までに初期に読み込まれている BVH ファイル(「test.bvh」)を同梱して置きます(このファイルと同じ座標系)。
[>>現在、読み込み可能が確認されているもの]

[○] 表情が反映されないものがある。少しおかしくなることがある。[ver.0.28 にて、一定パターンのみ Fix(ユーザー定義のため、全てはカバーできない)]
→ VRM のプリセット表情として使えるものが、キャラによって定義されてない場合があります。定義されてないものは無視されます。
「あいうえお」が揃ってない、片目を閉じる(ウインク)などが定義されてない、等のモデルも多くあります。
また、笑顔のブレンドシェイプ(プリセットの Joy)が「目のにっこり+口を大きく開けて笑う」のようになっているとき、リップシンクの「あいうえお」が実行されると、2重に口のモーフがブレンドされておかしくなることがあります。

※CRS では VRM のプリセット表情の「Joy」(にっこり), Blink_L」(ウィンク),「Blink」(目閉じ)を使っています。当アプリでは 0.27β以降、VRoid に関しては Joy のデフォルト定義「~_ALL_Joy」の代わりに「~_EYE_Joy」を使用することによって、リップシンクとの2重モーフにならないように対処しています(VRoid Studio 0.2.8 までで生成された VRM で確認済み)。また、VRoid 以外では Joy に定義した各ブレンドシェイプの名前に "mouth", "あ", "ワ" が含まれている場合、口のブレンドシェイプとみなして無視するようにしています。



■VRM(3Dモデル)の入手方法

 一般的に Web で配布されているものを利用できます。各モデルの利用方法はその規約に従って下さい。

ニコニ立体ちゃん
ニコニ立体で "vrm モデル配布" を検索
東北ずん子
(アプリのヘルプボタン → 下の方へスクロールして、画像アイコンをクリックでもブラウザからダウンロードできます)
アクシア[縞パン ver.]アリシア色改変モデル。頒布許可済み[@不沈空母]&ニコニ立体ちゃんライセンス
(アプリのヘルプボタン → 下の方へスクロールして、画像アイコンをクリックでもブラウザからダウンロードできます)
VRMファイルを作ってみたい
※アクシア(縞パン ver.) は実験用にこの手順に従ってコンバートしたものです(テクスチャだけ変えている[利用許可済み@不沈空母])。

※一般配布している VRMファイルの情報などありましたら、ツイッターでもメールでも教えて貰えると嬉しいです。このページにまとめて掲載させて頂きます。特にスマホでもすぐに利用できる(= zip でない:スマホユーザーが簡単にDLできるようにするため)ものに関してはアプリ内のヘルプに掲載させて頂きます。


(c) SSS LLC.(ず・ω・きょ)
(c) DWANGO Co.,Ltd. ニコニ立体ちゃんライセンス



■BVH(モーションファイル)の入手方法

 一般的に Web で配布されているものを利用できます(データによっては読み込み失敗するものもあります)。各モーションファイルの利用方法はその規約に従って下さい。

Perfume Global Site
 Projectページの「DOWNLOAD」から BVH と音楽ファイルがダウンロードできます。「Terms of use」(利用規約)にチェックを入れるとDLできるようになります。
 音楽もダウンロードできるので、[ライブラリ追加アイコン]で読み込みできます。
※BVH は「Y:180」にチェック入れて再生した方が良いです。

Live Animation モーションライブラリ
 各サンプルの「BVHサンプルXX」(XX:番号)を右クリックで「名前を付けてリンク先を保存」でダウンロードできます。
※「Y:180」にチェック入れて再生した方が良いものがほとんどです。

The Daz-friendly BVH release of CMU's motion capture database
 カーネギー・メロン大のデータベースのモーションキャプチャーデータをBVHに変換したものらしいです。各 zip のリンク(「Zip file for BVH directories 01-09」など)をクリックすると、緑色のダウンロードボタンが出るので、それを押すと zip がダウンロードできます。ボタンを押すと、海外らしい結構うざい広告(笑)が出ますが、閉じてしまって構いません。現在 2548 ものモーションキャプチャーデータを利用できます(>>モーションリスト)。特に使用に制限はなく、商業利用も可能のようです。元々学術研究用でもあるので、割と好きに使っても問題ないと思われます。

 また、少しページの下へ行くと「SECONDARY RELEASE: Daz-friendly hip-UNCORRECTED BVH files release.」というのもあります。こちらは「Hips」のオフセットが0でない(補正されてない)データのようです。「フットスリップの問題が発生した場合にのみ、これらのファイルを選択して使用してください」と書いてありますが、読み込んでみると、少しスムーズな動きをする気がします。ただし、いきなりコマ飛びのような動きも多いです。

 ここの他のサンプル(3dsMAX用など)を試してわかったんですが、エクスポートした3Dツールの座標系の違いで読み込めなかったり、見た目がおかしくなったりするようです。使用ライブラリの BVH インポータは OpenGL系(「Y-up 右手座標系」:Daz3Dも同じ)なので、例えば 3dsMAXなど「Z-up 右手座標系」の場合は見た目がおかしくなります

※直接読み込める BVHファイルの情報などありましたら、ツイッターでもメールでも教えて貰えると嬉しいです。このページにまとめて掲載させて頂きます。




■使用できる BVH を作る(変換する)

 現在の所、ヒエラルキーによるボーン構造やオフセット値など(?)、VRMLiveViewer で利用できるものとそうでないものがあるのがわかっています(使用ライブラリの BVH インポータは OpenGL系(「Y-up 右手座標系」:Daz3Dも同じ)なので、例えば 3dsMAXなど「Z-up 右手座標系」の場合は見た目がおかしくなります)。

 なので、非常に大雑把で正しいやり方とは言えないと思いますが、以下に簡単に利用できる方法を書いておきます。それは「Live Animation」(掲載時点:β4.65)というアニメーション(モーション)作成ソフトを使うことです。このソフトはキネクト(モーションキャプチャー)を取り込んだり、他のモーションファイル形式を変換したりできるソフトです。動作確認はフリー版(β4.65)でしてます。

1.Live Animation を起動したら、キャラ(アバター)の中から「johnny」君を選択します。他のキャラでも試してみましたが、「johnny」君以外は上手く行かないようです(追加アバターも試しましたが、見た目がおかしくなるようです) BVHインポータのバージョンアップにより修正されました(当アプリでは v0.24β以降)。



2.次に再生するモーションファイルをドラッグ&ドロップします(形式は何でも構わないが、BVHエクスポートしても、読み込めるのとそうでないものがあるので注意)。例えば「モーションライブラリ」で配布されている「~.lam」なども利用できます。必要あればアニメーションを編集しても構いません。



3.メニューから「ファイル>エクスポート>BVH」をすると、BVHエクスポートのダイアログが開きます。ファイル名以外の項目では赤で囲んだ「右手座標系」と「基本ポーズの反転」をチェックする必要があるようです。他のオプションは任意で設定して下さい。



 あとはエクスポートした「~.bvh」を VRMLiveViewer の [BVH 読込] から読み込みます。何らかが原因で使用できない場合は、エラーログが表示されます([×]ボタンで閉じることができます)。fbx や他の BVH 配布サイトの bvh も試したことがありますが、利用できないものも多くあります(→ BVHインポータのバージョンアップで修正されました(当アプリでは v0.24β以降)。ただし、3dsMAXでエクスポートしたものなど「Z-up 右手座標系」の場合は見た目がおかしくなります)。

踊りのモーションla_001_SIL_TOSH.lam)をBVH変換したものと、
エキスポートサンプルをそのまま読み込んで踊らせてみた例。
顔の向きを少し上に(正面を向くように)編集している。



■利用したオープンソースプロジェクト・素材など

[VRMビューワ/VRMインポーター]
VRM
UniVRM

MIT License
Copyright (c) 2018 DWANGO Co., Ltd. for UniVRM
Copyright (c) 2018 ousttrue for UniGLTF, UniHumanoid
Copyright (c) 2018 Masataka SUMI for MToon

[リップシンク]
Oculus Lipsync
Oculus VR, LLC Software Development Kit License
Copyright (c) 2015 Oculus VR, LLC. All rights reserved.

AniLipSync
MIT License
Copyright (c) 2018 XVI Inc.

[ライブモーション&ステージ&楽曲]
ユニティちゃんライブステージ!

ユニティちゃんライセンス(UCL)
(c) Unity Technologies Japan/UCL

[東北ずん子アイコン]
(c) SSS LLC.(ず・ω・きょ)

[ニコニ立体ちゃん(アリシア)]
(c) DWANGO Co.,Ltd. ニコニ立体ちゃんライセンス

※各素材の著作権は著作者に帰属します。各素材についての利用方法などは、各著作者が提示されてる利用規約などをご確認下さい。








(関連記事)
【Unity】VRoid(VRM)をインポートして動かす
【Unity】Androidのトーストやダイアログ、通知、音声認識、ハード音量操作など基本的な機能を使えるプラグインを作ってみた


category: Unity

thread: ソフトウェア開発

janre: コンピュータ

tag: VRoid  VRM  サンプル 
tb: 0   cm: --

【Unity】VRoid(VRM)をインポートして動かす  


 VRoid Studio が 8/3 に一般公開されたのでさっそく触ってみた。


 VRM 形式は VRChat が流行った経緯もあり、3Dアバターファイルフォーマットとして新たに MMD とは別に VR 用として利用できるフォーマットだ(そのためか VRoid 上では A ポーズだね(笑))。Unity 向けの C# による標準実装(UniVRM)がオープンソースで提供されていて、簡単に扱えるということなので試してみた。

 実際にとても簡単で、ざっくり説明しておくと、UniVRM の Unity パッケージが配布されているので、それをプロジェクトにインポートし、VRoid Studio で作ったキャラをエクスポート(*.vrm ができる)。保存した VRM ファイルをプロジェクトにインポート(ドラッグ&ドロップでOK)すれば良い。あとは見た目が少しおかしくなったりするので、その辺りを適当に修正し、以前にやった方法で歩かせたりすれば動かせる。そんな感じだ。


(※) Unity 5.6.3p1 - 2018.2.1f1 / VRoid Studio 0.1.1 - 0.2.3 / UniVRM 0.40 / Windows10(x64) で確認



●VRoid Studio から VRM を作成する

1.まだ VRoid Studio をインスールしてないなら、公式サイトからダウンロードして、インストールしよう。ページの下の方へ行くと、Windows版 と Mac版 の両方がある。アーカイブを解答したら、そのフォルダ(ファイル)ごと移動すれば使えるようだ。

VRoid Studio

 ただ、私がバージョン 0.1.1 と 0.2.0 を試した所、保存したデータが完全互換では無いようだ(というか髪の位置がずれる)。またインストしたフォルダが別れていると(「VRoidStudio-v0.1.1-win」「VRoidStudio-v0.2.0-win」のように)起動時の「開く」メニューの一覧には出てこない(そして起動後には他のデータを読み込めない)。キャラを作り込むのは正式版が出てからの方が良いかも知れない(笑)。まぁ、現在はベータ版なので、今後改善されることを願おう。

●ver.0.1.1 で作ったもの


●ver.0.2.0 で読み込んだら髪の位置がずれた(笑)

※「髪型編集」で「手描きグループ1」を選択肢、「ガイドパラメータ>高さ」を調整すると直るようだ。


2.「新規作成」でキャラを作った場合は少なくとも髪だけは付けておこう。実際最初に髪を塗るのが面倒だったので(笑)、そのままデフォルトでエクスポートしてみたが、Unity で読み込んだら髪の部分だけ空の白いメッシュが重なってしまった。面倒だったらアホ毛一本でも良いかも知れない(笑)。


3.後はとにかくキャラができたらファイルのメニューからエクスポートするだけだ(ver.0.2.x 以降は「撮影・エクスポート」に移動した)。また、私が試したのは ver0.1.1 だったが、アプリが不安定なのか、閉じようとしたらフリーズしたりするので、なるべく途中経過は保存(Ctrl+S)しておいた方が良いかも知れない。

 エクスポートしたファイル(*.vrm)は「C:\Users\(ユーザー名)\Documents\vroid\avatars」(※Windows版)のように、個人用のドキュメント以下に作られるようだ。


※下のボタンが見えない場合は、ウィンドウを広げれば見えるようになる




●VRM を Unity にインポートする

1.Unity のプロジェクトを開いたら、まずは先に変換ツール「UniVRM」をプロジェクトにインポートしよう。

UniVRM

 パッケージは「UniVRM-x.xx.unitypackage」と「UniVRM-RuntimeLoaderSample-x.xx.unitypackage」(x.xx はバージョン)の2つがあるが(掲載時点:0.40)、「~RuntimeLoader~」となってる方は、実行時にリアルタイムに読み込む方法のようだ。ここでは「UniVRM-x.xx.unitypackage」の方をインポートして欲しい。


 「API Update Required」ダイアログが出たら「I Made a Backup. Go Ahead!」(自動でアップデート)で良い。



2.UniVRM のインポートが終わったら、VRoid Studio でエクスポートした VRM ファイルを適当なフォルダでも作って(ここでは「Model」としている)、エクスプローラーから(※Windowsのとき)ドラッグ&ドロップしよう。インポートにはしばらく時間かかるが、変換が完了したら、ドロップしたフォルダにプレファブができる


「NormalMap settings」が出たら「Ignore」の方が良いかも知れない。「Fix now」でも構わないが、インポート(変換)したマテリアルがギラギラとする(NormalMap を手動で直すしかない)。私はその辺りはあまり詳しくないのでお任せする(←とりあえず動けば良い人(笑))。
(※ver.0.2.x 以降では修正されてるようなのでどちらでも可。)



3.あとはプレファブをヒエラルキーに置いて、カメラやモデルの位置を調整すれば良い。ここではカメラの Z軸を -2 に、モデルの Y軸の回転を 180 度にしてカメラに写している。


※「NormalMap settings」は「Ignore」にしている




●VRoid(VRM)キャラを動かす

 VRMのインポートに成功したら、キャラを動かしてみよう。基本的には以前に書いた「SDプロ生ちゃんを動かす!」と同じ方法で良い。大まかに説明すると、歩行モーションなどのアニメータや、キー入力を判定するスクリプトをモデルにアタッチすれば良い。ただ、一から作るのは結構大変なので、とりあえず既存のアセットやスクリプトを利用して動かしてみよう。

1.歩行モーションなどはユニティちゃんのアセットを利用するので公式サイトからダウンロードしよう。サイトにアクセスして、画面右上の「DATA DOWNLOAD」を押し、規約を読んだら一番下の方にある「ユニティちゃんライセンスに同意しました。」をチェックし、「データをダウンロードする」でダウンロードページへ移動できる。ここでは「ユニティちゃん 3Dモデルデータ」を押してパッケージをダウンロードして欲しい。

 また、ここでは余談になるが、ユニティちゃんパッケージは Unity4 時代からリリースされているので、ユニティちゃん自体を使いたいときは、「ユニティちゃんシェーダー (Unity 5.4/5.5β 対応版)」や「ユニティちゃんスクリプト(Unity 5 修正パッチ)」もダウンロード&インポートした方が良い。

ユニティちゃん公式


2.パッケージをダウンロードしたら、プロジェクトにインポートしよう(掲載時点:UnityChan_1_2_1.unitypackage)。
インポートしたら、ヒエラルキーに置いた VRoid のモデルをクリックし、インスペクタで「Animator>Contoller」に「UnityChanLocomotions」をセットしよう。エディタでプレイしてみればわかるが、これだけで立ちアニメーションが再生される(わかりづらいかも知れないが、拡大してみると、ゆっくりと呼吸してるようにアニメしている)。



3.アニメーションするようになったら、次に操作できるようにスクリプトをアタッチする前に、ヒエラルキーで空のオブジェクトを作り(Creat Empty:ここでは「VRoid_Locomotion」としている)、その子要素になるように VRoid モデルをドロップしよう。また、親オブジェクト(VRoid_Locomotion)の Position や Rotation などは全て (0, 0, 0) にしておく(微調整はモデルの方の Transform でやる)

 これはそのモデルを変更したくなったとき、簡単に中身だけ変えられるようにしておく処置だ。VRoid Studio 本体もしばらくはアップデートされるだろうし、その互換性も微妙なようなので、このようにしておくと更新時に非常に楽になる。



4.VRoid モデルを空オブジェクトの子要素に置いたら、次に操作スクリプトを親オブジェクト(VRoid_Locomotion)にアタッチしよう。ここではユニティちゃんの操作スクリプト「UnityChanControlScriptWithRgidBody.cs」に少し修正を入れて、他のキャラでも使えるようにした「UnityChanControlScriptWithRgidBodyForAny.cs」スクリプトをアタッチする。そのスクリプトは以下からダウンロードして欲しい。

>>サンプルのスクリプトをダウンロード
(Google Drive を利用。画面右上にあるダウンロードアイコンを押す)


5.スクリプトをアタッチしたら、「Rigidbody」の「Constrains>Freeze Rotation」と「Capsule Collider」の「Center>Radius」「Height」だけは調整しておこう。シーンビューを平行投影モードにすると調整しやすい。真横からみると VRoid モデルは少し足が埋まってしまうようなので(※VRoid Studio 0.1.1 で作った場合(?))、ここでは子要素(モデル)の Y軸を 0.07 だけ上げている。値は任意で良い。



●モデルの Position.Y だけ 0.07 にして少し調整している(※VRoid Studio 0.1.1 で作った場合(?))


6.ここまでできたらプレイしても良いが、床が無いので奈落の底に落ちる(笑)。ヒエラルキーに Cube を置いて床にしても良いが、せっかくなので、モックに使えるアセットをインポートしてみよう。

 Unity2017 まではメニューから「Assets>Import Package>Prototyping」でアセットをインポートできたのだが、Unity2018 以降はどうやら「StandardAssets」は廃止されたようだ(たぶんインポートしたアセット同士でバージョンによるエラーや競合などのトラブルが発生しやすいため)。まぁ、オブジェクトだけなら Unity4 時代のものでも問題は無いので(スクリプトやシェーダーは古いバージョンをインポートするとエラーが出やすいので注意)、アセットストアから「Sample Assets (beta) for Unity 4.6」をダウンロードしよう。

Sample Assets (beta) for Unity 4.6


7.ダウンロードが完了したらインポートするときに、ダイアログで一度「None」を押し、全てをオフにしてから、「Prototyping」のフォルダのみをチェックしよう(Prototyping 以下は自動でチェックが入る)。全てをインポートすると時間がかかるのと、エラーが出る可能性があるので、気をつけよう(Unity4 時代のものは特に)。



8.インポートができたら、フォルダ「Standard Assets/Prototyping/Prefabs/」以下に色々なオブジェクトが入っている。床には「FloorPrototype64x01x64」辺りを置けば良いだろう。他にも階段「Step~」、坂「Ramp~」など色々あるので、好きに置いてみると良いだろう。

 ちなみに、Ctrl キーを押しながらオブジェクトをドラッグすると、一定幅で移動することができるので、グリッド状にキレイに配置することができる。この幅はメニュー「Edit>Snap Settings...」で設定できるので上手に使おう。



9.プレイしてみると上手く動いただろうか?動くには動いたが、カメラは追従してないかも知れない。カメラを追従させる方法は、一番簡単なやり方だと、「Main Camera」を作ったキャラの子要素にしてしまえば良い。ヒエラルキーで「Main Camera」を「VRoid_Locomotion」にドラッグ&ドロップしよう。子要素にしたら距離やアングルなどを調整して完了だ。




 カメラをスムーズに動かすには以前の記事「SmoothFollow3」辺りを使うと良い。ちなみにアセットストアで配布しているプラグインにはスワイプ、ドラッグ、ピンチ操作できるスクリプトなども一緒に入っているので、スマホなどで使ってみたいときには良いだろう。




※カメラスクリプト「SmoothFollow3」はプラグインにも同梱されています。





(関連記事)
【Unity】VRM(VRoid)をライブステージで踊らせるアプリを作ってみた
【Unity】SDプロ生ちゃんを動かす!
【Unity】SDユニティちゃんを動かす!(Unity4)
【Unity】【C#】ユニティちゃんをサクっと簡単に動かす!(Unity4)
【Unity】【C#】SmoothFollow3(SmoothFollow に回転・遠近・高さ操作とピンチ・スワイプとの連携機能を付けた拡張版)


category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: VR  VRoid  VRM  サンプル 
tb: 0   cm: --

【Unity】【C#】UI-Text 版 FPS(フレームレート)をリアルタイムに測定して表示する  


 以前に作ったレガシーGUI を uGUI(UI.Text)に移植しただけのもの。

 StandardAssets には「FPSCounter」という FPS測定ライブラリも入っているが、ソースを見てみると、一定間隔の平均を求めてるようなので、できればリアルな(平均でない)値を見たいと思って、わざわざ移植した(と言ってもほとんどまるっとコピーだが(笑))。

(※) Unity 5.6.3p1 - 2018.2.1f1 / Windows10(x64) で確認



●UI-Text 版 リアルタイムにFPSを測定して表示する
using System.Text;
using UnityEngine;
using UnityEngine.UI;

// FPS 測定値を UI-Text に表示する
// http://fantom1x.blog130.fc2.com/blog-entry-307.html
public class FpsText : MonoBehaviour {

public Text targetText; //表示する UI-Text
public string displayFormat = "{0:F1} FPS"; //表示フォーマット(F0 とすれば小数点以下は無くなる)

//測定用
int tick = 0; //フレーム数
float elapsed = 0; //経過時間
float fps = 0; //フレームレート

StringBuilder sb = new StringBuilder(16);

// Use this for initialization
private void Start () {
if (targetText == null)
targetText = GetComponentInChildren<Text>();
}

// Update is called once per frame
private void Update () {
tick++;
elapsed += Time.deltaTime;
if (elapsed >= 1f) {
fps = tick / elapsed;
tick = 0;
elapsed = 0;

if (targetText != null)
{
sb.Length = 0;
sb.AppendFormat(displayFormat, fps);
targetText.text = sb.ToString();
}
}
}
}

 使い方は UI の Text などにアタッチし、targetText に表示する Text をセットすれば完了だ(未セットでも子要素までは自動で探す)。

 測定(計算)方法は Update() による Time.deltaTime で集計した単位時間あたりのフレーム数である。あくまでもフレーム更新での測定なので、現実時間に近い測定(連続した時間)にしたいなら Time.realtimeSinceStartup で測定するのも良いだろう(StandardAssets の FPSCounter は Time.realtimeSinceStartup での測定)。

 実は色々な FPSカウンターを見てみると、測定(計算)方法はまちまちなので、用途に合わせた選択をした方が良いだろう。例えば StandardAssets の「FPSCounter」では連続的な時間での平均的な fps 測定に、今回の「FpsText」では一定更新毎(連続的というより、更新約1秒ごとにフレーム数を測定という感じ)の測定には向いてるかも知れない。具体的に言えば、平均化されてる場合は、もたったりして、ある程度バラついてもフラットな値になるが、平均化されてない場合は、もたったりしてる瞬間は値が激変する。自分がどちらの値を欲してるかで決めれば良い。

 以前の記事にも書いたが完全にフレームごとの超詳細な測定をしたいなら、毎フレーム「1f / Time.deltaTime」で計算する方法もある。ただしこの場合、ほんの僅かなもたりでも(人間の感覚ではわからないくらい小さいものでも)値として出るので、通常使う分には向いてないかも知れない(また、物凄く更新が速いため、見づらいという欠点もある)。仕様はケースバイケースで合わせた方が良いだろう。


※この記事のスクリプトはプラグインのライブラリにも同梱されています。


※とりあえず試してみたい方には、最新版をビルドした apk デモをダウンロードできます。動作確認にもどうぞ。

プラグインデモをダウンロード
(Google Drive を利用)


Android 4.2以上
※「提供元不明アプリのインストール」許可が必要です。


(関連記事)
【Unity】【C#】FPS(フレームレート)をリアルタイムに測定して表示する
【Unity】【C#】FPS(フレームレート)をリアルタイムに測定して表示するv2(4隅選択可能で、画面サイズの変更にも対応版)


category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: Unityライブラリ  C# 
tb: 0   cm: --

【Unity】【C#】テキストファイルの読み書きをする(リソース/ストレージ)  


 Unity では内部リソースからテキストファイルを読み込む方法が非常に簡単に用意されているが、それとは別に外部のリソース(ストレージ等)でテキストファイルを読み書きする方法も書いておこう。

 またついでに Android でプラグインを利用して読み書きする方法も紹介しておく。ちなみに Unity から C# で直接 SDカードに書き込もうとすると、アクセス拒否で失敗するが、プラグインを利用する場合は、SDカードにも書き込むことが可能だ。エクスプローラみたいなファイル選択も使えるので、ユーザーが自由にファイルの読み書きを行えるようなシステムを作るには役に立つだろう。

 ここでは C# スクリプト例はインスタンスメソッドとして書いておくが、static なライブラリとして利用したいなら、例外処理を throw などすれば良いと思う。とりあえず簡単な実装を書いておこう。自由に改造でもして使って欲しい。


(※) Unity 5.6.3p1 - 2018.1.8f1 / Windows10(x64) で確認



■リソースからテキストアセットを読み込む(Unity ビルトイン機能)

 ここでは Unity の機能を使って、アプリに内包したテキストファイルを読み込んでみよう。

 これは Unity のエディタ上であらかじめリソースとして持っておき、ランタイム時にロードする方法だ。Unity では「Resources」というフォルダを作っておくと、起動後にリソースとしてテクスチャやデータなどを読み込むことができる。ここにテキストファイルを置いておけば、「TextAsset」として簡単に扱える。それを利用して読み込んでみよう。

●リソースからテキストアセットを読み込む(メソッド定義)
using UnityEngine;
using UnityEngine.UI;

public string textAssetName = "Texts/テスト"; //拡張子はいらない
public Text displayText; //表示するUI-Text

//リソースからテキストアセットを読み込む
void LoadTextAsset(string name)
{
if (string.IsNullOrEmpty(name) || displayText == null)
return;

TextAsset textAsset = (TextAsset)Resources.Load(name, typeof(TextAsset));
if (textAsset != null)
displayText.text = textAsset.text;
else
Debug.Log("Not found TextAsset : " + name);
}

●使用例(メインでのコードなど)
using UnityEngine;

//ロードボタンのコールバックハンドラ
public void OnLoadTextAsset()
{
LoadTextAsset(textAssetName);
}

 読み込み先テキストには UI-Text(displayText)を用いているが、もちろん string 型の引数のメソッドを作って直接読み込んでも良い。これはあくまでも例なので、その辺りは用途に応じて書き換えて欲しい。

●「Resources」フォルダを作り、その配下にテキストファイル(UTF-8)をインポートしておく。

 テストするには UI-Button などを適当に配置し、「Button」の「OnClick()」にスクリプトの「OnLoadTextAsset()」を登録すれば良い。





●「テスト用スクリプトのアタッチ例


●ファイルの内容は任意(UTF-8)

※ランタイム時にログを見るにはプラグインライブラリのプレファブ「DebugConsole」をシーンに置き、コード中の Debug.Log() を XDebug.Log() に置き換えて下さい。また、インスペクタで「displayText」に「DebugConsole」以下の「Text」を登録します。



■ローカルストレージなどでテキストファイルの読み書きをする(C# スクリプト)

 次にパス(ファイル名)を指定してテキストファイル(UTF-8)を読み書きすることをやってみよう。

 例ではフォルダ(ディレクトリ)に「Application.persistentDataPath」を使っているが、これはプラットフォームによって変わるデフォルトの永続的な保存先となる。また、会社名(company name)やアプリ名(product name)でもフォルダ分けされる。詳しくは公式マニュアルで確認して欲しい。

(参考)Application.persistentDataPath

●ローカルストレージなどでテキストファイルの読み書きをする(メソッド定義)
using System;
using System.IO;
using System.Text;

//テキストをファイルから読み込む(行読み)
//※Android で SD カードから読み込みをするには、「AndroidManifest.xml」にパーミッション("READ_EXTERNAL_STORAGE" または "WRITE_EXTERNAL_STORAGE")が必要。
string LoadText(string path)
{
StringBuilder sb = new StringBuilder(1024); //※capacity は任意

try
{
using (StreamReader reader = new StreamReader(path))
{
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
sb.Append(line).Append("\n");
}
}
}
catch (Exception e)
{
Debug.Log(e.Message);
return null;
}

return sb.ToString();
}

//テキストをファイルに保存
//※Android で External Storage に書き込みをするには、「AndroidManifest.xml」にパーミッション("WRITE_EXTERNAL_STORAGE")が必要。
//※セキュリティ上、Unity から直接 SD カードには保存できない。
bool SaveText(string text, string path)
{
try
{
using (StreamWriter writer = new StreamWriter(path))
{
writer.Write(text);
writer.Flush();
writer.Close();
}
}
catch (Exception e)
{
Debug.Log(e.Message); //Access to the path "filename" is denied. → パーミッションが無い, 書き込みアクセス不可(SDカードなど)
return false;
}
return true;
}

●使用例(メインでのコードなど)
using UnityEngine;
using UnityEngine.UI;

public string filename = "test.txt";
public Text displayText; //表示するUI-Text

//ロードボタンのコールバックハンドラ
public void OnLoadClick()
{
if (string.IsNullOrEmpty(filename) || displayText == null)
return;

string path = Path.Combine(Application.persistentDataPath, filename); //プラットフォームによってパスは異なる

if (!File.Exists(path))
{
Debug.Log("Not found : " + path);
return;
}

string text = LoadText(path);
if (!string.IsNullOrEmpty(text))
displayText.text = text;
}

//セーブボタンのコールバックハンドラ
public void OnSaveClick()
{
if (string.IsNullOrEmpty(filename) || displayText == null)
return;

string path = Path.Combine(Application.persistentDataPath, filename); //プラットフォームによってパスは異なる

if (SaveText(displayText.text, path))
Debug.Log("Save to : " + path);
}

 テストするには UI-Button などを適当に配置し、「Button」の「OnClick()」にスクリプトの「OnLoadClick()」「OnSaveClick()」をそれぞれ登録すれば良い。
●UI-Button 配置とテスト用スクリプトのアタッチ例

●UI-Button のコールバック登録例

 読み書きするテキストには UI-Text(displayText)を用いているが、もちろん string 型の引数のメソッドを作って直接読み書きしても良い。これはあくまでも例なので、その辺りは用途に応じて書き換えて欲しい。

 なお、Android でSDカードに読み書きする場合は以下のパーミッションが必要になる。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />'

 パーミッションについての説明が必要なら以前の記事を参照して欲しい。


※ランタイム時にログを見るにはプラグインライブラリのプレファブ「DebugConsole」をシーンに置き、コード中の Debug.Log() を XDebug.Log() に置き換えて下さい。また、インスペクタで「displayText」に「DebugConsole」以下の「Text」を登録します。



■Android でファイル選択+テキストファイルの読み書きをする(プラグイン利用)

 ついでにプラグインに入っている「StorageLoadTextController」と「StorageSaveTextController」(~/FantomLib/Prefabs/System/ 以下。検索で探すと簡単)というテキストファイル読み書きの機能を使ってみよう。これら「~Controller」は Android 標準のファイル選択機能を使い、テキストファイルを読み込み・書き込みをしてくれるものだ。これら機能はプラグイン内部に実装されているので、自分でコードを書く部分は、機能呼び出しと結果受け取りだけで良い。

 ではまず、その機能呼び出しと結果受け取りのコードだけ書いてしまおう。名前は任意で良い。これらは各「~Controller」や UI-Button のコールバックハンドラとなる。

●コールバックハンドラ例(メインでのコードなど)
using UnityEngine;
using UnityEngine.UI;
using FantomLib;

public Text displayText; //表示するUI-Text

//読み込んだテキストを UI-Text に表示する
public void OnStorageLoad(string text)
{
if (string.IsNullOrEmpty(text) || displayText == null)
return;

displayText.text = text;
}

public StorageSaveTextController storageSaveTextController; //※インスペクタで登録

//UI-Text のテキストをファイルに保存する
public void OnStorageSave()
{
if (displayText == null || string.IsNullOrEmpty(displayText.text)) //※空は保存しない場合
return;

if (storageSaveTextController != null)
storageSaveTextController.Show(displayText.text);
}

//エラーステータス用コールバックハンドラ
public void OnError(string message)
{
Debug.Log(message);
}

 あとはヒエラルキーに「StorageLoadTextController」と「StorageSaveTextController」(~/FantomLib/Prefabs/System/ 以下。検索で探すと簡単)を置き、UI-Button など(※名前は任意)を Canvas に配置したら、インスペクタでコールバックを設定するだけだ。

●「StorageLoadTextController」と「StorageSaveTextController」を置く。テスト用スクリプトのアタッチ例。

●スクリプト(TextFileTest)へコールバック登録する
※または、StorageLoadTextController.OnResult に直接 UI.Text.text を登録しても良い。

●UI-Button から機能呼び出しをする


 あとはビルドするだけだが、プラグインを含む場合のビルドは「AndroidManifest.xml」が必要になる。その辺りは以前の記事にまとめてあるので参照して欲しい。もちろん「Build Settings...」にシーンを追加するのを忘れずに。

●ファイルの内容は任意(UTF-8)

※ランタイム時にログを見るにはプラグインライブラリのプレファブ「DebugConsole」をシーンに置き、コード中の Debug.Log() を XDebug.Log() に置き換えて下さい。また、インスペクタで「displayText」に「DebugConsole」以下の「Text」を登録します。


※この記事のUnityアセットはプラグインとして配布されています。


※とりあえず試してみたい方は、最新版をビルドした apk デモをダウンロードできます。動作確認にもどうぞ。

プラグインデモをダウンロード
(Google Drive を利用)


Android 4.2以上
※「提供元不明アプリのインストール」許可が必要です。


(関連記事)
【Unity】AssetStore版 FantomPlugin のセットアップ
【Unity】Androidのトーストやダイアログ、通知、音声認識、ハード音量操作など基本的な機能を使えるプラグインを作ってみた
【Unity】【C#】UnityEvent, Action, delegate, interface でのコールバック実装方法とインスペクタでの登録


category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: Unityリファレンス  Unityプラグイン  C# 
tb: 0   cm: --


プロフィール

Social

検索フォーム

全記事一覧

カテゴリ

ユーザータグ

最新記事

リンク

PR

▲ Pagetop