Cubism 製品のマニュアル・チュートリアルはこちら
 
Cubism Editorマニュアル    Cubism Editorチュートリアル    Cubism SDKマニュアル    Cubism SDKチュートリアル

ランタイム時にモーションをロードする方法お問い合わせ。

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を使用することができない状況では、コードだけで、実行時に使用する正しい方法を知っていると思います。

コメント

  • @Dennis さん

    Unityの仕様により、ランタイムで動的に生成したAnimationClipはPlayable APIやAnimatorで再生することはできません。
    Playable APIやAnimatorは、AnimationClip.legacyにFalseが設定されているもののみ再生させることができます。
    しかしAnimationClipをランタイムで生成した場合、必ずAnimationClip.legacyがTrueで生成されます。

    ランタイムで生成したAnimationClipを再生させるのであれば、UnityのAnimationコンポーネントを利用してください。
    ただし、Cubism SDK for UnityはAnimationコンポーネントでの再生にMotionFadeは対応しておりませんので、必要であればユーザ側で実装して頂く必要がございます。
コメントするにはサインインまたは登録して下さい。