Animator.SetTrigger/NetworkAnimator.SetTrigger Bug?

I'm a bit confused about the functionality and purpose between the Animator component and the NetworkAnimator. From my understanding since the debut of 5.0, the NetworkAnimator was simply responsible for relaying the state of the Animator's parameters across the network. ...and that's how I've been using it to date. However, with the recent addition to the Animator of .SetTrigger I've switched from using booleans to trigger certain Animator states to using triggers. Therein lies my problem/confusion. Everything works properly up until the point of needing to synchronize triggers over the network. My speed parameter determines if the player is idle, walking, or running. Via script I modify it (on the client that has authority) using Animator.SetFloat(). This works just fine. On all other clients the animation is synchronized. However, when I use Animator.SetTrigger() for attacks, the animation is not synchronized. The animation occurs on the client, but it does not happen on the server or on other clients.

I've looked into using NetworkAnimator.SetTrigger(). This DOES synchronize the proper animation to the server and other clients. However, it's a bit wonky. It's as is the animation starts, and then a few frames into it, it resets and starts again.

1 Like

I am struggling with syncing animations right now too, and I was using the Network Animator on my objects, and (like you), my characters animate according to their velocity (or speed). I noticed the same "reseting" of the animation, and my guess was that because of the latency between clients and server, the client sees the object as moving at a fluid velocity, whereas the server only gets that data in chunks (with delays inbetween). I'm guessing this causes the server to see your object as having "zero" speed for short amounts of time -- and thus the choppy animations.

To fix this (for my part) I stopped using velocity to determine animations, and simply started using booleans. That is, if my unit/character has a path, I play the run animation, if it doesn't I stop the animation. This worked for me. But then you have to stop using velocity for animations (which is a dirty solution, but it worked for me).

As for your Animator trigger problem, I don't know yet, sorry. I'm still trying to get the Network Animator to sync animations properly when I have "Local Player Authority" checked on my objects. Currently it's not syncing animations between all clients and the server.

BUMP

A bit of an update... So I forgot to change the transitions for these animations. They transition from the ANY state...and I unchecked "Can Transition from Self". That fixed it a little. Now it doesn't start and then restart a few frames in. Now...using NetworkAnimator.SetTrigger()...it plays the animation...but it plays it twice.

EDIT - This only happens on the server...not connected clients. So the player acting as the server...their character performs the animation twice. Connected clients only perform the animation once.

Still struggling with this. Trying to isolate the problem I went back to using Animator.SetTrigger(). I tested it both as a client and as a host. The animation plays properly on the Local Player, but for anyone else observing it doesn't play...BUT...it DOES execute. I know this because there's an animation event on the animation. And the event executes on the server if the animation is coming from the client. Come on...SOMEBODY else must be going through this or have gone through it.

That's interesting. I had just assumed that normal triggers were not synced with that component. But if your event is firing then it must be a bug in unet that's just not playing the animation?

I don't know. I mean with UNet still in development the docs aren't really clear.

http://docs.unity3d.com/Manual/class-NetworkAnimator.html
http://docs.unity3d.com/ScriptReference/Networking.NetworkAnimator.SetTrigger.html

This is confusing to me because the NetworkAnimator page says that the component syncs ALL animations (float, int, bool, and trigger). But then why do you need the NetworkAnimator.SetTrigger() function if the NetworkAnimator already synchronizes Animator.SetTrigger() if the NetworkAnimator is set to auto-send that parameter? Only other information I could find was here...

http://forum.unity3d.com/threads/unet5-1-anim-trigger-parameter-how-do-i-use-networkanimator-settrigger.351214/

...and I don't think he has a clue what he's doing either, because he's setting the trigger on both the Animator and the NetworkAnimator. And like I said above, using the NetworkAnimator.SetTrigger() causes the animation to play twice for the Local Player (if the Local Player is the host)...and not at all for other observers.

BUMP

@hashashin You haven't supplied nearly enough information for anyone to be of any help to you. What parameters does your walk animation use for transitioning? Bool? Float? Int? Trigger? Is the parameter for walk set up to AutoSend? (If you don't know what this is you haven't looked over the docs for the NetworkAnimator enough).

In any case, unless your walk animation uses a Trigger parameter, this isn't the thread for you to seek help in. This thread is specifically for determining whether Triggers are properly synchronized across the network using the NetworkAnimator if you use Animator.SetTrigger(), or if there is a bug in NetworkAnimator.SetTrigger().

Almost 250 views and nobody else has encountered this problem? :eyes:

Hi, I solved this problem with a workaround, unchecking the trigger on the NetworkAnimator list and manually setting the trigger (standard animator), using a Command (in local player) that call a ClientRPC on all the other client instances.

While I already knew about that "work around" I appreciate it anyway @a-bottosso . Still would love to hear from someone on the Unity team about this.

I'm having the same problem... doesn't seem to be solved by the latest patch. Every triggered animation is played twice on a hosting player's game.

Any progress?

We hit this today and found a pretty hilarious fix: disable localPlayerAuthority on any NetworkIdentity that's controlled by a player on the server.

This gets rid of the doubling of animations, and at the same time does not remove player control/authority for the server players (I'm guessing because it's the server and it's special).

Anyway, hope this helps other people who google "NetworkAnimator double animations", and I'm looking forward to editing this when it breaks in some random update in the future :)

Im having the same issue, SetTrigger on Network Animator plays animations twice. Fixed it using a.botosso's rpc workaround for now. Client calls CmdSetTrigger(str), and on server it calls RpcSetTrigger(str).

I guess another workaround would be to have a SyncedVar named TriggerStr, with a hook that runs SetTrigger().
On a side note, after I started experimenting with Unet, unity editor has been crashing alot, do you guys notice that too?

Yep, same problem here, triggers are not syncing AT ALL for me

Bump.
I was having the same issue with the network animator.
I used the workaround as suggested but I'm curious why this hasn't been taken care of. Isn't this a bug?

Animations still triggered twice and also Animator.SetLayerWeight is not working properly...

Yep. It is a bug, but it seems to be one the dev. team doesn't seem keen on identifying/addressing.

Can you try to use the NetworkAnimator.setTrigger("trigger name")?
For example I have something like this:

private void UpdateAnimator(Vector2 input)
{
  animator.SetFloat("forward", input.y);
  animator.SetFloat("horizontal", input.x);

  if (CrossPlatformInputManager.GetButtonUp("Jump"))
  {
    animator.GetComponent<NetworkAnimator>().SetTrigger("jump");
  }

  animator.SetBool("grounded", characterController.isGrounded);
  animator.SetBool("walking", CrossPlatformInputManager.GetButton("Walk"));
  animator.SetBool("crouching", isCrouching);
}

and in network setup:

public override void OnStartLocalPlayer()
{
  //forward
  GetComponent<NetworkAnimator>().SetParameterAutoSend(1, true);
  //horizontal
  GetComponent<NetworkAnimator>().SetParameterAutoSend(2, true);
  //crouching
  GetComponent<NetworkAnimator>().SetParameterAutoSend(4, true);
  //jump
  GetComponent<NetworkAnimator>().SetParameterAutoSend(6, true);
  //grounded
  GetComponent<NetworkAnimator>().SetParameterAutoSend(8, true);

}

public override void PreStartClient()
{
  //forward
  GetComponent<NetworkAnimator>().SetParameterAutoSend(1, true);
  //horizontal
  GetComponent<NetworkAnimator>().SetParameterAutoSend(2, true);
  //crouching
  GetComponent<NetworkAnimator>().SetParameterAutoSend(4, true);
  //jump
  GetComponent<NetworkAnimator>().SetParameterAutoSend(6, true);
  //grounded
  GetComponent<NetworkAnimator>().SetParameterAutoSend(8, true);
}