★お知らせ(2023/12/27)
いつもLive2D公式コミュニティをご利用いただき誠にありがとうございます。
本コミュニティは2023年12月27日 11:00をもって閉鎖いたしました。
今後の運営はすべて新Live2D公式クリエイターズフォーラムに移行します。
閉鎖に伴い、以下機能は利用不可となります。
・アカウントの新規作成
・トピック投稿、返信
たくさんのご利用誠にありがとうございました。
新Live2D公式クリエイターズフォーラムは以下バナーよりご利用いただけます。
なお、本コミュニティに投稿されたトピックはすべて残りますが、今後削除する可能性がございますので予めご了承ください。
閉鎖に関するお問い合わせにつきましてはLive2D公式クリエイターズフォーラムへご連絡ください。
いつもLive2D公式コミュニティをご利用いただき誠にありがとうございます。
本コミュニティは2023年12月27日 11:00をもって閉鎖いたしました。
今後の運営はすべて新Live2D公式クリエイターズフォーラムに移行します。
閉鎖に伴い、以下機能は利用不可となります。
・アカウントの新規作成
・トピック投稿、返信
たくさんのご利用誠にありがとうございました。
新Live2D公式クリエイターズフォーラムは以下バナーよりご利用いただけます。
なお、本コミュニティに投稿されたトピックはすべて残りますが、今後削除する可能性がございますので予めご了承ください。
閉鎖に関するお問い合わせにつきましてはLive2D公式クリエイターズフォーラムへご連絡ください。
ランタイム時にモーションをロードする方法お問い合わせ。
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を使用することができない状況では、コードだけで、実行時に使用する正しい方法を知っていると思います。
0
コメント
Unityの仕様により、ランタイムで動的に生成したAnimationClipはPlayable APIやAnimatorで再生することはできません。
Playable APIやAnimatorは、AnimationClip.legacyにFalseが設定されているもののみ再生させることができます。
しかしAnimationClipをランタイムで生成した場合、必ずAnimationClip.legacyがTrueで生成されます。
ランタイムで生成したAnimationClipを再生させるのであれば、UnityのAnimationコンポーネントを利用してください。
ただし、Cubism SDK for UnityはAnimationコンポーネントでの再生にMotionFadeは対応しておりませんので、必要であればユーザ側で実装して頂く必要がございます。