はじめに
この記事はVTuber Tech #1 Advent Calendar 2018の2日目の記事です
昨日の記事は@nkjzmさんによる、【初心者向け】UnityとLive2Dで拡張しやすいVTuber配信システムを作る方法です。
こんにちは。あきら(@sh_akira)です。
普段はバーチャルモーションキャプチャーというVRMモデルを操作するアプリを作っています。
今回はそれとは別のアプローチで自分だけのVTuber環境を作ってみようという記事です。
VR機器で3Dモデルを動かして、いわゆるVTuberのようなことが出来るようになるまでを
昨日の記事と同じくUnityを初めて触る人でも分かるように開発環境のインストールから全て説明しています。
今回モデルのファイル形式にVRM形式を使用しています。
VRM形式については、VRMの何がいいの?という話 こちらに分かりやすくまとまっていますのでご覧ください。
記事中のソースコードはパブリックドメインです。プラグインについては各ライセンスに従ってください。
完成品
完成品(埋め込み用) pic.twitter.com/tz2CqTJBYr
— 🗾あきら☎︎@VMC0.21 (@sh_akira) 2018年12月2日
必要な機材
- HTC Vive (Oculus/WinMRは今回説明しませんが基本的に手順は変わらず動くはずです)
- VR Ready PC (Windows 10です)
必要なプラグイン
- UniVRM 0.45 (VRMモデルの読込をします)
- SteamVR plugin 2.0.1 (VR機器を扱います) *** 最新だとエラーになるそうです。コメント欄参照ください ***
- Final IK 1.8 (有料$90です。定期的にセールで半額になったりします。)
- OVRLipSync 1.28.0
- AniLipSync-VRM 1.0.0
使用モデル
- ニコニ立体ちゃん(アリシア・ソリッド)のVRMモデル
開発環境
- Unity 2017.4.15f
最近VRChatの開発環境がこのバージョンになったので今回は同じバージョンで開発します。
開発環境構築
Unityのインストール
まずはUnityをインストールします。
ダウンロードページからUnity 2017.x内にあるUnity 2017.4.15のUnity インストーラーをダウンロードします。
ダウンロードされたUnityDownloadAssistant-2017.4.15f1.exeを実行してください。
基本的にはデフォルトの設定のままNextで進んでいき、
インストール先の指定でそのUnityのバージョン名をフォルダにつけると複数のバージョンのUnityがインストールできます。
今回は"C:\Program Files\Unity 2017.4.15f1"にしました。
インストールが完了すると"Launch Unity"のチェックがあるので、チェックを入れたままFinishしてUnityを実行します。
プロジェクトの設定をする
※初めてインストールした場合この段階でUnityのアカウント登録やログインが必要になる場合があります。
画面の指示に従ってログインしてください。
Unityを起動するとプロジェクトを開く画面が表示されるので右上のNewを押します。
Project Nameに好きなプロジェクト名を付けます。今回はMyVTuberとしました。
良ければCreate Projectを押します。
Unityの画面が表示されますが、分かりやすいようにレイアウトを変更します。
画面右上のDefaultを2by3に変更します
現在のScene(シーン)を保存します
画面中央のHierarchy内にあるUntitledを右クリックしてSave Scene Asを押し、シーンを保存します。
今回はそのままAssetsフォルダにプロジェクト名と同じMyVTuberという名前を付けて保存します。
Project内に今保存したMyVTuberが現れますが、このままだとアイコンが大きく見づらいため
画面下部のバーを一番左にしてリストに変更しておきます。
必要なアセットをインポートする
SteamVR Plugin
上部のWindowメニューからAsset Storeを開きます
検索欄にSteamVRと入力すると出てくるSteamVR Pluginを押します。
ダウンロードしてインポートを押します。するとImport Unity Packageの画面が出ますので、そのまま右下のImportを押してください。
その後このような画面が出た場合は、Accept Allを押します。
Unity 2018.3.xを使用する場合、メニュー内のPackageManagerからOpenVRをインストールする必要があります。この手順書通りのバージョンでは関係ありません
Final IK
次にAsset Storeの検索欄に Finalと入れると出てくるFinal IKを押します。
持ってない場合は購入して、ダウンロードしてインポートを押します。するとImport Unity Packageの画面が出ますので、そのまま右下のImportを押します。
UniVRM
UniVRMのリリースページからUniVRM-0.45_0c49.unitypackageをダウンロードします。
Unity上部のAssetsメニュー->Import Package->Custom Package...を押して、ダウンロードしたUniVRM-0.45_0c49.unitypackageを開きます。
するとImport Unity Packageの画面が出ますので、そのまま右下のImportを押してください。
以上で必要なアセットのインポートは完了なので、左上のSceneタブを押して元の画面に戻します。
正しくインポートできていれば右側のProject内のAssetsフォルダの下にPlugins、SteamVR、VRMの3フォルダがあるはずです。
VRMモデルをインポートする
Project内のAssetsを右クリックして出るメニューからCreate->Folderを選択して出来た新しいフォルダーにModelsと名前を付けます。
出来たModelsフォルダを右クリックしてShow in Explorerを押してエクスプローラを開きます。
Assetsフォルダが開くはずなので、Modelsを開いてください。まだ中身は空です。
ニコニ立体ちゃん(VRM)のページからダウンロードを押してダウンロードしたzipファイルを解凍します。
Alicia_VRM\Alicia\VRM内にAliciaSolid.vrmファイルがあるので、先ほど開いたModelsフォルダにコピーしてください。
Unityに戻ると自動でインポートが始まります。終わったらModelsフォルダを開いてください。AliciaSolidのPrefab(青い立方体のアイコン)が表示されていればインポート完了です。
VRMファイルにはそれぞれライセンスが設定されています。Prefabを選択するとInspector内のVRM Meta (Script)に
アバターの人格に関する許諾範囲(Personation / Charaterization Permission)
- アバターに人格を与えることの許諾範囲(A person who can perform with this avatar)
- アバターを操作することはアバター作者にのみ許される(Only Author)
- 明確に許可された人限定(Explictly Licensed Person)
- 全員に許可(Everyone)
- このアバターを用いて暴力表現を演じることの許可(Violent acts using this avatar)
- 不許可(Disallow)
- 許可(Allow)
- このアバターを用いて性的表現を演じることの許可(Sexuality acts using this avatar)
- 不許可(Disallow)
- 許可(Allow)
- 商用利用の許可(For commercial use)
- 不許可(Disallow)
- 許可(Allow)
- その他のライセンス条件(Other License Url)
- 上記許諾条件以外のライセンス条件がある場合はそのライセンス文書へのURLを記述
このようなライセンス情報が入っていますので、必ず使用するモデルの規約に従ってください。
実際に作ってみる
SteamVR Pluginを配置する
Project内のAssets\SteamVR\Prefabsにある[CameraRig]をドラッグしてHierarchyのシーン内に配置します。
配置したら画面上部の▶(Play)ボタンを押して実行してみます。
SteamVRが立ち上がって、HMDを認識していれば
このような画面が出ますのでYesを押します。何回か同じような画面が出るので全てYesを押してください。
するとこのような小窓が出てくると思いますので、Save and generateを押します。
しばらく処理されて元の画面に戻ったらSteamVR Inputの画面はxで閉じて構いません。
そうしたら再度画面上部の▶(Play)ボタンを押して実行してみます。HMDにGameタブと同じ画面(何もない空間と太陽とコントローラー)が表示されているはずです。SteamVRのメニューが表示される場合があるので、コントローラーのSteamVRメニューボタンで閉じます。これでVRの準備は完了です。もう一度画面上部の▶(Play)ボタンを押して実行を止めてください。
モデルを配置する
Project内のAssets\ModelsにあるAliciaSolidのPrefab(青い立方体アイコン)をドラッグしてシーン上に配置します。その際[CameraRig]の中に入れてしまったりしないように注意してください。画像の通りに配置されていればよいです。
また▶(Play)ボタンを押して実行してみます。アリシアさんを眺めるだけVRが完成しました。しばらく眺めて満足したら▶(Play)ボタンを再度押して実行を止めておきます。
Final IKを設定する
Herarchy上のCameraRigの中にあるController(Left)を右クリックしてCreate Emptyを押して出来たGameObjectを右クリックし、Renameを押して名前をLeftHandにします。
同様にController(Right)にRightHandを、CameraにHeadを作り、
LeftHand、RightHand、Headがそれぞれ画像のように配置されるようにします。
Hierarchy上のAliciaSolidを選択して、Inspectorを一番下までスクロールしたところにあるAdd Componentを押して、vrikと入力するとVR IKが出てきますので、それを選択します。
するとInspectorの一番下にVRIK (Script)が追加されるので、Solverを開き、SpineとLeft ArmとRight Armをそれぞれ開いておきます。
開いたSpine内のHead Targetに先ほど作ったHeadを、Left ArmのTargetにLeftHandを、Right ArmのTargetにRightHandをそれぞれドラッグして登録します。
この段階で一度▶(Play)ボタンを押して実行してみます。HMDを被って両手にコントローラーを持って動かしてみてください。手の位置に合わせて腕は動くし、頭の位置に合わせて体も移動するようになっているはずです。動かしてみると分かると思いますが、まだ色々問題があります。まず頭の位置が身長と合ってないし、自分の頭が見えてしまっていてリボンや頭の中が見えて困ります。それからコントローラーの位置に手が来ていますが、明らかに思っている位置と手の向きではないはずです。次はひとつづつこれを直していきます。何度も言っていますが、一度Playした後編集する際は▶(Play)ボタンを再度押して実行を止めておきます。
自分の頭がHMD内に映らないようにする/体がたまに消えるのを直す
VRMには自分の頭を非表示にするためのVRMFirstPersonというスクリプトが付いていますので、この機能を使えるように設定します。
メニューのEdit->Project Settings->Tags and Layersを開きます。
User Layer 9にFIRSTPERSON_ONLY_LAYER
、User Layer 10にTHIRDPERSON_ONLY_LAYER
と入力します。
※この9,10の数値や名称は今後のUniVRMの更新で自由に設定変更可能になる可能性があります。UniVRM0.45時点でのデフォルトです。
次にHierarchyの[CameraRig]内のCameraを選択して、InspectorのCamera内にあるCulling Maskの選択肢からTHIRDPERSON_ONLY_LAYERのチェックを外します。
このCameraは自分のHMDでの視点になっているカメラです。FIRSTPERSON_ONLY_LAYERというのは自分目線で表示するレイヤー(頭を除く体だけ)で、THIRDPERSON_ONLY_LAYERは他人から見たときに表示するレイヤー(頭も含む)なので、THIRDPERSON_ONLY_LAYERを外すことで自分視点から頭の表示を消します。
HierarchyからAliciaSolidを選択して、Inspector一番下のAdd Componentを押して、New Scriptを選択します。
NameにFirstPersonSetup
と入力しCreate and Addを押します。
追加されたFirst Person Setup (Script)を右クリックしてEdit Scriptを押して、スクリプトを開きます。
FirstPersonSetup.csが表示されたら、void Start(){ }内に
GetComponent<VRM.VRMFirstPerson>().Setup();
foreach (var renderer in GetComponentsInChildren<SkinnedMeshRenderer>(true))
{
renderer.updateWhenOffscreen = true;
}
を追加して、
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FirstPersonSetup : MonoBehaviour {
// Use this for initialization
void Start () {
GetComponent<VRM.VRMFirstPerson>().Setup();
foreach (var renderer in GetComponentsInChildren<SkinnedMeshRenderer>(true))
{
renderer.updateWhenOffscreen = true;
}
}
// Update is called once per frame
void Update () {
}
}
このようにしたら保存して画面を閉じます。追加したのはVRMのFirstPersonを初期化する関数の呼び出しと、カメラ位置によって体が描画されなくなるのを防ぐためにすべてのSkinnedMeshRendererのUpdate When Offscreenをオンにする処理です。
この状態でまた▶(Play)ボタンを押して実行してみます。先ほどまで自分の頭が見えて邪魔だったはずですが、表示が消えて体だけ見えるようになっているはずです。確認したら▶(Play)ボタンを押して実行を止めます。
手の位置と向きを直す
手の向きと位置が今のままだと間違っているのでこれを直します。Final IKのVRIKは"手首"の位置を設定するものですが、SteamVRのコントローラーは、コントローラーの先端位置を示しているのでこのようなずれが生じます。なのでコントローラー側を手首の位置と向きになるようにオフセットしてあげることにします。
Hierarchy内LeftHandを選択し、InspectorのTransformのPositionに-0.03,0.025,-0.12
を、Rotationに-40,0,90
を入力します。
同様にRightHandを選択し、InspectorのTransformのPositionに左手と逆回転の0.03,0.025,-0.12
を、Rotationに-40,0,-90
を入力します。
また▶(Play)ボタンを押して実行してみます。手の位置が大体実際の位置に合うようになっていればOKです。モデルによっては少し位置が違うかもしれないので数値はお好みで調整してください。
モデルの大きさと実際の体型のずれを合わせる
今のままだとアリシアさんと自分の身長や腕の長さが合わず、立つと視点が高くなっていたり、腕を伸ばしきる前にアリシアさんの腕が伸びきっていて、手からコントローラーが離れていくようになってしまっていると思います。このずれをなるべく無くしていきます。
▶(Play)ボタンを押して実行します。Hierarchyから[CameraRig]を選択してInspectorのTransform内のScaleの値を変更します。
まずはXとZの値を両手を広げたときにちょうどモデルの手が真っ直ぐになるように(実際に手をまげたらモデルも同じように曲がるように)なる数値を入れます。Play中は即座に反映されるので、0.8あたりから0.79,0.78,0.77・・・という風に微調整して自分の体形に合った数値を探してください。XとZには同じ数値を入れてください。今回は0.8を入れました。
次にYの値を調整します。真っ直ぐ立って画面上のアリシアちゃんのかかとが浮かず、膝が曲がらない程度にYの値を調整してください。今回は0.85にしました。
この状態のまま入力したX,Y,Zの値を覚えておいてください。再度▶(Play)ボタンを押して実行を停止して、入力したものが元に戻ってしまっているはずなので、再度覚えておいたX,Y,Zを入れなおしてください。
がに股なのを直す
見てわかる通り、足が開き過ぎていてしゃがんだりするとひざが外側に向いたりして可愛くないです。これを直します。
HierarchyからAliciaSolidを選択し、InspectorのVRIK内のLeft Leg、Right Leg、Locomotion内の値をそれぞれ変更します。
ひざの向きを変えるために
Left Leg内Swivel Offsetを15
Right Leg内Swivel Offsetを-15
歩幅を変えるために
Locomotion内の
Foot Distanceを0.15
Step Thresholdを0.4
Max Velocityを0.3
Velocity Factorを0.3
Root Speedを30
に変更します。すべての値は画像を確認してください。
歩幅などは自分の好みで変更してください。
配信用の環境を作る
ここまでで自分の体をVR機器で良い感じに動かせるようになりました。VTuberになるためにはこの動きを別のカメラで撮ってその映像を見せないといけません。
そのための設定をしていきます。
メインカメラの表示順を上げる
今までのままだと実行中のGame画面にはHMDと同じ映像が表示されています。これを別のカメラからの映像に切り替えて、カメラを正面に持ってくることにします。
Hierarchy上のMain Cameraを選択し、まずはTransformのPositionを0,1,-2
に設定します。
それからCameraのDepthを1
に、Target EyeをNone (Main Display)
に設定します。
▶(Play)ボタンを押して実行します。HMDには今まで通り自分の視点での画面が表示されて、Unity側のGame画面には配置したMain Cameraの映像が表示されているはずです。確認出来たら▶(Play)ボタンを押して実行を止めます。
自分の姿をHMD内で確認できるようにする
今のままだとHMDを被ってしまうと自分の姿がどのようにカメラに写っているか確認できないので、カメラの映像を表示させるパネルを設置します。
ProjectのAssetsフォルダを右クリックして、Create->Custom Render Textureを選びます。
出来たファイルにはMainCameraTextureと名前を付けます。
出来たMainCameraTextureを選んで、InspectorのSizeに1920x1080
と入力します。
Hierarchy上のMain Cameraを右クリックし、Duplicateを選択します。
新しく増えたMain Camera(1)を選択して、先ほど作ったMainCameraTextureをTarget Textureにドラッグ&ドロップして設定します。
HierarchyのMyVTuberを右クリックしてGameObject->3D Object->Quadを選択します。
出来上がったQuadを右クリックしてRenameでMonitorPanelにします。
作成したMonitorPanelのTransformのPositionを0,0.9,-2
、Rotationを0,180,0
、Scaleを-3.2,1.8,1
に設定します。
ScaleのXをマイナスにすると、左右の表示が反転するためミラー表示が出来ます。自分の動きを確認するときに左右が逆だととても操作しづらいのでミラーにしています。
そして先ほど作成したProjectのAssetsフォルダにあるMainCameraTextureをHierarchy上のMonitorPanelにドラッグ&ドロップします。
MonitorPanelのInspector内の一番下にあるMainCameraTextureのShaderをStandardからUnlit->Textureに変更します。
▶(Play)ボタンを押して実行します。目の前に鏡のように自分の姿が映っているはずです。動いて確認してみてください。動くのを確認したら▶(Play)ボタンを押して実行を止めます。
髪の毛が正しく揺れていないのを修正する
UniVRMとFinal IKを同時に使用した場合、特に設定をしないとその場で頭だけ動かしたときに髪の毛が正しく揺れてくれません。なのでこれを修正します。
UnityのEditメニューからProject Settings->Script Execution Orderを開きます。
出てきたScript Execution Orderの右下の+ボタンを押して、
大量にメニューが出てくるので下向き三角▼を押し続けて一番下から2番目の、VRM.VRMSpringBone
を選びます。
VRM.VRMSpringBoneがリストの一番下に10400(一番大きい数字)で追加されたことを確認します。
同様にVRM.VRMSpringBoneColliderGroupも入れて10500になったら、右下のApplyを押してください。
出来たらそのまま▶(Play)ボタンを押して実行します。その場で頭を左右に動かしてみてください。髪の毛が綺麗に揺れるようになっていると思います。動くのを確認したら▶(Play)ボタンを押して実行を止めます。
リップシンクを入れる
今のままでは喋っても口が動きません。リップシンクをいれてみます。
OVRLipSync 1.28.0
OVRLipSync 1.28.0のページに行き、
規約に同意する場合チェックを入れてダウンロードしてファイルを展開してください。
Unity上部のAssetsメニュー->Import Package->Custom Package...を押して、展開した中のLipSync\UnityPlugin\OVRLipSync.unitypackageを開きます。
今までと同じように、Import Unity Packageの画面が出ますのでImportを押してください。
AniLipSync-VRM 1.0.0
AniLipSync-VRM 1.0.0のページからAniLipSync-VRM.unitypackageをダウンロードして、
Unity上部のAssetsメニュー->Import Package->Custom Package...を押して、ダウンロードしたAniLipSync-VRM.unitypackageを開きます。
同じように、Import Unity Packageの画面が出ますのでImportを押してください。
AniLipSync-VRMはこの記事のために新しく作りました。
リップシンクの設定
まずProject内のAssets\Oculus\PrefabsフォルダにあるLipSyncInterfaceをHierarchyにドラッグして配置します。
次にAssets\AniLipSync-VRM\PrefabsにあるAniLipSync-VRMをHierarchyにドラッグして配置します。
Inspectorの一番下、Anim Morph Target (Script)内のBlend Shape Proxyに配置しているVRMモデルをドラッグ&ドロップして設定します。
以上でリップシンク設定は完了です。▶(Play)ボタンを押して実行します。マイクに向かってあ、い、う、え、おと声を出して口が動くか確認してください。確認したら▶(Play)ボタンを押して実行を止めます。
まばたきを入れる
今はずっと目が開きっぱなしで瞬きをしないので怖いです。自動まばたきを入れます。
HierarchyからAliciaSolidを選択し、Inspectorの一番下のAdd Componentでblinkerと検索すると出てくるBlinkerを選びます。
Blinker (Script)が設定されるので値を好きなように変更します。
- Inter Val(次のまばたきまでの秒数、0秒~指定秒数までのランダムでまばたきします)
- Closing Time(閉じたままの時間)
- Opening Seconds(開くアニメーションの時間)
- Close Seconds(閉じるアニメーションの時間)
今回はそのままにしておきます。▶(Play)ボタンを押して実行します。指定秒数内でランダムにまばたきすることを確認します。確認したら▶(Play)ボタンを押して実行を止めます。
手首がねじれるのを解決する
HMDで自分の手首を見てみると、雑巾絞りのようにねじれてしまっているように見えます。これは手の回転を手首だけ突然回しているため発生しています。
Final IKにはこれを緩和するためのTwistRelaxerスクリプトが入っているのでこれを適用します。
HierarchyからAliciaSolidを選択し、InspectorのVRIK (Script)内のReferencesの中にあるLeft Forearmに設定されているelbow_L (Transform)をダブルクリックします。
ひじの関節部が選択されるので、InspectorからAdd Componentを押してtwistと検索すると出てくるTwist Relaxerを選択します。
標準の設定だと強度と角度が強すぎて、逆におかしな回転をするようになるので、
Weightを0.4
、Parent Child Crossfadeを1
に設定します。
全く同じことをVRIK内のReferencesのRight Forearmに対しても設定します。
両肘にTwist Relaxerが設定された状態になったら再び▶(Play)ボタンを押して実行します。実行中にお好みの回転の値を探して確認後に設定しなおしも出来ます。確認したら▶(Play)ボタンを押して実行を止めます。
表情を変える
まばたきとリップシンクを設定したのである程度顔は動くようになりましたが、VRMは表情制御を行うことができます。なので今回はコントローラーのタッチパッド(スティック)を4分割して設定した表情に変えられるようにスクリプトを追加します。
ProjectのAssetsを右クリックしてCreate->C# Scriptを選択し、出来たスクリプトの名前をControllerInputManager
にします。
出来たControllerInputManagerをダブルクリックしてスクリプトを開き、中身を全て消して、
using AniLipSync.VRM;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Valve.VR;
using VRM;
public class ControllerInputManager : MonoBehaviour
{
public VRMBlendShapeProxy blendShapeProxy;
public Blinker blinker;
public AnimMorphTarget animMorphTarget;
private SteamVR_ActionSet[] actionSets;
// VRMの表情
private Dictionary<BlendShapeKey, float> shapeValueDictionary = new Dictionary<BlendShapeKey, float> {
{new BlendShapeKey(BlendShapePreset.Neutral), 0.0f }, // NEUTRAL(標準)
{new BlendShapeKey(BlendShapePreset.Blink), 0.0f }, // BLINK(目を閉じる、まばたき)
{new BlendShapeKey(BlendShapePreset.Joy), 0.0f }, // JOY(喜び)
{new BlendShapeKey(BlendShapePreset.Angry), 0.0f }, // ANGRY(怒り)
{new BlendShapeKey(BlendShapePreset.Sorrow), 0.0f }, // SORROW(悲しみ)
{new BlendShapeKey(BlendShapePreset.Fun), 0.0f }, // FUN(楽しみ)
{new BlendShapeKey(BlendShapePreset.Blink_L), 0.0f }, // BLINK_L(左目閉じる)
{new BlendShapeKey(BlendShapePreset.Blink_R), 0.0f }, // BLINK_R(右目閉じる)
{new BlendShapeKey("><"), 0.0f }, // ><(アリシアちゃん専用表情)
};
private List<BlendShapeKey> keyList;
private int GetKeyIndex(BlendShapePreset preset) { return keyList.FindIndex(d => d.Name == preset.ToString().ToUpper()); }
private int GetKeyIndex(string preset) { return keyList.FindIndex(d => d.Name == preset.ToUpper()); }
private BlendShapeKey GetKey(BlendShapePreset preset) { return keyList[GetKeyIndex(preset)]; }
private BlendShapeKey GetKey(string preset) { return keyList[GetKeyIndex(preset)]; }
// Use this for initialization
void Start()
{
keyList = new List<BlendShapeKey>(shapeValueDictionary.Keys);
actionSets = SteamVR_Input.actionSets;
if (actionSets == null) { actionSets = SteamVR_Input_References.instance.actionSetObjects; }
}
// Update is called once per frame
void Update()
{
if (blendShapeProxy == null) return;
var sources = SteamVR_Input_Source.GetUpdateSources();
foreach (var source in sources)
{
if (source == SteamVR_Input_Sources.Any) continue;
foreach (var actionSet in actionSets)
{
foreach (var action in actionSet.allActions) //ボタン
{
if (action is SteamVR_Action_Boolean)
{
var actionBoolean = (SteamVR_Action_Boolean)action;
if (actionBoolean.GetStateDown(source))
{
var name = actionBoolean.GetShortName();
if (name == "InteractUI") // トリガー半引き
{
}
else if (name == "GrabPinch") // トリガー全引き
{
}
else if (name == "Teleport") // タッチパッド押し
{
}
else if (name == "GrabGrip") // グリップボタン押し
{
}
}
}
else if (action is SteamVR_Action_Single) //Axis
{
var actionSingle = (SteamVR_Action_Single)action;
if (actionSingle.GetChanged(source))
{
var name = actionSingle.GetShortName();
var axis = actionSingle.GetAxis(source);
if (name == "Squeeze") // トリガー
{
}
}
}
else if (action is SteamVR_Action_Vector2) // Padやスティック
{
var actionVector2 = (SteamVR_Action_Vector2)action;
if (actionVector2.GetChanged(source))
{
var name = actionVector2.GetShortName();
var axis = actionVector2.GetAxis(source);
//
// タッチパッドの座標(両手とも)
// (0, 1)
// (-1, 0)(0, 0)(1, 0)
// (0,-1)
//
// タッチパッドを離した時は(0,0)が飛んでくる
//
if (name == "TouchPad")
{
var isLeft = source == SteamVR_Input_Sources.LeftHand;
//全ての表情を一旦無効にする
foreach (var key in keyList)
{
shapeValueDictionary[key] = 0.0f;
}
if (Mathf.Approximately(axis.x, 0.0f) && Mathf.Approximately(axis.y, 0.0f)) //中心(離した時)
{
//まばたきとリップシンクを復活させる
blinker.enabled = true;
animMorphTarget.curveAmplifier = 100f;
shapeValueDictionary[GetKey(BlendShapePreset.Neutral)] = 1.0f;
}
else
{
//表情とぶつからないようにまばたきを止めてリップシンクを弱くする
blinker.enabled = false;
animMorphTarget.curveAmplifier = 0.1f;
if (axis.x < 0) // 左
{
if (axis.y > 0) // 左上
{
shapeValueDictionary[GetKey(isLeft ? BlendShapePreset.Blink_L : BlendShapePreset.Blink)] = 1.0f;
}
else if (axis.y < 0) // 左下
{
shapeValueDictionary[GetKey(isLeft ? BlendShapePreset.Joy : BlendShapePreset.Angry)] = 1.0f;
}
}
else if (axis.x > 0) // 右
{
if (axis.y > 0) // 右上
{
shapeValueDictionary[isLeft ? GetKey("><") : GetKey(BlendShapePreset.Blink_R)] = 1.0f;
}
else if (axis.y < 0) // 右下
{
shapeValueDictionary[GetKey(isLeft ? BlendShapePreset.Sorrow : BlendShapePreset.Fun)] = 1.0f;
}
}
}
//表情を適用する
blendShapeProxy.SetValues(shapeValueDictionary.ToList());
}
}
}
}
}
}
}
}
このコードに置き換えてください。置き換えたら上書き保存してください。
HierarchyのMyVTuberを右クリックしてGameObject->Create Emptyを選び、出来たGameObjectを右クリックしてRenameでControllerInputManager
にしてください。
作成したHierarchy上のControllerInputManagerを選択して、InspectorのAdd Componentでcontrollerinputと検索して出てくるController Input Managerを選択してください。
画像のようにBlend Shape ProxyにAliciaSolid、BlinkerにもAliciaSolid、Anim Morph TargetにAniLipSync-VRMをそれぞれドラッグ&ドロップで登録してください。
次にタッチパッドをSteamVRで使えるように設定します。
Hierarchyの[CameraRig]内のController (Left)を選択してInspectorのSteam VR_Behaviour_PoseのPose Actionの選択肢を開き、Add...を選択します。
こんな画面が出るはずなので、ActionsのIn側の+ボタンを押して、
NameにTouchPad
(大文字小文字が区別されますので正しく)、Typeをvector2にして、Save and generateを押します。
途中このような画面が出たらSaveを押してください。
しばらく出力に時間がかかった後、同じ画面に戻るので今度はOpen binding UIを押してください。
ブラウザでSteamVRのBinding設定画面が開きますので、Editを押します。
出てきた画面を一番下までスクロールして左側のTrackpadの+ボタンを押します。
選択肢が出ますので一番上のTRACKPADを選んでください。
左下にTRACKPADが追加されるのでその中のPositionのNoneを押し、選択肢からtouchpadを選びます。
下のMirror Modeにチェックが入ってなかったらチェックを付けて、Save Personal Bindingボタンを押します。
名前を付けるか聞かれるのでそのままSaveを押します。
これで設定は完了なのでブラウザは閉じて構いません。
Unityに戻って、この画面はもう大丈夫なので右上の×ボタンで閉じます。
ここまで来たらいよいよ表情が動かせるはずです。▶(Play)ボタンを押して実行します。
タッチパッドを左上、右上、左下、右下とそれぞれ4分割してキーを割り当てています。割り当ては次の表のとおりです。
左手
ウインク(左) | ><(アリシア専用) |
---|---|
喜び | 悲しみ |
右手 |
両目閉じる | ウインク(右) |
---|---|
怒り | 楽しい |
確認したら▶(Play)ボタンを押して実行を止めます。
この表情変更スクリプトには、表情変更時にリップシンクで口が破綻しないように抑制する機能と、自動まばたきを一時停止する機能が入っているので表情が崩れません。
仕上げ
カメラにコントローラーが映らないようにする
自身の目からはコントローラーが見えるように(分かりやすさのため)するが、配信には映したくないのでカメラからは見えないようにします。
Hierarchyの[CameraRig]内のController (left)のModelを選択し、InspectorのLayerを9:FIRSTPERSON_ONLY_LAYERにします。
同様にController (right)のModelのLayerもFIRSTPERSON_ONLY_LAYERにしてください。
次にMain Cameraを選択し、InspectorのCulling MaskのFIRSTPERSON_ONLY_LAYERのチェックを外します。
同様にMain Camera(1)にも同じ設定をします。
この状態で▶(Play)ボタンを押して実行します。Unity上のGame画面と、HMD内の鏡にはコントローラーが映らなくなっているはずです。自分の手元にだけコントローラーが見えていたらOKです。確認したら▶(Play)ボタンを押して実行を止めます。
配信の合成用に背景をグリーンバックにする
この後好きな背景と合成して録画をするために自分以外の背景をGB(グリーンバック)にします。
Main CameraのClear FlagsをSolid Colorに変更し、Backgroundの色(最初は紺色)をクリックするとColorパネルが表示されます。
Rを0
、Gを255
、Bを0
にしてグリーンバックにしたらColorパネルを閉じます。
足元の水色の枠(プレイエリア表示)も消すために[CameraRig]を選択して、Layerを9:FIRSTPERSON_ONLY_LAYERにします。
その際子要素も変更するか聞かれますが、変更したくないのでNo, this object onlyを押してください。
この状態で▶(Play)ボタンを押して実行します。Unity上のGame画面はモデル以外全て緑色になっていて、HMD内の空間と鏡は今まで通りになったはずです。HMD内も緑にすると目がチカチカするのでこのままで完成です。確認したら▶(Play)ボタンを押して実行を止めます。
完成!
ついに自分のVTuberシステムが完成しました。実行可能形式に出力しましょう。
UnityのFileメニューからBuild Settings...を選びます。
設定は特に変えずにそのままBuildボタンを押してください。
いくつかファイルが出力されるので、空のフォルダ(今回はMyVTuber)を作成して、そこで保存を押します。
ビルドが終わるのを待つと・・・
出力先のフォルダが開きました。選択されているMyVTuber.exeが完成品になります。
早速MyVTuber.exeを実行してみてください。
解像度選択画面が表示されます。Windowedにチェックを入れて、好きな解像度を指定したらPlay!を押します。
グリーンバックのモデルが表示されました!ですが表情変更が出来ないはずです。これはBindingの設定がされていないためです。
HMDを被ってコントローラーのメニューボタンでSteamVRのメニューを開いてください。
このような画面になるので、Closeを押してEditを押します。
上で1度設定したのと同じ画面が表示されているので同じ要領で再度Trackpadの設定をします。
タッチパッドをなぞると画面はスクロールできます。
やることは全く同じです。Trackpadの+を押して、TRACKPADを選択したら、PositionのNoneをtouchpadに変えて、Save Personal Bindingします。
設定したらコントローラーのメニューボタンでSteamVRの設定画面を閉じます。
今度はタッチパッドを触れば表情が変わるようになっているはずです。
以上でVTuberアプリの設定は全て完了です。これでいつでも起動してVTuberになることが出来ます。
録画・配信
アプリを作っても録画や配信をして見せてこそのVTuberです。簡単に録画の説明もします。
録画に使用するアプリはOBSです。前日の@nkjzmさんのOBSの説明と少し重複しますが、こちらはWindows版で説明をします。
OBSのインストール
まずはOBSのダウンロードページからダウンロード インストーラボタンを押してOBSをダウンロードします。
そのまま実行してインストールを勧めます。特に何もなくNextを押して進めていけば良いです。
このままFinishしてOBSを起動させます。
自動構成ウィザードが出るのではいを押して実行します。
とりあえず録画を選んで次へ(後から変えられます)
解像度は1920x1080のまま次へ
私の環境ではこのようになりました。環境によっては違う設定になる場合もあります。このまま設定を適用を押します。
画面右下の設定を押します。
出力の録画フォーマットをmp4に変更します。flvは扱いにくいです。
そして録画ファイルのパスを確認します。このフォルダに録画された映像が保存されるので、覚えておくか好きなフォルダに変更してください。
確認出来たらそのままOKを押して設定を閉じます。
背景を設定する
今回はこちらの画像をお借りしました。
OBSのソース欄にある+ボタンから画像を選択します。
名前を背景画像に変更してOKを押します。
参照ボタンで好きな画像を選んだらOKを押します。
※画像の著作権等には注意してください。今回はフリー素材を使用しています。
モデルを合成する
MyVTuber.exeを起動して、グリーンバックにモデルが表示された状態にします。
シーンの+ボタンを押してゲームキャプチャを選択します。
こちらはMyVTuberと名付けてOKします。
モードを特定のウインドウをキャプチャに変更し、ウインドウに[MyVTuber.exe]: MyVTuberを選択します。少し待つと画面が表示されるので、OKを押してください。
背景の緑を透過させる設定をします。ソースのMyVTuberを右クリックしてフィルタを選択します。
左下の+ボタンからクロマキーを選択します。
フィルタ名はそのままクロマキーでOKします。
デフォルトで色キーが緑になっており、背景が透明になっています。類似性や滑らかさなどはモデルによって変わるので、適宜調整してください。
今回は特に問題なさそうなのでデフォルトのまま閉じるを押します。
マイクの設定をする
モデルが合成されたのを確認したら今度はマイクの設定をします。ミキサーのマイクの横にある歯車ボタンを押してプロパティを開きます。
デバイスが既定になっているので、実際に使用するマイク(今回はHTC Vive)を選択してOKを押します。
この状態で「あー」と声を出してみると、マイクのバーが動き、画面上のモデルの口は"あ"の口に開くはずです。
これで設定は完了です!
録画する
あとは録画開始ボタンを押すだけです!歩き回ったり表情を変えてみたりイケてる動画を撮ってください!
出来上がったアプリで撮った動画は記事冒頭の完成品の動画です。
おわり
明日は、@broken55さんによる「OBSを使った配信の基礎とTips」です。
VTuber Tech #1 Advent Calendar 2018
VTuber Tech #2 Advent Calendar 2018