新しいLive2D公式コミュニティ(日本向け)が公開されました!
ぜひご利用ください!
Live2D公式コミュニティ
■このコミュニティの今後について
このコミュニティ(forum.live2d.com)につきましては、しばらくの間新コミュニティと並行して運営しますが、2023年夏ごろを目処に方針を決定する予定です。
(2022/12/27追記 2022年内を目処に閉鎖 から変更しております)
内容については決定次第お知らせいたします。
海外向けコミュニティについては変更ございません。
ぜひご利用ください!
Live2D公式コミュニティ
■このコミュニティの今後について
このコミュニティ(forum.live2d.com)につきましては、しばらくの間新コミュニティと並行して運営しますが、2023年夏ごろを目処に方針を決定する予定です。
(2022/12/27追記 2022年内を目処に閉鎖 から変更しております)
内容については決定次第お知らせいたします。
海外向けコミュニティについては変更ございません。
Live2Dに関するユーザーのみなさま同士の交流・ご質問・不具合の報告・提案・要望などについて是非お寄せください。
※Live2D公式スタッフからの発言や回答については確約できないことを予めご了承ください。
Live2D ヘルプ
Cubism Editorダウンロード / 動作環境
Cubism SDKダウンロード / 対応表
Cubism 製品利用ライセンス(SDK含)
Cubism 製品のライセンスについてのお問い合わせはこちら
nizima 及び nizima 製品についてのお問い合わせはこちら
※Live2D公式スタッフからの発言や回答については確約できないことを予めご了承ください。
Live2D ヘルプ
Cubism Editorダウンロード / 動作環境
Cubism SDKダウンロード / 対応表
Cubism 製品利用ライセンス(SDK含)
Cubism 製品のライセンスについてのお問い合わせはこちら
nizima 及び nizima 製品についてのお問い合わせはこちら
【各最新OSの対応状況について】
Cubism Editorは 4.1.02 正式版以降でWindows 11 及び macOS Monterey に対応しております。ぜひ最新版をご利用ください。
※macOSをお使いの方でOSアップデートする際は必ずCubism Editorのライセンスを解除してください。
Cubism EditorをインストールしているmacOSをアップグレードしたい
Cubism SDKについては各SDKのREADMEまたはNOTICEをご確認ください。
【Mac各機種への対応状況について】
現在、Cubism EditorはApple M1チップ搭載機種には対応しておりません。
詳細は 動作環境 をご参照ください。
関連するお問い合わせへの対応はこの文章をもって代えさせていただきます。
Cubism Editorは 4.1.02 正式版以降でWindows 11 及び macOS Monterey に対応しております。ぜひ最新版をご利用ください。
※macOSをお使いの方でOSアップデートする際は必ずCubism Editorのライセンスを解除してください。
Cubism EditorをインストールしているmacOSをアップグレードしたい
Cubism SDKについては各SDKのREADMEまたはNOTICEをご確認ください。
【Mac各機種への対応状況について】
現在、Cubism EditorはApple M1チップ搭載機種には対応しておりません。
詳細は 動作環境 をご参照ください。
関連するお問い合わせへの対応はこの文章をもって代えさせていただきます。
ランタイム時にモーションをロードする方法お問い合わせ。
SDK version : Unity Cubism SDK 4-r.1
はじめまして。開発中の質問があってきました。
開発中のゲームにLive2Dを適用中です。モデルとモーションをサーバーからダウンロードして使用しているのでPrefabやユニティが提供する便利な機能を利用することができません。
model3.jsonとmotion3.jsonだけを持って、実行時に使用する方法を探しています。CubismFadeControllerとCubismMotionControllerに挑戦し成功したように見えます。しかし、モーションとモーションの間にFadeが正常に動作しない。モーションが自然に接続されず、前のモーションを強制的に終了し、新た始まるとみられる。
CubismFadeMotionListを実行時に作成する方法が間違ってないかと考えています。次のようなコードを使用して、挑戦しました。
======================================================================================================
public class InitModel : MonoBehaviour
{
private readonly string model3Path = Application.streamingAssetsPath + "/test.model3.json";
private readonly string motion3IdlePath = Application.streamingAssetsPath + "/idle.motion3.json";
private readonly string motion3AngryPath = Application.streamingAssetsPath + "/angry.motion3.json";
private CubismMotionController cubismMotionController;
private CubismFadeController cubismFadeController;
private AnimationClip[] animationClips;
void Start()
{
// Load Model
var model = CubismModel3Json.LoadAtPath(model3Path, BuiltinLoadAssetAtPath).ToModel();
// Load Motions
var motion3Jsons = new CubismMotion3Json[] {
CubismMotion3Json.LoadFrom(File.ReadAllText(motion3IdlePath)),
CubismMotion3Json.LoadFrom(File.ReadAllText(motion3AngryPath))
};
animationClips = new AnimationClip[] { motion3Jsons[0].ToAnimationClip(), motion3Jsons[1].ToAnimationClip() };
// Create FadeController, MotionController
cubismFadeController = model.gameObject.AddComponent();
var fadeMotions = ScriptableObject.CreateInstance();
fadeMotions.MotionInstanceIds = new int[2];
fadeMotions.CubismFadeMotionObjects = new CubismFadeMotionData[2];
for (int i = 0 ; i < 2 ; i++) {
var animationEvent = new AnimationEvent();
animationEvent.time = 0;
animationEvent.functionName = "InstanceId";
animationEvent.intParameter = animationClips[i].GetInstanceID();
animationEvent.messageOptions = SendMessageOptions.DontRequireReceiver;
animationClips[i].events = new AnimationEvent[] { animationEvent };
fadeMotions.MotionInstanceIds[i] = animationClips[i].GetInstanceID();
fadeMotions.CubismFadeMotionObjects[i] = CubismFadeMotionData.CreateInstance(motion3Jsons[i], animationClips[i].name, animationClips[i].length, false, true);
}
cubismFadeController.CubismFadeMotionList = fadeMotions;
cubismMotionController = model.gameObject.AddComponent();
}
public static object BuiltinLoadAssetAtPath(Type assetType, string absolutePath)
{
if (assetType == typeof(byte[]))
{
return File.ReadAllBytes(absolutePath);
}
else if(assetType == typeof(string))
{
return File.ReadAllText(absolutePath);
}
else if (assetType == typeof(Texture2D))
{
var texture = new Texture2D(1,1);
texture.LoadImage(File.ReadAllBytes(absolutePath));
return texture;
}
throw new NotSupportedException();
}
void OnGUI() {
if (GUI.Button(new Rect(10, 60, 120, 40), "Start Motion Idle"))
{
// Idle
cubismMotionController.PlayAnimation(animationClips[0], priority: CubismMotionPriority.PriorityForce);
}
if (GUI.Button(new Rect(10, 110, 120, 40), "Start Motion Angry"))
{
// Angry
cubismMotionController.PlayAnimation(animationClips[1], priority: CubismMotionPriority.PriorityForce);
}
}
}
======================================================================================================
モデルとモーションは正常にロードされたものと見なされます。しかし、IdleモーションとAngryモーションの間に自然に接続されていません。
Prefab、AssetBundleを使用することができない状況では、コードだけで、実行時に使用する正しい方法を知っていると思います。
はじめまして。開発中の質問があってきました。
開発中のゲームにLive2Dを適用中です。モデルとモーションをサーバーからダウンロードして使用しているのでPrefabやユニティが提供する便利な機能を利用することができません。
model3.jsonとmotion3.jsonだけを持って、実行時に使用する方法を探しています。CubismFadeControllerとCubismMotionControllerに挑戦し成功したように見えます。しかし、モーションとモーションの間にFadeが正常に動作しない。モーションが自然に接続されず、前のモーションを強制的に終了し、新た始まるとみられる。
CubismFadeMotionListを実行時に作成する方法が間違ってないかと考えています。次のようなコードを使用して、挑戦しました。
======================================================================================================
public class InitModel : MonoBehaviour
{
private readonly string model3Path = Application.streamingAssetsPath + "/test.model3.json";
private readonly string motion3IdlePath = Application.streamingAssetsPath + "/idle.motion3.json";
private readonly string motion3AngryPath = Application.streamingAssetsPath + "/angry.motion3.json";
private CubismMotionController cubismMotionController;
private CubismFadeController cubismFadeController;
private AnimationClip[] animationClips;
void Start()
{
// Load Model
var model = CubismModel3Json.LoadAtPath(model3Path, BuiltinLoadAssetAtPath).ToModel();
// Load Motions
var motion3Jsons = new CubismMotion3Json[] {
CubismMotion3Json.LoadFrom(File.ReadAllText(motion3IdlePath)),
CubismMotion3Json.LoadFrom(File.ReadAllText(motion3AngryPath))
};
animationClips = new AnimationClip[] { motion3Jsons[0].ToAnimationClip(), motion3Jsons[1].ToAnimationClip() };
// Create FadeController, MotionController
cubismFadeController = model.gameObject.AddComponent();
var fadeMotions = ScriptableObject.CreateInstance();
fadeMotions.MotionInstanceIds = new int[2];
fadeMotions.CubismFadeMotionObjects = new CubismFadeMotionData[2];
for (int i = 0 ; i < 2 ; i++) {
var animationEvent = new AnimationEvent();
animationEvent.time = 0;
animationEvent.functionName = "InstanceId";
animationEvent.intParameter = animationClips[i].GetInstanceID();
animationEvent.messageOptions = SendMessageOptions.DontRequireReceiver;
animationClips[i].events = new AnimationEvent[] { animationEvent };
fadeMotions.MotionInstanceIds[i] = animationClips[i].GetInstanceID();
fadeMotions.CubismFadeMotionObjects[i] = CubismFadeMotionData.CreateInstance(motion3Jsons[i], animationClips[i].name, animationClips[i].length, false, true);
}
cubismFadeController.CubismFadeMotionList = fadeMotions;
cubismMotionController = model.gameObject.AddComponent();
}
public static object BuiltinLoadAssetAtPath(Type assetType, string absolutePath)
{
if (assetType == typeof(byte[]))
{
return File.ReadAllBytes(absolutePath);
}
else if(assetType == typeof(string))
{
return File.ReadAllText(absolutePath);
}
else if (assetType == typeof(Texture2D))
{
var texture = new Texture2D(1,1);
texture.LoadImage(File.ReadAllBytes(absolutePath));
return texture;
}
throw new NotSupportedException();
}
void OnGUI() {
if (GUI.Button(new Rect(10, 60, 120, 40), "Start Motion Idle"))
{
// Idle
cubismMotionController.PlayAnimation(animationClips[0], priority: CubismMotionPriority.PriorityForce);
}
if (GUI.Button(new Rect(10, 110, 120, 40), "Start Motion Angry"))
{
// Angry
cubismMotionController.PlayAnimation(animationClips[1], priority: CubismMotionPriority.PriorityForce);
}
}
}
======================================================================================================
モデルとモーションは正常にロードされたものと見なされます。しかし、IdleモーションとAngryモーションの間に自然に接続されていません。
Prefab、AssetBundleを使用することができない状況では、コードだけで、実行時に使用する正しい方法を知っていると思います。
コメント
Unityの仕様により、ランタイムで動的に生成したAnimationClipはPlayable APIやAnimatorで再生することはできません。
Playable APIやAnimatorは、AnimationClip.legacyにFalseが設定されているもののみ再生させることができます。
しかしAnimationClipをランタイムで生成した場合、必ずAnimationClip.legacyがTrueで生成されます。
ランタイムで生成したAnimationClipを再生させるのであれば、UnityのAnimationコンポーネントを利用してください。
ただし、Cubism SDK for UnityはAnimationコンポーネントでの再生にMotionFadeは対応しておりませんので、必要であればユーザ側で実装して頂く必要がございます。