CRIWARE Unity Plugin Manual  Last Updated: 2024-12-05
[CriAtom]LipSyncプラグインを使用したCriLipsDeformerForAtomSourceの再利用

サンプル内容

概要

複数キャラクターに対して、1つの CriLipsDeformerForAtomSource を再利用してリップシンクさせます。

cri4u_samples_criatom_expansion_lipsync_scene05_main.png

シーン情報


ミドルウェア ADX LipSync(CRI Lips), CRI ADX (CRI Atom)
サンプル Expansionサンプル
格納場所 /cri/unity/samples/UnityProject/Assets/Scenes/criatom/expansion/LipSync
シーンファイル Scene_05_LipSync_ReuseCriLipsDeformer.unity
ACFファイル /cri/unity/samples/UnityProject/Assets/StreamingAssets/ADXLipSync/ForADXLipSyncSample.acf
ACBファイル /cri/unity/samples/UnityProject/Assets/StreamingAssets/ADXLipSync/ForADXLipSyncSample.acb


プログラムの解説

複数キャラクターに対して、1つの CriLipsDeformerForAtomSource を再利用してリップシンクさせます。

CriLipsDeformer が内部的に管理している CriWare.CriLipsAtomAnalyzer はアンマネージメモリを多く消費します。
このため不要なハンドルを作成できないように Lipsライブラリ の初期化時に CriLipsAtomAnalyzer の作成上限数が決まっています。

よって CriWare.CriLipsAtomAnalyzer を複数個用意するのではなく、生成済みの CriWare.CriLipsAtomAnalyzer を再利用することをおすすめします。

再利用について

再利用にあたって、サンプルでは以下のリソースを用意します。

以下でそれぞれのリソースについて説明します。

CriAtomSource

キャラクターのセリフ用のキューを再生します。
サンプルではシーン上にキャラクター毎に配置しています。
覚え書き:
本サンプルでは音声再生プレーヤーをキャラクター毎に用意している想定でサンプルを作成しています。
音声再生プレーヤーは必ずしもキャラクター毎に分ける必要はありません。分けていない場合は以下の CriWare.CriLipsDeformerForAtomSource.AttachToAtomSource の呼び出しをスキップしてください。

private CriAtomExPlayback PlayAndLipSync(CriLipsDeformerForAtomSource lipsDeformer, CriAtomSource atomSource, ICriLipsMorph lipsMorph) {
// 解析器の付け替えをしない
// var result = lipsDeformer.AttachToAtomSource(atomSource);
Debug.Assert(result);
lipsDeformer.LipsMorph = lipsMorph;
UpdateSamplingRate(lipsDeformer.atomAnalyzer, atomSource);
return atomSource.Play();
}

ICriLipsMorph

実際にキャラクターモデルのリップシンクを行うクラスです。キャラクター毎に必ず1つ用意してください。
C#スクリプトからインスタンスを生成する場合は、以下のようにします。
private ICriLipsMorph criLipsMorphForRingo = null;
private void Start() {
criLipsMorphForRingo = new CriLipsMorphBlendShapeJapaneseVowel()
{
Target = ringo,
aIndex = ringo.sharedMesh.GetBlendShapeIndex("MOUTH_A"),
iIndex = ringo.sharedMesh.GetBlendShapeIndex("MOUTH_I"),
uIndex = ringo.sharedMesh.GetBlendShapeIndex("MOUTH_U"),
eIndex = ringo.sharedMesh.GetBlendShapeIndex("MOUTH_E"),
oIndex = ringo.sharedMesh.GetBlendShapeIndex("MOUTH_O"),
};
}
CriWare.CriLipsDeformerForAtomSource.LipsMorph にセットすると、次回からそのクラスを使用してリップシンクします。
private CriAtomExPlayback PlayAndLipSync(CriLipsDeformerForAtomSource lipsDeformer, CriAtomSource atomSource, ICriLipsMorph lipsMorph) {
lipsDeformer.LipsMorph = lipsMorph;
}
このとき元々 CriWare.CriLipsDeformerForAtomSource.LipsMorph にセットされていた ICriLipsMorph は CriWare.ICriLipsMorph.Reset が呼ばれて口を閉じ口に遷移させます。

CriLipsDeformerForAtomSource

内部的にリップシンクの音声解析器を1つ持ちます。
AtomSourceとICriLipsMorphの参照関係を受け持ちます。

リップシンクが必要なシーン中に固定数配置しておき、本サンプルのように必要なタイミングで各リソースの参照を与えることをおすすめします。