Sync Animations on multiple objects

What is the best way to sync identical animations on two objects?. I have two buttons attached to a canvas – I set an animation controller up on each button with animations to slide the buttons on and off the screen based on the state of a parameter. Then - in a script - during the update I have something like the following:

Public Animator button1;
Public Animator button2

Void Update()
{

If( something happens)
{
Button1.setbool(“Parameter Name”, true);
Button2.setbool(“Parameter Name”, true);
}

Something Else happens
{
Button1.setbool(“Parameter Name”, false);
Button2.setbool(“Parameter Name”, false);
}

State machine and transitions for each controller then make everything move.

Here’s the effect I am trying to correct. The two animations are not synchronized. Sometimes buttons 1 & 2 move perfectly together – sometimes 1 ahead of 2 and some times 2 ahead of 3 – all very random.

What is the best technique for synchronizing identical animations on different objects (more than 2) so that everything moves ‘together’?

Appreciate any guidance – have tried searching for this but I am not sure if incorrect terminology is the reason I am not finding much.

1 Like

As an update found this post

which solved the issue. Parameters don’t seem to be the way to go - rather explicitly run the animation clips in the same update frame,

2 Likes

Hey! Thought I’d just pop in and give everyone a more in-depth solution. I was having a lot of troubles with this for some reason, but using the idea from that link managed to solve the issue. The issue I had was whenever I was trying to grab the AnimationStateInfo, it was either returning null or 0 (I’m sure I was missing something obvious that would’ve fixed this)

Anyways, like in that other post, the idea is to throw down an animator on your scene to act as the parent for all other animations that are instantiated after the scene has started.

protected Animator Animsync;
protected Animator Animation;

private void Awake()
{
    Animsync = GameObject.Find("Animsync").GetComponent<Animator>();
    Animation = GetComponent<Animator>();
}

private void Update()
{
    Animation.Play(0, -1, Animsync.GetCurrentAnimatorStateInfo(0).normalizedTime);
}

The idea is your find a master animator (I called it Animsync), get it’s animator state info, and then return the normalized time of that animation. From there, you just update your animation in an Update() event. (so you’d attached this C# script to every game object with an Animator component on it that you want to be synced)

Hopefully this helps you as I was stuck on this for the longest time!

6 Likes

Heres slightly modified version of the same approach, that supports sub-states syncing, as well as multiple layers with different weights:

    void Update()
    {
        for (int i = 0; i < toAnim.layerCount; i++)
        {
            toAnim.Play(fromAnim.GetCurrentAnimatorStateInfo(i).fullPathHash, i, fromAnim.GetCurrentAnimatorStateInfo(i).normalizedTime);
            toAnim.SetLayerWeight(i, fromAnim.GetLayerWeight(i));
        }
    }
2 Likes

This not syncing the transitions guys. :frowning:

This not syncing the transitions guys.

To sync identical Animations in a clean way, create a StateMachineBehaviour script named whatever you want and a Parameter named “Offset” in your Animator Controller.

Choose one of the Animations to be the one the others should be syncronized to.

Then, set the Cycle Offset to be equal to the Offset paramete on the animations you chose.
9177053--1277909--upload_2023-7-28_6-16-32.png

Then, add the StateMachineBehaviour script to the animations you chose with the “OnStateEnter” method as such:

        override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
                var animsync = GameObject.Find("Animsync").GetComponent<Animator>();
                animator.SetFloat("Offset", animsync.GetCurrentAnimatorStateInfo(0).normalizedTime % 1);
        }

This will accurately update the Cycle Offset to be equal to where your main Animation is currently at during its animation, and doesn’t solve the problem by just spamming the Update() method.

wow wow wow, this works great thanks for sharing!