Animations don't replicate when client plays them

(Following up on Animations not replicating from client)
I am playing AnimationTracks loaded into an AnimationController from the client, but they do not replicate to the server and to other clients

Extra information:

  • The client owns the physics for the NPC (and all its parts are unanchored)
  • There is no humanoid, it uses an AnimationController and the Animator instance inside the AnimationController was created offline
  • The Handle (root part) has priority 127, everything else has priority 0 (this was set offline)
  • All of the constraints are created offline or on the server
  • The client loads AnimationTracks from the folder workspace.anims containing Animations which was created offline
  • I don’t modify AnimationTrack properties such as Weight, Looped, Priority, and Speed
  • They play perfectly on the local client
1 Like

It might help to make a minimal repro here using some default animation that can play anywhere. This seems hard/tedious to repro just having the text here otherwise.

1 Like

I’ve also noticed that sometimes animations on Player characters (untouched, default r15s spawned with LoadCharacter) wont replicate to others as well–I’m not sure if this is related, but I thought I’d mention it

(the OP issue still happens 100% of the time)

It seems like you might be having a similar issue to what I’m going through, although I don’t have a working solution you might be able to find something that works for you here hopefully.

1 Like

Thanks, I looked through your thread and I couldn’t find anything I haven’t done

If it doesn’t get resolved, I’ll probably dedicate a full day of next week to creating a repro of OP’s 100% occurring bug as @buildthomas suggested

here’s a repro:
animationcontrollerdoesntreplicate.rbxl (17.8 KB)

the animation in animtest is the same as workspace.Model.AnimSaves.ExportAnim.Test

I believe its network ownership, you likely shouldn’t run animations on anything global from a client unless it’s your actual character.

Sorry about this: The documentation on AnimationController and Humanoid for playing animations from the client has been incorrect for a long time.

It doesn’t rely on network ownership at all. Replicating animations from the client is only allowed for descendants of the Player’s Character.

Making the model a descendant of the Character in your repro makes it work. In this case, if it’s not physically a part of the Character model and low-latency responsiveness to user input isn’t absolutely critical, I’d recommend just calling LoadAnimation from the server and allow the animation event to replicate from there. Besides the initial latency it should animate just as smoothly on any client either way.

Also worth noting that all replication for Animations is handled through internal replicated events on the Animator object, so for replication from the client to work it’s critical that the animator is first created on the server and replicated to the client before you first call LoadAnimation. All client-side animation scripts should include a WaitForChild(“Animator”) before the first LoadAnimation. Not an issue in your case, but FYI.

I filed a request with the IX team to correct the documentation and add these notes a month ago and it should be updated soon.

2 Likes

Hey @Sarenheart00, besides the things I mentioned above the Animator has one more weird quirk that could be causing your random issue.

You’ll want to make sure the sum of weights for all playing animations within the same priority add up to exactly 1.

If the sum of weights is < 1 it blends with the result of the next lower priority.

If the sum of weights is > 1 the Animator will process playing AnimationTracks until the total of weights >= 1 and then stop, ignoring any remaining playing tracks. Usually this will ignore the most recently loaded clips, but order isn’t guaranteed.

I know any rational person would expect us to just normalize the weights when the total is > 1. We plan to fix this soon, but I don’t have an ETA.

Let me know if this is the issue you’re hitting.

2 Likes

@ContextLost I’ve got pretty good reasoning that you’ve nailed the issue. I decided to run a small test, bringing all my systems back to a fixed state, (I messed a ton up trying to solve this), and printed the animation weight of any playing tracks using the AnimationPlayed() on the humanoid. Every time I see the weight print as something that isn’t zero, (oddly enough even a weight of 0.5 seems to break it), the replication completely stops. Although to be honest, I’m not entirely sure how to go about fixing this, I’m not all that experienced with animation weights as I’ve never really had an issue/need to fix/do with them.

–Edit------

https://streamable.com/3bhcn

^ Link to a recording of me printing weights with a client and server view

Hey @ContextLost, I know that it’s probably not a great idea to nag you about an ETA on a fix for this issue, however, it’s utterly ruined Saren and I’s game. It’s been around since January I believe.

Have any info on an ETA for this issue to be fixed? Our players have been complaining about it every day since release.

Sorry, hard to give an ETA.

This should also be able to work around by just ensuring that the weights on your AnimationTracks add up to less than or exactly 1 by setting the weights correctly in your own code managing your animations.

Note there’s also a separate hard limit of 10 unique animations playing at a time as well. No immediate plans to raise that limit either.

If you stay under both of these limits you should be fine.

2 Likes

So I’ve been toying around with attempting to get the total weight, but I’ve ran into a sort of odd predicament. I don’t actually know how to get the total weight of everything playing, nor do I have the slightest clue as to how I can actually go about keeping them at 1 or below.
I’ve tried looking up as much as I can about AnimationTrack weights and I’ve pretty much hit a wall at this point.

–Edit----

I’m also really confused as to what actually mandates as the true “weight” of a track. When printing WeightCurrent it always prints zero, until it randomly prints some number above. Yet all the animations have a target weight of 1. If the current weight of all tracks is supposed to be below 1 is there some sort of different math that determines the total weight. Because adding them up doesn’t make much sense to me, as playing two animations at once would instantly bring you over 1.