MotionMatching icon indicating copy to clipboard operation
MotionMatching copied to clipboard

issue with custom animation with custom rig

Open Shandy666 opened this issue 8 months ago • 9 comments

First of all, thanks for this awesome project, but when I attempt to use it, I face some errors.

Image

For both the character and the animation, I used the skeleton or rig that Daz3D provided. It looks like this

Image

Is there anything I have missed? Thanks in advance

Shandy666 avatar May 26 '25 01:05 Shandy666

You can try override ReadChannels method in BVHImporter.cs with this implementation:

/// <summary>
/// Reads the CHANNELS declaration of a BVH joint and stores the axis-order
/// information that will be needed later when converting raw values into
/// <see cref="Vector3"/> / <see cref="Quaternion"/>.
/// </summary>
/// <param name="channels">List where the detected <see cref="AxisOrder"/> are appended
///                        (translation first for the root, then rotation).</param>
/// <param name="words">The BVH file already tokenised into individual words.</param>
/// <param name="w">Current cursor index inside <paramref name="words"/> (passed by ref).</param>
/// <param name="root">
///     <c>true</c>  – this is the very first “ROOT” joint and therefore **must**
///                   contain both translation **and** rotation channels (6 total);<br/>
///     <c>false</c> – any other joint.  According to the original paper each of them
///                   should expose only 3 rotation channels, but Mixamo and some
///                   exporters add an *extra* set of XYZ-position channels (6 total).
/// </param>
/// <remarks>
/// The stock implementation assumed 3 rotation channels for every non-root joint
/// and threw an error otherwise.  This version gracefully handles 6-channel joints
/// by silently discarding the redundant position channels – Motion-Matching does
/// not use them anyway – which lets us import BVH files straight from Mixamo,
/// Rokoko Studio, etc., without preprocessing.
/// </remarks>
private void ReadChannels(List<AxisOrder> channels, string[] words, ref int w, bool root = false)
{
    // 1. “CHANNELS” keyword
    if (words[w++] != "CHANNELS")
    {
        Debug.LogError("[BVHImporter] CHANNELS keyword not found");
        return;
    }

    // 2. Channel count declared right after the keyword
    int numChannels = int.Parse(words[w++]);

    // ──────────────── TRANSLATION (root only) ────────────────
    if (root)
    {
        // The root **must** provide 3 translation + 3 rotation = 6 channels.
        if (numChannels != 6)
        {
            Debug.LogError("[BVHImporter] The root joint must have exactly 6 channels");
        }

        // Remember in which order the three position axes appear (XYZ / XZY …)
        channels.Add(ReadChannelPosition(words, ref w));
    }
    else
    {
        // Non-root joints may come with 3 **or** 6 channels depending on the exporter.
        // When 6, the first three are XYZ-position that we can safely ignore.
        if (numChannels == 6)
        {
            // Consume and discard the position axis order
            ReadChannelPosition(words, ref w);
        }
        else if (numChannels != 3)
        {
            Debug.LogError($"[BVHImporter] Unexpected channel count ({numChannels}) at joint – expected 3 or 6");
        }
        // If there are only 3 channels – nothing to skip, cursor is already after the count.
    }

    // ──────────────── ROTATION (always required) ────────────────
    channels.Add(ReadChannelRotation(words, ref w));
}

ilezhnin avatar May 26 '25 07:05 ilezhnin

Thank you for the code @ilezhnin ! I will integrate it into a future version of the package :)

@Shandy666 , take a look at the code provided by @ilezhnin , let's see if it solves your issue. Otherwise, if you attach a minimal .bvh to reproduce the error, I can take a look.

JLPM22 avatar May 26 '25 10:05 JLPM22

@ilezhnin, thanks for the help, the code works, but the animation has become weird

https://github.com/user-attachments/assets/53985b8c-0292-4e26-9924-7b73b535bc96

And @JLPM22, what kind of skeleton that this package actually support? I can recreate the animation with any type of skeleton using the Blender Retarget addon, by the way. And for the sake of enhancement of this tools, I will send you the BVH with the Daz3D Rig so you can make improvements for the future version.

acceleration.txt

Shandy666 avatar May 26 '25 10:05 Shandy666

@Shandy666 Thank you for the animation file! I took a quick look, and indeed, it looks weird. I will take a deeper look at a future version of the package. But for now, the skeleton I usually use is the one provided by Xsens, so if you could try to retarget to this:

tpose.txt

JLPM22 avatar May 26 '25 11:05 JLPM22

By the way, I have just uploaded a new version with @ilezhnin improvements!

JLPM22 avatar May 26 '25 11:05 JLPM22

thanks for the skeleton file, i will try to use it. and i looking forward for the further development. and by the way, i need you to clarify, are you using IK to Link the character into the generated animation? because i saw an invisible skeleton walking around if i turn the "Motion Matching Skinned Mesh Renderer" component off. if yes i would try to recreate it using Animation Rigging Package as it has "weight" control so I could smoothly mix it with the traditional animation because the character mechanic I'm working on is require full body movement for the combat. thanks in advance.

Shandy666 avatar May 26 '25 12:05 Shandy666

thanks for the skeleton file, i will try to use it. and i looking forward for the further development. and by the way, i need you to clarify, are you using IK to Link the character into the generated animation? because i saw an invisible skeleton walking around if i turn the "Motion Matching Skinned Mesh Renderer" component off. if yes i would try to recreate it using Animation Rigging Package as it has "weight" control so I could smoothly mix it with the traditional animation because the character mechanic I'm working on is require full body movement for the combat. thanks in advance.

That skeleton walking around is the generated pose by Motion Matching, which is later retargeted into the Unity Avatar by the MotionMatchingSkinnedMeshRenderer.

You can find the Transform hierarchy of this skeleton as children of the MotionMatchingController. Keep in mind that this skeleton is generated in the LateUpdate(). You can also subscribe to the event OnSkeletonTransformUpdated from the MotionMatchingController component, to get notified every frame when the skeleton is updated. Hope it helps!

JLPM22 avatar May 27 '25 09:05 JLPM22

@JLPM22 thanks for the information, i will keep it in mind. and by the way, i have tried to look at your animation from the sample, i saw it has 6 channels (position and rotation) in the first bone and 3 channels (Rotation) in the rest of bones. and my animation in other hand has 6 channels in each bone (maybe 9 including position, rotation, and scale) maybe that's why the tools is confused?

now in my case (or some people's case), in order to root motion work properly and smoothly, i used root bone in the button (pivot point of the character) so my point is, sometime child bone also need to have 6 channels (position and rotation) e.g hips bone. i hope we can figure out to handle this, thanks in advance.

Shandy666 avatar May 27 '25 16:05 Shandy666

and by the way, you ever said that the unity's Animator is restricted, well that's true. but hopefully this could be your way to enhance this tool

https://docs.unity3d.com/6000.1/Documentation/Manual/Playables.html

Shandy666 avatar May 27 '25 17:05 Shandy666