はじめに
こんにちは。
やっと普通の記事を書くことができてうれしいですね(?)
ということで今回は、Unityに「Live2D Cubism SDK for Unity」を入れて「おもしろい!」って思うことが目標のなんとも変な記事になっています(?)
- Unityを使ったことがある
かつ
- Live2Dって何?
- 面白そうだけど難しそう…
- Live2Dという言葉を聞いたことがある
という方向けになっています。
- 既にLive2D Cubism SDK for Unityを使ったことがある
- 詳しい使い方を知りたい
という方には向いていない内容です。では早速やっていきましょう!
使用した環境
- Windows 11(25H2)
- Unity Hub & Unity Editor(6000.3.11f1)
- Live2D Cubism SDK(Cubism 5 SDK for Unity R5)
今回は「入力システムパッケージ(Input System)」を使用しています。
「入力マネージャー(Input Manager)」を使用している場合は、プロジェクトの設定で変更してください。
そもそも「Live2D」とは?
「Live2D」は平面の絵をまるで立体のように動かせるという、とても面白い技術ですね。
最近よく目にする「VTuber」と呼ばれている方々は、この技術を使って元になるイラストを動かしてる感じになってます。他にもゲームで使われていたりするので、知っておいて損はない技術かなって思います。
準備
1.下記URLから「Live2D Cubism SDK for Unity」をダウンロード
2.Unityのプロジェクトを開いて、「Live2D Cubism SDK for Unity」をドラッグ&ドロップする
試すだけなら2Dのシーンにした方がいいです。
(今回の記事では2Dで進めていきます。)
3.すべてインポートする
これで終了です(めっちゃ簡単ですね)
動かしてみよう
ということで実際に動かしてみましょう!
1.マウスカーソルに合わせて動かす
最初は一旦マウスカーソルに合わせて動くようなプログラムを入れてみましょう。
ます、シーン上にAssets/Live2D/Cubism/Samples/Models/Maoの中にある「Mao」と書いてあるプレハブをシーンに入れてみましょう!
その後ちっちゃいと思うので、一旦スケールを均等に「10」にしておきましょう。
こちらサンプルとして入っている「虹色まお」というキャラクターになってます。
(↓詳しく知りたい人はこちら↓)
さすがに公式が配布してるだけあっていろいろと品質が高く、学習にはもってこいって感じのキャラになっているので、今回はこのキャラクターを使って説明していきます。
では、次に早速動かしてみましょう!
「MouseMotion」というスクリプトを新規作成して、以下のコードをコピペしましょう。
「入力システムパッケージ(Input Sysytem)」を使用しています。
using Live2D.Cubism.Core;
using UnityEngine;
using UnityEngine.InputSystem;
public class MouseMotion : MonoBehaviour
{
// 現在の追従位置を記憶する変数(Lerpに使う)
private float _currentX;
private float _currentY;
private CubismModel _model;
void Start()
{
// このGameObjectにアタッチされているLive2Dモデルを取得
_model = GetComponent<CubismModel>();
}
//キャラをUpdateで制御するときは「LateUpdate」で制御しないといけない
void LateUpdate()
{
// マウスのスクリーン座標を取得(New Input System版)
Vector2 mousePos = Mouse.current.position.ReadValue();
// スクリーン座標を -1.0 〜 +1.0 の範囲に正規化
// 画面左端→-1、中央→0、右端→+1 になる
float targetX = (mousePos.x / Screen.width - 0.5f) * 2f;
float targetY = (mousePos.y / Screen.height - 0.5f) * 2f;
// Lerpで目標値に滑らかに近づける(5f = 追従速度)
_currentX = Mathf.Lerp(_currentX, targetX, Time.deltaTime * 5f);
_currentY = Mathf.Lerp(_currentY, targetY, Time.deltaTime * 5f);
// 目の動き(eyeball = 黒目の位置)
_model.Parameters.FindById("ParamEyeBallX").Value = _currentX;
_model.Parameters.FindById("ParamEyeBallY").Value = _currentY;
// 顔の角度(×30で-30°〜+30°の範囲に拡大)
_model.Parameters.FindById("ParamAngleX").Value = _currentX * 30f;
_model.Parameters.FindById("ParamAngleY").Value = _currentY * 30f;
// 顔のZ回転(首傾け)。Xと逆方向にかけることで自然な動きに
_model.Parameters.FindById("ParamAngleZ").Value = _currentX * -10f;
// 体の傾き(顔より小さい値で控えめに動かす)
_model.Parameters.FindById("ParamBodyAngleX").Value = _currentX * 10f;
_model.Parameters.FindById("ParamBodyAngleY").Value = _currentY * 10f;
// 呼吸アニメーション
// Sinは-1〜+1なので、+1して/2することで 0〜1 の範囲に変換
_model.Parameters.FindById("ParamBreath").Value = (Mathf.Sin(Time.time * 1.5f) + 1f) / 2f;
}
}
これを早速さっきのプレハブに入れて、キャラの位置もいい感じの位置に調整してから実行してみましょう!
詳しいコードの説明は省きます(というかコメントに書いてある通りです)が、ここにもすごいポイントが隠されています!
例えば、顔の角度を変えている部分に注目してみましょう。
// 顔の角度(×30で-30°〜+30°の範囲に拡大)
_model.Parameters.FindById("ParamAngleX").Value = _currentX * 30f;
_model.Parameters.FindById("ParamAngleY").Value = _currentY * 30f;
// 顔のZ回転(首傾け)。Xと逆方向にかけることで自然な動きに
_model.Parameters.FindById("ParamAngleZ").Value = _currentX * -10f;
モデルによっても変わってくるとは思いますが、これだけで動きを制御できるのはすごいと思っています。
というように、Live2Dの最大のメリットとして制御が簡単なんですよね。
モデルだけしっかり作ってもらえれば、すごい感じの動きが簡単に実装できちゃうのでいいんですよね。
2.瞬きをつける
これもすごく簡単に制御できちゃいます。
「EyeControl」というスクリプトを作成後、以下のコードをコピペしてまたプレハブに入れてみましょう!
using UnityEngine;
using UnityEngine.InputSystem;
using Live2D.Cubism.Core;
public class EyeControl : MonoBehaviour
{
private float _blinkSpeed = 8f;
private bool _isBlinking;
private CubismModel _model;
void Start()
{
_model = GetComponent<CubismModel>();
}
void LateUpdate()
{
// スペースキーが押されたら瞬きを開始
if (Keyboard.current.spaceKey.wasPressedThisFrame)
{
_isBlinking = true;
}
if (_isBlinking)
{
// 目を閉じる
float eyeOpen = _model.Parameters.FindById("ParamEyeLOpen").Value;
eyeOpen -= Time.deltaTime * _blinkSpeed;
if (eyeOpen <= 0f)
{
eyeOpen = 0f;
_isBlinking = false;
}
_model.Parameters.FindById("ParamEyeLOpen").Value = eyeOpen;
_model.Parameters.FindById("ParamEyeROpen").Value = eyeOpen;
}
else
{
// 目を開く
float eyeOpen = _model.Parameters.FindById("ParamEyeLOpen").Value;
eyeOpen = Mathf.MoveTowards(eyeOpen, 1f, Time.deltaTime * _blinkSpeed);
_model.Parameters.FindById("ParamEyeLOpen").Value = eyeOpen;
_model.Parameters.FindById("ParamEyeROpen").Value = eyeOpen;
}
}
}
実行してspaceを押してみましょう!
仕組みも単純で、目の開閉度を調整しているだけですね。
ちょっとした注意点
このスクリプトには注意があって、まず虹色まおのドキュメントにもあるとおり「開閉のパラメーターが0では完璧に閉じない」そうなので、目が完全に閉じません!
しかもパラメーター操作で0より小さい値に設定できない仕様となっているので、どうしようっていう感じですよねw
一応自分は
if (eyeOpen <= 0f)
{
eyeOpen = -0.2f;//ここを0f→-0.2fに変更
_isBlinking = false;
}
ここのif文をこんな感じに変えてみました。
(効果あるかは何とも言えませんが一応完璧に目は閉じてくれると思います。めっちゃ気になるならこうした方がいいよとだけ言っておきます。)
3.アニメーション(モーション)の再生
これがメインといっていいと思いますが、ここまでやってきたのと同じで何も難しいことはありません。
まずは前提として「CubismMotionController」というコンポーネントが必要です。
その後、「AnimationTest」というスクリプトを作成して以下のコードをコピペしましょう。
using Live2D.Cubism.Framework.Motion;
using UnityEngine;
using UnityEngine.InputSystem;
public class AnimationTest : MonoBehaviour
{
private CubismMotionController _motionController;
//アニメーションクリップを入れるための変数(後でインスペクターからアタッチしないと動作しません)
[SerializeField] private AnimationClip _motionClip;
void Start()
{
//CubismMotionControllerコンポーネントを取得
_motionController = GetComponent<CubismMotionController>();
}
void Update()
{
if (Keyboard.current.aKey.wasPressedThisFrame)
{
//アニメーション再生
_motionController.PlayAnimation(_motionClip, isLoop: false);
}
}
}
その後、プレハブに入れて、アニメーションをアタッチしましょう!
アニメーションもテンプレートがいくつか用意されていて、Assets/Live2D/Cubism/Samples/Models/Mao/motionsにあるアニメーション(モーション)のどれか一つをAnimationTestのMotion Clipにアタッチしましょう!
実行したあとキーボードのAを押すと、そのアニメーションが再生されると思います!
最後に
かなり雑な説明になってしまいましたが、基本はこんな感じで結構簡単に制御ができます!
結構コメント残したはずなので、大体何してるかくらいはわかってくれるかなと思っていますが、今後丁寧に説明したバージョンを出そうかはちょっと考えてます。
興味があればもっと詳しいことを学んでみましょう!
以上です!
本作品のキャラクターには株式会社Live2Dの著作物であるサンプルデータが株式会社Live2Dの定める規約に従って用いられています。本作品は制作者の完全な自己の裁量で制作されています。




