Unity を使ったモデルデータの制御

プロジェクトの新規作成から、初音ミクのLive2Dモデルを表示し、 XBOX 360 のコントローラを使ってパラメータやモーションを制御するまでを紹介する。


1. Live2D モデルを表示する

1.1 フォルダを作成
 ・Live2D
  - ライブラリ「Live2DUnity.dll」を格納
 ・Resources
  - 各種素材(モデルデータ、テクスチャ、音声など)を格納
 ・Scripts
  - スクリプトを格納
 ・Scenes
  - シーンを保存する

1.2 main.cs
 「Scripts」フォルダに main.cs を作成

1.3 空のゲームオブジェクトを作成
 「GameObject」メニュー→「Create Empty」をクリック。(Ctrl + Shift + N でも可)
 名前を「Miku」に変更する
 Position は (0, 0, 0)にする 

 このゲームオブジェクトに main.cs をドラッグ&ドロップでアタッチする



1.4 main.cs に記述

using UnityEngine;
using System.Collections;
using live2d; //Live2Dライブラリを使用

public class main : MonoBehaviour {
	
	public TextAsset mocFile; // mocファイル
	public Texture2D texture; // テクスチャファイル
	private Live2DModelUnity live2DModel; //Live2Dモデルクラス
	
	void Start ()
	{
		//初期化(Live2Dを使用する前に必ず1度だけ呼び出す)
		Live2D.init();
		//モデルデータを読み込む
		live2DModel = Live2DModelUnity.loadModel ( mocFile.bytes );
		//テクスチャの関連付け
		live2DModel.setTexture( 0, texture );
	}

	void Update ()
	{
	
	}

	// デフォルトでは DrawMeshNow でLive2Dモデルを描画するので OnRenderObject を使う
	void OnRenderObject ()
	{
		//表示位置と大きさの指定
		Matrix4x4 m1 = Matrix4x4.Ortho( 0, 900, 900, 0, -0.5f, 0.5f );
		Matrix4x4 m2 = transform.localToWorldMatrix;
		Matrix4x4 m3 = m2 * m1;
		live2DModel.setMatrix( m3 );		

		//頂点の更新
		live2DModel.update();

		//モデルの描画
		live2DModel.draw();
	}
}


1.5 moc ファイルとテクスチャを指定
 mocFile に .mocファイル、texture に .png ファイルをそれぞれドラッグ&ドロップ


1.6 再生ボタンを押してシーンを再生
 おそらく小さいく表示されるので、「Miku」のScale を(5, 5, 1)にする。



1.7 テクスチャを綺麗にする
 テクスチャをゴミ取りツールにかける

 綺麗にテクスチャを表示させるために設定を変更する
 ・Max Size を「1024」から「2048」に変更
 ・Format を「Compressed」から「Truecolor」に変更


 再生してモデルの状態を確認




2. パラメータを制御する

2.1 main.cs を編集

using UnityEngine;
using System.Collections;
using live2d; //Live2Dライブラリを使用

public class main : MonoBehaviour {
	
	public TextAsset mocFile; // mocファイル
	public Texture2D texture; // テクスチャファイル
	private Live2DModelUnity live2DModel; //Live2Dモデルのインスタンス
	
	void Start ()
	{
		//初期化(Live2Dを使用する前に必ず1度だけ呼び出す)
		Live2D.init();
		//モデルデータを読み込む
		live2DModel = Live2DModelUnity.loadModel( mocFile.bytes );
		//テクスチャの関連付け
		live2DModel.setTexture( 0, texture );
	}
	
	void Update ()
	{
		
	}
	
	// デフォルトでは DrawMeshNow でLive2Dモデルを描画するので OnRenderObject を使う
	void OnRenderObject ()
	{
		//表示位置と大きさの指定
		Matrix4x4 m1 = Matrix4x4.Ortho( 0, 900, 900, 0, -0.5f, 0.5f );
		Matrix4x4 m2 = transform.localToWorldMatrix;
		Matrix4x4 m3 = m2 * m1;
		live2DModel.setMatrix( m3 );
		
		//経過時間で顔の角度Xを動かす
		float time = UtSystem.getUserTimeMSec() / 1000f;
		live2DModel.setParamFloat( "PARAM_ANGLE_X", 30 * Mathf.Sin( time ), 1);
		
		//頂点の更新
		live2DModel.update();
		
		//モデルの描画
		live2DModel.draw();
	}
}


3. 描画方法を変更する

DrawMeshNow を使うデフォルトの描画モードから、DrawMesh を使う描画モードに変更する

3.1 試しに3DText を生成
 Positionを(0, 0, -5)とする
 色を赤色にする

3.2 main.cs を編集

using UnityEngine;
using System.Collections;
using live2d; //Live2Dライブラリを使用

public class main : MonoBehaviour {
	
	public TextAsset mocFile;
	public Texture2D texture;
	private Live2DModelUnity live2DModel; //Live2Dモデルのインスタンス
	
	void Start ()
	{
		//初期化(Live2Dを使用する前に必ず1度だけ呼び出す)
		Live2D.init();
		//モデルデータを読み込む
		live2DModel = Live2DModelUnity.loadModel ( mocFile.bytes );
		//テクスチャの関連付け
		live2DModel.setTexture( 0, texture );

		//描画モードを指定
		live2DModel.setRenderMode( Live2D.L2D_RENDER_DRAW_MESH );
	}

	// DrawMesh で描画の場合は Update で描画できる
	void Update ()
	{
		//表示位置と大きさの指定
		Matrix4x4 m1 = Matrix4x4.Ortho( 0, 900, 900, 0, -0.5f, 0.5f );
		Matrix4x4 m2 = transform.localToWorldMatrix;
		Matrix4x4 m3 = m2 * m1;
		live2DModel.setMatrix( m3 );
		
		//経過時間で顔の角度Xを動かす
		float time = UtSystem.getUserTimeMSec() / 1000f;
		live2DModel.setParamFloat("PARAM_ANGLE_X", 30 * Mathf.Sin( time ), 1);
		
		//頂点の更新
		live2DModel.update();
		
		//モデルの描画
		live2DModel.draw();
	}
}


3.3 カメラの設定を変更
 「Projection」を「Perspective」→「Orthographic」に変更



4. モーションと音声を再生

4.1 音声ファイル(hajimetenooto.mp3)の設定

 音声ファイルは、3D Sound のチェックを外して「Apply」

4.2 音声を GameObject にドラッグ&ドロップ
 Play On Awake を 「False」にしておく
 Loop を「True」にしておく

4.2 main.cs を編集

using UnityEngine;
using System.Collections;
using live2d; //Live2Dライブラリを使用

public class main : MonoBehaviour {
	
	public TextAsset mocFile; // mocファイル
	public Texture2D texture; // テクスチャファイル
	public TextAsset[] mtnFiles; // mtnファイル
	
	private Live2DModelUnity 	live2DModel; // Live2Dモデルクラス
	private Live2DMotion 		motion; // Live2Dモーションクラス
	private MotionQueueManager 	motionManager; // モーション管理クラス
	
	void Start ()
	{
		// 初期化(Live2Dを使用する前に必ず1度だけ呼び出す)
		Live2D.init();
		// Live2Dモデルクラスのインスタンスの作成(mocの読み込み)
		live2DModel = Live2DModelUnity.loadModel ( mocFile.bytes );
		// テクスチャの関連付け
		live2DModel.setTexture( 0, texture );
		
		// 描画モードを指定
		live2DModel.setRenderMode( Live2D.L2D_RENDER_DRAW_MESH );
		
		// モーションのインスタンスの作成(mtnの読み込み)と設定
		motion = Live2DMotion.loadMotion( mtnFiles[ 0 ].bytes );
		motion.setLoop( true );
		
		// モーション管理クラスのインスタンスの作成
		motionManager = new MotionQueueManager();
		// モーションの再生
		motionManager.startMotion( motion, false );
		
		// 音声の再生
		GetComponent<AudioSource>().Play();
	}
	
	// DrawMesh で描画の場合は Update で描画する
	void Update ()
	{
		// 表示位置と大きさの指定
		Matrix4x4 m1 = Matrix4x4.Ortho( 0, 900, 900, 0, -0.5f, 0.5f );
		Matrix4x4 m2 = transform.localToWorldMatrix;
		Matrix4x4 m3 = m2 * m1;
		live2DModel.setMatrix( m3 );
		
		// 再生中のモーションからモデルパラメータを更新
		motionManager.updateParam( live2DModel );
		
		// 頂点の更新
		live2DModel.update();
		
		// モデルの描画
		live2DModel.draw();
	}
}

4.3 mtnファイルを mtnFiles にドラッグ&ドロップ


5. モーションを再生した上で他のパラメータを加算する

5.1 main.cs を編集

using UnityEngine;
using System.Collections;
using live2d; //Live2Dライブラリを使用

public class main : MonoBehaviour {
	
	public TextAsset mocFile; // mocファイル
	public Texture2D texture; // テクスチャファイル
	public TextAsset[] mtnFiles; // mtnファイル
	
	private Live2DModelUnity 	live2DModel; // Live2Dモデルクラス
	private Live2DMotion 		motion; // Live2Dモーションクラス
	private MotionQueueManager 	motionManager; // モーション管理クラス
	
	void Start ()
	{
		// 初期化(Live2Dを使用する前に必ず1度だけ呼び出す)
		Live2D.init();
		// Live2Dモデルクラスのインスタンスの作成(mocの読み込み)
		live2DModel = Live2DModelUnity.loadModel ( mocFile.bytes );
		// テクスチャの関連付け
		live2DModel.setTexture( 0, texture );
		
		// 描画モードを指定
		live2DModel.setRenderMode( Live2D.L2D_RENDER_DRAW_MESH );
		
		// モーションのインスタンスの作成(mtnの読み込み)と設定
		motion = Live2DMotion.loadMotion( mtnFiles[ 0 ].bytes );
		motion.setLoop( true );
		
		// モーション管理クラスのインスタンスの作成
		motionManager = new MotionQueueManager();
		// モーションの再生
		motionManager.startMotion( motion, false );
		
		// 音声の再生
		GetComponent<AudioSource>().Play();
	}

	// DrawMesh で描画の場合は Update で描画する
	void Update ()
	{
		// 表示位置と大きさの指定
		Matrix4x4 m1 = Matrix4x4.Ortho( 0, 900, 900, 0, -0.5f, 0.5f );
		Matrix4x4 m2 = transform.localToWorldMatrix;
		Matrix4x4 m3 = m2 * m1;
		live2DModel.setMatrix( m3 );

		// 再生中のモーションからモデルパラメータを更新
		motionManager.updateParam( live2DModel );

		// マウスの座標で顔の角度XYを動かす(加算)
		float targetX = 2 * Input.mousePosition.x / Screen.width - 1 ;
		float targetY = 2 * Input.mousePosition.y / Screen.height - 1 ;
		live2DModel.addToParamFloat ( "PARAM_ANGLE_X", 30 * targetX, 1 );
		live2DModel.addToParamFloat ( "PARAM_ANGLE_Y", 30 * targetY, 1 );
		
		// 頂点の更新
		live2DModel.update();
		
		// モデルの描画
		live2DModel.draw();
	}
}

ドラッグによって顔を向ける処理についてはフレームワークの L2DTargetPoint クラスを使うと便利です
http://sites.cybernoids.jp/cubism/sdk_tutorial/framework/drag


6. キー入力で別のモーションを再生する

6.1 main.cs を編集

using UnityEngine;
using System.Collections;
using live2d; //Live2Dライブラリを使用

public class main : MonoBehaviour {
	
	public TextAsset mocFile; // mocファイル
	public Texture2D texture; // テクスチャファイル
	public TextAsset[] mtnFiles; // mtnファイル
	
	private Live2DModelUnity 	live2DModel; // Live2Dモデルクラス
	private Live2DMotion 		motion; // Live2Dモーションクラス
	private MotionQueueManager 	motionManager; // モーション管理クラス
	private MotionQueueManager 	motionManager2; // モーション管理クラス
	
	void Start ()
	{
		// 初期化(Live2Dを使用する前に必ず1度だけ呼び出す)
		Live2D.init();
		// Live2Dモデルクラスのインスタンスの作成(mocの読み込み)
		live2DModel = Live2DModelUnity.loadModel ( mocFile.bytes );
		// テクスチャの関連付け
		live2DModel.setTexture( 0, texture );
		
		// 描画モードを指定
		live2DModel.setRenderMode( Live2D.L2D_RENDER_DRAW_MESH );
		
		// モーションのインスタンスの作成(mtnの読み込み)と設定
		motion = Live2DMotion.loadMotion( mtnFiles[ 0 ].bytes );
		motion.setLoop( true );
		
		// モーション管理クラスのインスタンスの作成
		motionManager = new MotionQueueManager();
		motionManager2 = new MotionQueueManager();
		// モーションの再生
		motionManager.startMotion( motion, false );
		
		// 音声の再生
		GetComponent<AudioSource>().Play();
	}
	
	// DrawMesh で描画の場合は Update で描画する
	void Update ()
	{
		// 表示位置と大きさの指定
		Matrix4x4 m1 = Matrix4x4.Ortho( 0, 900, 900, 0, -0.5f, 0.5f );
		Matrix4x4 m2 = transform.localToWorldMatrix;
		Matrix4x4 m3 = m2 * m1;
		live2DModel.setMatrix( m3 );
		
		// キー入力でモーションを再生
		// Fire1 : マウス左クリック or 左Ctrlキー or ジョイスティックボタン 0
		if( Input.GetButtonDown( "Fire1" ) ){
			motion = Live2DMotion.loadMotion( mtnFiles[ 0 ].bytes );
			motion.setLoop ( true );
			motionManager.startMotion( motion, false );
			GetComponent<AudioSource>().Play();
		}
		// Fire2 : マウス右クリック or 左Altキー or ジョイスティックボタン 1
		if( Input.GetButtonDown( "Fire2" ) ){
			motion = Live2DMotion.loadMotion( mtnFiles[ 1 ].bytes );
			motionManager2.startMotion( motion, false );
		}
		
		// 再生中のモーションからモデルパラメータを更新
		motionManager.updateParam( live2DModel );
		motionManager2.updateParam( live2DModel );
		
		// 頂点の更新
		live2DModel.update();
		
		// モデルの描画
		live2DModel.draw();
	}
}



7. ゲームコントローラを使ってパラメータを制御する

7.1 main.cs を編集
 Input の名称(Horizontal や Fire 1 など)はデフォルトのものを使用

using UnityEngine;
using System.Collections;
using live2d; //Live2Dライブラリを使用

public class main : MonoBehaviour {
	
	public TextAsset mocFile; // mocファイル
	public Texture2D texture; // テクスチャファイル
	public TextAsset[] mtnFiles; // mtnファイル
	
	private Live2DModelUnity 	live2DModel; // Live2Dモデルクラス
	private Live2DMotion 		motion; // Live2Dモーションクラス
	private MotionQueueManager 	motionManager; // モーション管理クラス
	private MotionQueueManager 	motionManager2; // モーション管理クラス
	
	void Start ()
	{
		// 初期化(Live2Dを使用する前に必ず1度だけ呼び出す)
		Live2D.init();
		// Live2Dモデルクラスのインスタンスの作成(mocの読み込み)
		live2DModel = Live2DModelUnity.loadModel ( mocFile.bytes );
		// テクスチャの関連付け
		live2DModel.setTexture( 0, texture );
		
		// 描画モードを指定
		live2DModel.setRenderMode( Live2D.L2D_RENDER_DRAW_MESH );
		
		// モーションのインスタンスの作成(mtnの読み込み)と設定
		motion = Live2DMotion.loadMotion( mtnFiles[ 0 ].bytes );
		motion.setLoop( true );
		
		// モーション管理クラスのインスタンスの作成
		motionManager = new MotionQueueManager();
		motionManager2 = new MotionQueueManager();
		// モーションの再生
		motionManager.startMotion( motion, false );
		
		// 音声の再生
		GetComponent<AudioSource>().Play();
	}
	
	// DrawMesh で描画の場合は Update で描画する
	void Update ()
	{
		// 表示位置と大きさの指定
		Matrix4x4 m1 = Matrix4x4.Ortho( 0, 900, 900, 0, -0.5f, 0.5f );
		Matrix4x4 m2 = transform.localToWorldMatrix;
		Matrix4x4 m3 = m2 * m1;
		live2DModel.setMatrix( m3 );
		
		// キー入力でモーションを再生
		// Fire1 : マウス左クリック or 左Ctrlキー or ジョイスティックボタン 0
		if( Input.GetButtonDown( "Fire1" ) ){
			motion = Live2DMotion.loadMotion( mtnFiles[ 0 ].bytes );
			motion.setLoop ( true );
			motionManager.startMotion( motion, false );
			GetComponent<AudioSource>().Play();
		}
		// Fire2 : マウス右クリック or 左Altキー or ジョイスティックボタン 1
		if( Input.GetButtonDown( "Fire2" ) ){
			motion = Live2DMotion.loadMotion( mtnFiles[ 1 ].bytes );
			motionManager2.startMotion( motion, false );
		}
		// Fire3 : マウス中クリック or 左cmdキー(Windowsキー) or ジョイスティックボタン 2
		if( Input.GetButtonDown( "Fire3" ) ){
			motion = Live2DMotion.loadMotion( mtnFiles[ 2 ].bytes );
			motionManager2.startMotion( motion, false );
		}
		// Jump : スペースキー or ジョイスティックボタン 3
		if( Input.GetButtonDown( "Jump" ) ){
			motion = Live2DMotion.loadMotion( mtnFiles[ 3 ].bytes );
			motionManager2.startMotion( motion, false );
		}
		
		// 再生中のモーションからモデルパラメータを更新
		motionManager.updateParam( live2DModel );
		motionManager2.updateParam( live2DModel );

		// Rトリガー・Lトリガーで目の開閉(Input設定変更が必要)
		float axis_3 = Input.GetAxis( "Mouse ScrollWheel" ) * 10;
		live2DModel.addToParamFloat( "PARAM_EYE_L_OPEN", axis_3, 1 );
		live2DModel.addToParamFloat( "PARAM_EYE_R_OPEN", axis_3, 1 );
		
		// ゲームコントローラで顔を動かす(加算)
		float targetX = Input.GetAxis( "Horizontal" );
		float targetY = Input.GetAxis( "Vertical" ) ;
		live2DModel.addToParamFloat( "PARAM_ANGLE_X", 30 * targetX, 1 );
		live2DModel.addToParamFloat( "PARAM_ANGLE_Y", 30 * targetY, 1 );
		live2DModel.addToParamFloat( "PARAM_ANGLE_Z", 10 * targetX, 1 );
		live2DModel.addToParamFloat( "PARAM_BODY_ANGLE_X", 3 * targetX, 1 );
		live2DModel.addToParamFloat( "PARAM_BODY_ANGLE_Y", 3 * targetY, 1 );

		// 頂点の更新
		live2DModel.update();
		
		// モデルの描画
		live2DModel.draw();
	}
}


7.2 Input 設定の変更
 「Edit」メニュー→「Project Settings」→「Input」をクリックする
 「Mouse ScrollWheel」の「Type」を、「Mouse Movement」から「Joystick Axis」に変更する


Comments