Execute code after the animator update but before constraints are applied

For foot IK you’re supposed to raycast to the current foot position and adjust the IK target/weight accordingly. Tried using LateUpdate, but constraints are applied before the LateUpdate. What to do?

1 Like

Hey,

What about Update? Or OnAnimatorIK?

Thanks for the reply! Update happens before the Animator is updated. OnAnimatorIK only works with humanoid rigs, my rig is generic, also i doubt it would work anyway.

Each rig referenced in your rig builder is added as an AnimationPlayableOutput to your Animator. To change the order you can use the following extension method: Unity - Scripting API: Experimental.Animations.AnimationPlayableOutputExtensions.SetSortingOrder(AnimationPlayableOutput,int)

The order is not guaranteed otherwise like explained in the following thread:

"Yes, the PlayableGraph created for Animation Rigging has several outputs, this is no bug. The first output handles the SyncSceneToStream playable chain which synchronizes scene values to make them available to the Animation Rigging jobs. Afterwards, the other outputs handle the multiple Rigs set on your RigBuilder. The Animation Rigging outputs are set to use the previous input evaluation values so that they behave as a post process step to what was evaluated before (see https://docs.unity3d.com/ScriptRefe…utputExtensions.SetAnimationStreamSource.html)
We created a separate PlayableGraph in order for Animation Rigging to play nice with other animation systems. This way, we can use Animation Rigging with the Animator state machine or Timeline or your custom PlayableGraph.
However, in 2019.2, we are missing a proper sorting order to better control when a PlayableGraph is evaluated in the Animator. While the Animator state machine always has priority on all other animation systems, we’re not guaranteed that the Timeline PlayableGraph will be built before the AnimationRigging graph and thus in the right evaluation order.
We’re fixing that in 2019.3 by adding a sorting order to AnimationPlayableOutput (see https://docs.unity3d.com/2019.3/Doc…PlayableOutputExtensions.SetSortingOrder.html).
In the meantime, to ensure your PlayableGraph are evaluated in the right order, make sure to also create them in the same order. By controlling when RigBuilder becomes enabled, you will also control when its PlayableGraph will be built, and thus change the evaluation order."

1 Like

I had the same issue today, came up with a crude solution, by attaching the below script (tweaked from an example - 99% of the code is superfluous) as a child of an ‘information’ rig. It’s constrained object needs to be a child of the root (I used an empty gameobject); the position of this constrained gameobject in Update is the animated position of the source object before IK in the previous frame - which is near enough for a decent raycast unless you’re animating Road Runner. That’s provided the rig is at the top of the stack in the rig builder, and whilst I’ve found it works I’ve not extensively tested it.

This is an extremely convoluted way of getting at a simple Vector3, but in lieu of a sorely needed convenience method, or any real knowledge of the API, it’s the only option I could find in the short time I had.

It would help if the examples/docs had 1 good example of procedural target placement (foot IK being the best candidate). The vast majority of the documentation is on setting up and manipulating joints in the editor, rather than a worked-through use case. I get that it’s meant to be a generic system and it’s down to the developer/artist how the targets place themselves, but just one worked example that doesn’t involve dragging an editor marker around would be extremely useful.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Animations.Rigging;
using UnityEngine.Experimental.Animations;
using Unity.Burst;
using Unity.Mathematics;
using UnityEngine.Animations;

[BurstCompile]
public struct AnimationInfoBinderJob : IWeightedAnimationJob
{
    public ReadWriteTransformHandle constrained;
    public ReadOnlyTransformHandle source;
  

    public FloatProperty jobWeight { get; set; }

    public void ProcessRootMotion(AnimationStream stream) { }

    public void ProcessAnimation(AnimationStream stream)
    {
        float w = jobWeight.Get(stream);
        if (w > 0f)
        {
            constrained.SetPosition(
                stream,
                source.GetPosition(stream))
                ;
        }
    }


}

[System.Serializable]
public struct AnimationInfoBinderData : IAnimationJobData
{
    public Transform constrainedObject;
    [SyncSceneToStream] public Transform sourceObject;

    public bool IsValid()
    {
        return !(constrainedObject == null || sourceObject == null);
    }

    public void SetDefaultValues()
    {
        constrainedObject = null;
        sourceObject = null;
    }
}

public class AnimationInfoBinderBinder : AnimationJobBinder<AnimationInfoBinderJob, AnimationInfoBinderData>
{
    public override AnimationInfoBinderJob Create(Animator animator, ref AnimationInfoBinderData data, Component component)
    {
        return new AnimationInfoBinderJob()
        {
            constrained = ReadWriteTransformHandle.Bind(animator, data.constrainedObject),
            source = ReadOnlyTransformHandle.Bind(animator, data.sourceObject)
        };
    }

    public override void Destroy(AnimationInfoBinderJob job) { }
}


public class AnimationInfoBinder : RigConstraint<
    AnimationInfoBinderJob,
    AnimationInfoBinderData,
    AnimationInfoBinderBinder
    >
{
}

Yeah, figured that as well after the fact. Ive tried making my own playable behaviour but i couldnt manage to make it execute after the animator updated, even with that order thing. I assume its somehow related to that syncSceneToStream thing. Also according to the profiler, animator processing and animation rigging processing happens in parallel, so there is no actual inbetween step as is, as far as i can tell.

Tried that as well, didnt work well for me. Anyway, for my solution i ditched the animation rigging altogether, ported the IK part of it (since thats the only thing i need from it really) as a regular main-thread code, and just used that in late update. The whole job/multithreading thing imo is extremely limiting and not necessary in 90% of cases anyway, most games are GPU bound nowadays.

Yeah the animation rigging constraint are added to the animator so they are definitely processed at the same time when the animation graph is evaluated. The order thing would be the solution for that if it worked…

If I look at the events execution list there:

Maybe you could have use the FixedUpdate? Also I have tried changing the Update Mode of the Animator?

Glad you figured out a solution though!

Hey, sorry to revive this thread, but are there any better solutions to this problem yet?

I’d like to get the position of a bone in an animation before Animation Rigging modifies it.

Alternatively, I’d just like to stop the player’s feet from going through the floor. I’d like to take the current foot position, and if it’s underneath the raycast position, set a two-bone constraint weight to 1 to stop it from going through.

However, once the leg is underground, and the weight is 1, I can no longer poll for the original foot position.

Hey everyone, I think I found the solution:

Check out ExtractTransformConstraint from this thread:

1 Like

I have been working with the Animation Rigging package for a week now and am coming to the same conclusion as Customphase. I love the idea of Animation Rigging but think I need to ditch it as there are some serious shortcomings. The main problems:

  • The rig constraints execute off the main thread and it is impossible to do Raycasts or interact with other Unity systems (ReadWrite to Transforms) from inside the executing rig constraint code.
  • I cannot find a way to manually step/pose the animator and have the RigConstraints execute immediately. I can get the animator to pose immediately but the playable graph doesn’t evaluate in this case. It is too awkward to try to do all the raycasting in the Update/FixedUpdate loop then store the results and use them in a custom rig constraint.
  • The playableGraph executers outside Update/FixedUpdate loop which is awkward to work with.
  • It is difficult to have code that executers before or after a particular rig constraint execution. This seems to require create custom constraints which is a lot of work and configuring for what is essentially a callback.

Will try Customphase approach and implement something similar that works on the main thread.

1 Like

Just wanted to add that the option to force the rigging/constraints to evaluate would be great. I need manual control of when physics scenes update and have rigged animation that needs to update between each physics step. Currently, there seems to be no good way of doing this.