【Meta Quest】VRの世界で動くキャラを眺めて触りたい!設定方法まとめ【Unity】
Meta Questが楽しいです!
ゲームも面白いんですが、Unityを使うともっと楽しい!
自分で適当なアセットを配置して、その中を歩き回るだけでも楽しかったりします。
そんな楽しみ方の一つに「VRの世界でキャラクターを眺める」があります。(ありますよね?)
アニメやゲームが好きな人なら「目の前で動く等身大フィギュアに触れる」というのはインパクトあると思います。
けど、購入してから一ヶ月、やりたいことがうまくいかず試行錯誤の連続。
その都度、先人の方々の技術や情報を参考にさせて頂き、やりたいことが少しずつ出来てきました。
その中でも「これは便利で使える!」と思った機能や設定をまとめてみました。
[2020/02/02追記]
Meta Questではなく、「Oculus Link経由でRiftのPC向けアプリ」として動かしたい場合は、こちらの記事もどうぞ!
Unityでの新規プロジェクト作成、Oculus Integrationアセットの登録、カメラやコントローラの設定も書いてますので、ご参考になるかも知れません。
[2019/12/01追記]
・説明文や画像を大幅に追加しました。
・画像ファイルを簡単に取得できるので、「Oculus Link経由の画像」も使っています。その場合、「※Oculus Link画像」と記載しています。その他の画像は、Meta QuestかUnityの画像ですので、ご参考にしてくださいね。
使用環境について
以下の環境を使用しました。
- Meta Quest 128GB
- Unity 2018.4.1f1 Personal
- Unity Hub 2.2.1
- Oculus Integration 1.42
- Java 1.8.0_211
- Oculus Link ※一部画像のスクショ用
インストールや設定方法は、この記事では割愛しています。
ネット上に記事がたくさんありますので、そちらを参考にしてくださいね。
(1) MMDモデルをUnityにインポートする
UnityでMMDモデルを使う時、MMD4Mecanimが非常に便利です。
というよりは、これが無いと始まりません。
基本的な使い方は、「MMD4Mecanim チュートリアル(基本編).pdf」に一通りのことが書いてあります。
このツールとMMDモデルがあれば、インポート後に少し設定するだけで、Meta Questの世界でキャラを眺めることができます。以降の(2)から(4)も、MMD4Mecanimの機能を使ってますよ。
インポートの手順
- キャラクターをUnityにインポートする
pmxファイルだけでなく、フォルダそのものをUnityにD&Dします。pmxファイルだけをインポートしてしまうと、テクスチャが反映されず、キャラクターが真っ白になるので要注意です。
ネット上で配布されているMMDファイルをお借りする時は、ライセンスや利用規約を良く読んでおきましょう。
今回の例では、ニコニ立体公式キャラクター「ニコニ立体ちゃん(アリシア・ソリッド)」をお借りしました!
とてもかわいいキャラクターですよ。 - Projectのファイル一覧で、キャラクターの「MMD4Mecanimファイル」を選択する
アリシア・ソリッドの場合、「Alicia_solid.MMD4Mecanim」ですね。
- Inspectorで「利用規約」などを確認し、「同意する」をクリックする
- 「PMX2FBX」の画面で「Process」ボタンをクリックする
- 黒いコマンドプロンプトの画面が表示されるので、しばらく待つ
この処理で、MMDのPMXファイルが「Unityで使えるFBXファイル」に変換されるようですね。 - 作成された「FBXファイル」を選択する
拡張子が表示されないので分かりにくいですが、画面右下のバーを「一番右」に移動すると、「灰色のキャラクター」がアイコン表示されると思います。
- Inspectorの「Rig」で、[Animation Type]を「Generic」から「Humanoid」に変更し、「Apply」ボタンをクリックする
この設定を忘れると、キャラクターが動かないので気を付けましょう。 - 再度、Projectのファイル一覧を見てみると、手順6で選択したファイルが「カラー」になってるので、そのファイルをHierarchyにD&Dする
SceneでもD&Dできますが、どこかの記事で「Hierarchyの方が良い」とあったのでそうしてます。
インポートできました!
(2) 揺れそうなものが揺れる
髪や服、アクセサリーなどの「揺れもの」が物理演算で動いてくれます。
すべてが物理演算になるワケではなく、あらかじめMMD側で設定されている箇所が揺れるようです。
設定方法
[Inspector > MMD4 Mecanim Model > Physics]
- 「Physics Engine」を Bullet Physics に変更する
- 「Join Local World」のチェックを外す
- 「Frame Per Second」を 75 に変更する
目の前で揺れて動くのは良いものです!
(3) 手のモデルを表示する
VRの中で自分の手がコントローラなのはちょっと寂しい。
このサイトを参考に、動く手をゲットしました。
設定方法も詳しく書いてあります。
指がアニメーションするのがリアルですね。
※Oculus Link画像
別のモデルもある
これとは別に、[/Assets/Oculus/SampleFramework/Core/] に CustomHands がありました。
これを使うと、指単位のアニメーション+スクリプト付きで便利なんですが、なぜか手の座標がずれてしまいました。
良い方法がないか調査中。
(4) 揺れものに触る
以下の手順で触れるようになります。
物理設定とコライダーがポイントですね。
設定方法
- 物理演算をオンにする
「(2) 揺れそうなものが揺れる」で設定した「Physics Engine」が Bullet Physics になっていればOK! - 適当な「透明なオブジェクト」を作成し、MMD4 Mecanim Rigid Body を追加する
例えば、Cubeを追加して、Mesh Rendererをオフにして、MMD4 Mecanim Rigid Bodyを追加します。Cubeの形は手の形に合わせて、長方形が良いかも知れません。
- 左右のコントローラに「透明なオブジェクト」を追加する
「(6) 手のモデルを表示する」を設定しているのであれば、左手の場合、「OVRCameraRig > TrackingSpace > LeftHandAnchor > OVRControllerPrefab > Hand > Cube」の位置ですね。
[設定サンプル(左手の場合)]
これで揺れものに触れるようになりました!
しかも触れるだけでなく、布のようなものであれば、めくることも可能。
そうなんです。めくれるんです!!
(5) モノをつかむ
モノをつかむにはOculus標準のOVRGrabberがありますが、hecomiさんのVR Grabberを使うと、離れた場所にあるものをつかめます。
設定方法
- Inspectorで、[OVRCameraRig > TrackingSpace]の下に、Vrg Left GrabberとVrg Right Grabberを追加する
- つかみたいものに VrgGrabbable を追加する
とにかく青いポインターがカッコいい。
※Oculus Link画像
モデル全体はつかめるが…
この方法で、キャラクターの揺れもの(服や髪)がつかめると良いんですが、いろいろ試してもつかめませんでした。残念。。。
根本的な仕組みが違うのでしょうか。
ちなみにですが、以下の設定をすると、モデル自体をつかめるようにはなります。
- MMDモデル自体に VRGrabble をアタッチする
- キャラクターに「自動的にコライダー」を作る
ここのサイトを参考にしました。
[Inspector > MMD4 Mecanim Model > Physics > Colliders > Generate Colliders]の「Processボタン」をクリックするだけで、身体や服などに当たり判定用のColliderを自動的に作ってくれます。超便利!
- 今回は重力制御はしないので、Rigidbodyで「Use Gravity」をオフ、「Is Kinematic」をオンにしておく
これはこれで面白いんですけどね。
※Oculus Link画像
(6) 表情を変える
いろいろ方法はあるようですが、設定だけで表情を変えるには、MMD4 Mecanim Morph Helperをアタッチするのが簡単です。
設定方法
[MMD4 Mecanim Morph Helperのパラメータ]
- 「Morph Speed」を 0.01 に変更する
- 「Morph Name」に名前を入れる(”にっこり”など)
「MMDモデルのHierarchy > U_Char > U_Char_1(なければ、U_Char_2とか) > BlendShapes」をクリックすると、変更できる表情のパターンが一覧表示されます。ここの文字を使います。
- 「Morph Weight」を 1 に変更する
通常時。
「にっこり」
複数アタッチすると、表情を合成できます。
「じと目」と「照れ」
複雑な表情変更をしたい場合は、プログラムする必要がありそう。
(7) モデルの両手両足を直接動かす
UnityでAnimatorのIK機能を使います。
プログラムが必要ですが、特別なアセットを追加しなくても使えるのが良いですね。
まずは下準備
先ほどのサイトを参考に、以下を準備しておきます。
- モデルが Humanoid になっているか確認する
「(1) MMDモデルをUnityにインポートする」の手順にありましたね。 - モデルに設定しているAnimatorのWindowを開いて、IKを設定する
例えば、「UnityChanActionCheck」を設定している場合、UnityChanActionCheckをダブルクリックして、「Layers > Base Layerr > 歯車アイコン」をクリックして、「IK Pass」にチェックを入れます。
- スクリプトを準備する
サンプルの「IKController」では、左手(LeftHand)と右手(RightHand)の操作をしていました。
同じような感じで、左足(LeftFoot)・右足(RightFoot)・左肘(LeftElbow)・右肘(RightElbow)・左膝(LeftKnee)・右膝(RightKnee)をコーディングしていきます。
操作用の玉を付ける
この例では、「半透明のSphere」を体の各所に配置してます。
そして、キャラクターにスクリプトに追加して、それぞれのTargetに、先ほどの「半透明のSphere」を設定します。
画像ではスクリプト名が「IKAnimator」になっていますが、元はサンプルの「IKController」です。諸事情で、名前を変更しているだけです。
キャラクターを動かす
これで、VR内で半透明のSphereを動かせば、キャラクターを好きなポーズに変更できます。
ブロックの上に座らせてみました。
※Oculus Link画像
この状態で「セーブ」ができると面白そうですね。jsonか何かに保存すると良いのかも。
また試してみよう。
有料アセット「Final IK」もあります
スクリプトが少し難しいかも知れませんね。
「(8) こっちを向いて欲しい」のサイトも参考になると思います。
別の方法としては、有料にはなりますが「Final IK」というアセットがあります。
このアセットを使うと、スクリプトが最初から準備されていたり、更に高度なことができるようになるんですが、定価が90ドルと結構高い。。。セールの時を狙うのが良いですね。
私も最近50%セールの時に購入して、いろいろ試している途中です。
設定方法はこのサイトが分かりやすかった。
(8) こっちを向いて欲しい
キャラクターが常にまっすぐを向いているのは、少し違和感がありますね。
カメラの方を向かせるには、方法がいくつかあるようです。
設定方法メモ
- AnimatorのIKを使う
目線だけでなく、顔自体が動くのがリアル!
Look Targetには OVRCameraRig の CenterEyeAnchor を設定します。
- アセット「Head Look Controller」を使う
ちょっと設定は面倒ですが、確かにこっちを向いてくれました。 - MMDモデルのBlendShapesを使う
MMDモデルによっては、BlendShapesの設定の一つとして「視線追跡」を準備してくれている場合があります。名前は「カメラ目線、コッチミンナ、こっちみんな、コッチミテ、カメラ、カムラ」などいろいろ。もしこんな名前のBlendShapesがあれば、オン(値を100)にして見てくださいね。
こっち見た!
対応していればIKがお手軽ですね。
これが、
こうなります。
(9) キャラクターに動いて欲しい
とりあえず動いて欲しい場合、Unityちゃんのアセットが便利です。
公式サイトから「ユニティちゃん 3Dモデルデータ」をダウンロードしてインポートしておきましょう。
インポート時の注意
ここで1つ注意点があります。
インポートして、Unity上でプレイボタンを押すと、こんなエラーが起きると思います。
All compiler errors have to be fixed before you can enter playmode! Assets\UnityChan\Scripts\AutoBlink.cs(8,23): error CS0234: The type or namespace name ‘Policy’ does not exist in the namespace ‘System.Security’ (are you missing an assembly reference?)
以下の記事を参考に AutoBlink.cs を修正しておきます。
1行をコメントアウトか削除すればOK!
設定方法
これでやっと設定できます。
- 動かしたいキャラの Inspector > Animator > Controller で「UnityChanActionCheck」を選択する
- 「Add Component」ボタンをクリックして、Idle Changer.cs をアタッチする
VR内でYボタンを押すと、アニメーションを切り替えることができます。
なお、Controllerで「UnityChanARPose」を選択すると、アニメーションではありませんが、いろんなポーズをとってくれます。
これはこれで面白い。
うまく行かない場合もある
ちなみにですが、今回のように別モデルのControllerを使う場合、MMDモデルの体格や作り方によってはうまく動かない場合もあります。やけに手足が細くなったり、つま先だけ地面に張り付いたようになったり、とにかく表示がおかしい。
そんな時は、別のMMDモデルにするか、別のAnimatorを探してみてくださいね。
自分で作成・修正できないうちは、いろんな組み合わせを試すしかありません。。。
(10) まばたきして欲しい
目を開けっぱなしでは不自然です。
モデルがBlendShapesを持っている場合、BlendShapeBlinkを使うと定期的にまばたきしてくれます。
BlendShapesが無い場合、MMD4MFaceBlinkが良いですね。
どちらもスクリプトをアタッチ後、設定するだけでまばたきしてくれます!
BlendShapesの番号を調べる
例えば、この記事で使っている「アリシア・ソリッド」の場合、BlendShapesの「まばたき」は 24番でした。
この数値を Index に入れましょう。
(11) ジャギーを無くして滑らかにする
パソコンのUnity上で見るとキレイに見えるのに、Meta Quest上で見るとジャギーがひどくて目がチカチカしてました。
設定方法
この設定を試すと、かなりジャギーが低減されました!
いまは、eyeTextureResolutionScaleを「1.5f」にしてます。
Oculus Linkの場合
設定しなくてもジャギーは気になりませんでした。
スクリプトで「eyeTextureResolutionScale」は設定せず、デフォルトのまま使ってます。
(12) 3Dモデルにギリギリまで寄る
これを設定すると、目の直前までポリゴンが透明化しなくなります。
[OVRCameraRig > TrackingSpace > CenterEyeAnchor > Camera > ClippingPlanes > Near]
0.04くらいにしてます。
(13) 負荷を下げる
普段は見る事が少ない「視野角の周辺部」の描画を荒くして、負荷を下げてくれます。
負荷が気にならない場合は、設定しなくて良いと思います。
[2019/12/01追記]
いまはオフにしてます。
(14) コントローラで自分を動かしたい
部屋が狭い場合や座っている場合などは、ヘッドセット(カメラ)の行動範囲が限定されてしまいます。
そんな時は、コントローラで操作できると便利です。
設定方法
いろいろ方法はありますが、カメラに「OVR Player Controller」をアタッチするのが簡単です。
- Hierarchyで「OVRCameraRig」を選択する
- Inspectorの一番下にある「Add Component」をクリックする
- 「OVR Player Controller」を選択する
「Character Controller」と「OVR Player Controller (Script)」がアタッチされます。
これで、コントローラで操作できるようになります。
設定の補足
- 左スティックで移動、右スティックで回転します。
- 「Snap Rotation」をオフにするとなめらかに回転しますが、酔いやすくなるのでおすすめしません。回転の角度を「Rotation Ratchet」で変更できるので、45→30に変更するなどで対応した方が良いですね。
- カメラの高さは「Height」で変更できます。
キャラクターの後ろに回ったり、
地面ギリギリまで下がったり。
※Oculus Link画像
プログラムを改造して、カメラの高さをスティックやボタンで変更できれば更に便利そうですね。
まとめ
Meta QuestでMMDモデルを眺める時、便利でこれは使える!と思ったものをまとめてみました。
今回参考にさせて記事は、どれも分かりやすく大変参考になりました。
ありがとうございます。
Meta Quest+Unityでやりたいことはたくさんありますので、これからが楽しみです!
コメント
トラックバックは利用できません。
コメント (6)
Elbowと書くとエラーが起きる
WERUさん、コメントありがとうございます。
エラーが出るんですね。どこだろう。
サンプルスクリプト参考に下記のように追加で書いたのですが
どうしてもElbowがエラー起こしてますよという赤文字で警告されております
using UnityEngine;
using System.Collections;
public class IKController : MonoBehaviour {
[Header(“HandAnchors”)]
[SerializeField]
public Transform rightHandAnchor = null;
[SerializeField]
public Transform leftHandAnchor = null;
private Animator animator;
void Start()
{
animator = GetComponent();
}
void OnAnimatorIK()
{
if (!animator)
return;
if (rightHandAnchor != null)
{
animator.SetIKPositionWeight(AvatarIKGoal.RightHand, 1);
animator.SetIKRotationWeight(AvatarIKGoal.RightHand, 1);
animator.SetIKPosition(AvatarIKGoal.RightHand, rightHandAnchor.position);
animator.SetIKRotation(AvatarIKGoal.RightHand, rightHandAnchor.rotation);
}
if (leftHandAnchor != null)
{
animator.SetIKPositionWeight(AvatarIKGoal.LeftHand, 1);
animator.SetIKRotationWeight(AvatarIKGoal.LeftHand, 1);
animator.SetIKPosition(AvatarIKGoal.LeftHand, leftHandAnchor.position);
animator.SetIKRotation(AvatarIKGoal.LeftHand, leftHandAnchor.rotation);
}
if (rightHandAnchor != null)
{
animator.SetIKPositionWeight(AvatarIKGoal.RightFoot, 1);
animator.SetIKRotationWeight(AvatarIKGoal.RightFoot, 1);
animator.SetIKPosition(AvatarIKGoal.RightHand, rightHandAnchor.position);
animator.SetIKRotation(AvatarIKGoal.RightHand, rightHandAnchor.rotation);
}
if (leftHandAnchor != null)
{
animator.SetIKPositionWeight(AvatarIKGoal.LeftFoot, 1);
animator.SetIKRotationWeight(AvatarIKGoal.LeftFoot, 1);
animator.SetIKPosition(AvatarIKGoal.LeftHand, leftHandAnchor.position);
animator.SetIKRotation(AvatarIKGoal.LeftHand, leftHandAnchor.rotation);
}
if (rightHandAnchor != null)
{
animator.SetIKPositionWeight(AvatarIKGoal.RightElbow, 1);
animator.SetIKRotationWeight(AvatarIKGoal.RightElbow, 1);
animator.SetIKPosition(AvatarIKGoal.RightHand, rightHandAnchor.position);
animator.SetIKRotation(AvatarIKGoal.RightHand, rightHandAnchor.rotation);
}
if (leftHandAnchor != null)
{
animator.SetIKPositionWeight(AvatarIKGoal.LeftElbow, 1);
animator.SetIKRotationWeight(AvatarIKGoal.LeftElbow, 1);
animator.SetIKPosition(AvatarIKGoal.LeftHand, leftHandAnchor.position);
animator.SetIKRotation(AvatarIKGoal.LeftHand, leftHandAnchor.rotation);
}
}
}
こうすると
Assets\IKController.cs(65,46): error CS0117: ‘AvatarIKGoal’ does not contain a definition for ‘LeftElbow’
というエラーを返してきますお手上げです
なぜかFootだけはエラーが出ません、スクリプトが間違っているのかなあ?
関係ないと思いますがクエストは持ってなくPico4でテストしております
よろしくお願いします
WERUさん、コメントありがとうございます。
ElbowやKneeは AvatarIKGoal では無く、AvatarIKHint のようです。
例)AvatarIKHint.LeftElbow
確認してみてくださいね。
AvatarIKHint
ありがとうございます
今度はAssets\IKController.cs(62,33): error CS1503: Argument 1: cannot convert from ‘UnityEngine.AvatarIKHint’ to ‘UnityEngine.AvatarIKGoal’と出ておてあげです(´;ω;`)
AvatarIKHintの場合、animatorのメソッドは SetIKHintPositionWeight() や SetIKHintPosition() を使う必要があります。
以下の記事などを参考にしてみてくださいね。
■テラシュールブログ様
【Unity】Timelineのアニメーションに微調整を加える(Humanoid編)
■かめくめ様
UnityのIKを使って物を運ぶアニメーション