Howdy, Stranger!

It looks like you're new here. Sign in or register to get started.

If you have any questions, reports, suggestions, or requests about Live2D, please send them to this forum.
※We cannot guarantee statements or answers from Live2D staff. Thank you for your understanding in advance.
 
Live2D Cubism
Cubism Products and Downloads
Cubism product manuals and tutorials
Cubism Editor Manual    Cubism Editor Tutorial    Cubism SDK Manual    Cubism SDK Tutorial
[About macOS Sequoia] (Updated October 22, 2024)
Live2D Cubism Editor 5.1.02 now supports macOS Sequoia.
Other Live2D Cubism products currently released are not guaranteed to work on macOS Sequoia.
Please refrain from upgrading macOS, as it may not operate properly.

[Unity] Problems About Motion Priority & Fade

edited September 14 in Help
I must admit, Live2D SDKs is difficult to learn. No API documentation and so.
Now I'm stuck on very basic things, Playing Animation.

MotionController.PlayAnimation() consist of:
void CubismMotionController.PlayAnimation(AnimationClip clip, [int layerIndex = 0], [int priority = 2], [bool isLoop = true], [float speed = 1])
with **priority** parameter (default: **2**):
CubismMotionPriority.cs

public class CubismMotionPriority
{
    public const int PriorityNone = 0;
    public const int PriorityIdle = 1;
    public const int PriorityNormal = 2;
    public const int PriorityForce = 3;
}

So, I play a character login/intro motion:
CharacterViewer.cs
motionController.PlayAnimation(animations["login"], isLoop: false);

From the documentation, you need to subscribe to `AnimationEndHandler` event to make the next motion transition faded.

By using a callback that is called when motion playback ends, which exists in the CubismMotionController, the same motion can be played again from the callback to generate a fade and loop the motion.

https://docs.live2d.com/en/cubism-sdk-tutorials/loop-playback-with-fade-cubism/

I follow the tutorial and make a method to subscribe to:
CharacterViewer.cs
//...
motionController.AnimationEndHandler += OnLoginComplete;
//...

//...
private void OnLoginComplete(float instanceId)
{
    // This will play `idle` animation continously
    motionController.PlayAnimation(animations["idle"], priority: 1);
    motionController.AnimationEndHandler -= OnLoginComplete;
}
//...
Above codes work as expected. From `login` -> `idle` motion with fade transition.

On another hand, i perform a Raycast to the character. When I click a part with `Touch` component, it will play a specified animation. (NB: There's 3 parts with `Touch` component)
Touch.cs
//...
if (hitCount > 0 && results[0].Drawable.TryGetComponent(out Touch _)) // If the part found...
{
    // This will play Touch animation with janky transition, no fade
    CharacterViewer.MotionController.PlayAnimation(
        CharacterViewer.Animations["touch_body"],
        priority: 3,
        isLoop: false
    );
    CharacterViewer.MotionController.AnimationEndHandler += OnTouchComplete; // It doesn't subscribed to the handler whatsoever :v
}
//...

//...
void OnTouchComplete(float instanceId)
{
    Debug.Log("Back to Idle...");
    CharacterViewer.MotionController.PlayAnimation(
        CharacterViewer.Animations["idle"],
        priority: 3,
        isLoop: true
    );
    CharacterViewer.MotionController.AnimationEndHandler -= OnTouchComplete;
}
//...
The `Touch` animation will play because I used `Force` priority. Using `Normal` priority also work, but it's give me a log message: `can't start motion.`. There's no fade transition because the Idle animation is looped (AnimationEndHandler practically will not be called because the animation will not ended. CMIIW).
The method (`OnTouchComplete()`) I registered to the event isn't called. So, the character can't go back to the Idle animation. According to the docs:

CubismMotionController.AnimationEndHandler callback will not be called if isLoop in CubismMotionController.PlayAnimation() is passed true.

https://docs.live2d.com/en/cubism-sdk-tutorials/loop-playback-with-fade-cubism/

It's clear that I don't play `Touch` animation looped. So why, `OnTouchComplete()` isn't called?

Alternatively, if I wait until the current animation is done, also not working.
Touch.cs
//...
CharacterViewer.MotionController.PlayAnimation(
    CharacterViewer.Animations["touch_body"],
    priority: 2,
    isLoop: false
);
await UniTask.WaitUntil( // Equivalent to Task.WaitUntil in System.Threading.Tasks
    () => !CharacterViewer.MotionController.IsPlayingAnimation()
);
OnTouchComplete(0); // Execute with dummy argument
//...
Bruh, it's drives me nuts... If anyone can help me is much appreciated :smile:

Answers

Sign In or Register to comment.