JokerScriptでLive2Dの複数モーション再生

JokerScript上でアイドルモーション再生しつつ、顔だけモーション変えたい場合のスクリプトを書いてみました。
やり方は前に書いた[UnityでLive2Dの複数モーション再生](http://qiita.com/naotaro0123/items/b3cabee3ca0e0261e7ad)とほぼ同じです。
MotionQueueManagerを2つ作り、クラスを修正すれば[live2d_facemotion]タグで再生できるようになります。

# 開発環境
・Live2D_SDK_Unity_2.1.00_1_jp
・Unity5.2.0f3
・jokerscript_v041
・live2d_for_joker_plugin_031

# JokerScriptのカスタム部分
以下の4つスクリプトを修正します。修正部分はAddCodeとコメントを付けました。

**./JOKER/Scripts/Novel/ObjectSet/Live2dObject.cs**

```csharp:Live2dObject.csの173行目あたり
・
・
// モーション切り替え
public override void setMotion(string storage, string idle)
{
	this.rootObject.GetComponent<SimpleModel>().Motion_change(storage, idle);
}

// 顔モーション切り替え AddCode Start
public override void setFaceMotion(string storage, string idle)
{
	this.rootObject.GetComponent<SimpleModel>().FaceMotion_change(storage, idle);
}
// 顔モーション切り替え AddCode End
・
・
```

**./JOKER/Scripts/Novel/ObjectSet/AbstractObject.cs**

```csharp:AbstractObject.csの112行目あたり
・
・
public virtual void setMotion(string storage, string idle) { }
// AddCode Start
public virtual void setFaceMotion(string storage, string idle) { }
// AddCode End
・
・
```

**./JOKER/Scripts/Novel/Components/Live2dComponent.cs**

```csharp:Live2dComponent.csの346行目あたり
・
・
// AddCode Start
//IComponentTextはテキストを流すための機能を保持するためのインターフェース
public class Live2d_facemotionComponent : AbstractComponent
{
	public Live2d_facemotionComponent()
	{

		//必須項目
		this.arrayVitalParam = new List<string> {
			"name",
			"storage"
		};

		this.originalParam = new Dictionary<string, string>() {
            { "name","" },
            { "tag",""},
            { "storage",""},
			{ "idle", ""}
		};

	}

	public override void start()
	{

		string name = this.param["name"];
		string tag = this.param["tag"];
		string storage = this.param["storage"];
		string idle = this.param["idle"];
		List<string> images = new List<string>();
		if (tag != "")
		{
			images = this.gameManager.imageManager.getImageNameByTag(tag);
		}
		else
		{
			images.Add(name);
		}

		foreach (string image_name in images)
		{
			Image image = this.gameManager.imageManager.getImage(image_name);
			image.getObject().setFaceMotion(storage, idle);
		}
		this.gameManager.nextOrder();
	}
}
// AddCode End
・
・
```

**./JOKER_GAME/live2D/Scripts/SimpleModel.cs**

```csharp:SimpleModel.csの22行目あたり
・
・
    private Live2DMotion motion;							// モーションクラス
	private Live2DMotion faceMotion;						// 顔モーションクラス Add Code
	private MotionQueueManager motionManager;				// モーション管理クラス
	private MotionQueueManager faceMotionManager;			// 顔モーション管理クラス Add Code
	private L2DPose pose;									// パーツ切り替えクラス
	private L2DPhysics physics;								// 物理演算クラス
    private Matrix4x4 live2DCanvasPos;						// 表示位置
	private int motioncnt = 0;								// ファイル項番
	private int facemotioncnt = 0;							// 顔ファイル項番 Add Code
・
・
```

```csharp:SimpleModel.csの100行目あたり
・
・
/// <summary>
/// カメラがシーンにレンダリング後に呼ばれる
/// </summary>
void OnRenderObject()
{
	if (live2DModel == null) return;
	live2DModel.setMatrix(transform.localToWorldMatrix * live2DCanvasPos);
	// アプリが終了していた場合
	if (!Application.isPlaying)
	{
		live2DModel.update();
		live2DModel.draw();
		return;
	}
	// 再生中のモーションからモデルパラメータを更新
	if(motionManager != null )
	{
		motionManager.updateParam(live2DModel);
	}
	// Add Code Start
	// 再生中のモーションからモデルパラメータを更新 
	if (faceMotionManager != null)
	{
		faceMotionManager.updateParam(live2DModel);
	}
	// Add Code End
・
・
```

```SimpleModel.csの280行目あたり
// Add Code Start
/// <summary>
/// FACEモーションのチェンジ
/// </summary>
/// <param name="storage">モーションファイル名</param>
/// <param name="idle">アイドリング有無</param>
public void FaceMotion_change(string storage, string idle)
{
	int cnt = 0;
	for (int m = 0; m < mtnFiles.Length; m++)
	{
		if (mtnFiles[m].name == storage)
		{
			break;
		}
		cnt++;
	}

	// アイドルフラグがONなら、指定したモーションをアイドリングさせる
	if (idle != "")
	{
		facemotioncnt = cnt;
	}

	// モーションのロードをする
	faceMotion = Live2DMotion.loadMotion(mtnFiles[cnt].bytes);
	// フェードインの設定
	faceMotion.setFadeIn(mtnFadeines[cnt]);
	// フェードアウトの設定
	faceMotion.setFadeOut(mtnFadeoutes[cnt]);
	// モーション再生
	faceMotionManager.startMotion(faceMotion, false);
	// サウンドがあればボイス再生
	if (soundFiles[cnt] != null)
	{
		GetComponent<AudioSource>().clip = soundFiles[cnt];
		GetComponent<AudioSource>().Play();
	}
}
// Add Code End
```

# JokerScriptでの使い方（タグ）
シナリオファイル(scene1.txt)に以下のタグでモーションの同時再生ができます。
使い方はlive2d_motionと同じでidleをなしで1回だけ再生、idle="ON"とするとループ再生します。

```ini:scene1.txt
; 再生したいアイドルモーション
[live2d_motion name="haru" storage="haru_normal_08.mtn" ]

; 表情だけ変えたい場合の表情のモーション
[live2d_facemotion name="haru" storage="haru_normal_09_face.mtn" idle="ON"]
```
![001.gif](https://qiita-image-store.s3.amazonaws.com/0/15028/fa205969-f93e-30f1-890c-081f61546691.gif)

こんな感じにソースが見えてるので自由にカスタムしちゃって下さい！