I’m attempting to Play Animations on a Client Controlled Character by SetNetworkOwner(Player)
However it’s not replicating.
From my understanding Animations should replicate when a Humanoid or an AnimationController is Network Owned by the respective Controller; a Mini is Network Owned by a Player who’s controlling it’s Animation.
Tested in Studio with Accurate Play Solo
I also did additional testing with Start Server and 2 Players, each player had their own Mini dancing but not for the other player.
I just did some research… I’m pretty sure you need to set the ownership of the animation to the client, in order for the animation to replicate to the server when played without the use of remote events.
Check through your code to make sure that you’re setting network ownership of the animation object to the client through the server.
In other words Animations will only replicated from the Client to Server if that Character is a Player’s Character?
I’m not entirely sure about it being more efficient since these NPCs are controlled on the Client shouldn’t the Client also handle Animations?
They aren’t stationary NPCs owned by the Server but they belong to the Player; each player has their own NPC, these NPCs aren’t shop keepers owned by the Server.
I am not entirely sure on this point. At first, I interpreted the documentation as anything which the player had network ownership over, however this was not the case when I tested it which lead me to assume that only player characters are replicated like mentioned in the article.
If they are only controlled on the client, why does the server create it? I assume it is because other players are supposed to also see it, while you want the animations to run smoother for the client who owns it?
Yes, the NPC will follow the Player around (Movement Controlled) and Animated.
The reason why I’m not or don’t want to Play Animations on the Server is because of Latency, I want to provide instant feedback to the player’s input for better UX than a delayed feedback.
If that is impossible for the Roblox Studio then I’ll have to control Animations on the Server.
Unfortunately, I am unable to provide a solution which will automatically replicate the animation to the server.
Luckily, it is possible to manually implement this behaviour. You can load the animation on the client first, then :FireAllClients() from the server to play it on each client. I may be missing something, however if you want to avoid latency then this may be the only option (unless anyone can solve your original request for automatically replicating the animation).
cc @colbert2677 to clarify whether this is the best approach or there is another way. I believe they have made solutions to similar threads in the past.
I actually don’t think I have. I’ve seen many posts regarding the inability to replicate animations via network ownership but I’ve not been able to crack the case. The solutions to those threads are fairly inconsistent and typically include workarounds.
At the very least, something I do know is that animation replication is done via the Animator object. Disabling replication is as simple as replacing that object, but I don’t know about doing the operation in reverse.
In terms of the method you showed, FireAllClients is the least expensive non-automatic solution to replicating animations or anything in general. Letting each client handle visuals puts no stress on the server, since it’s just sending received information back around.
As far as automatic animation replication goes though, I don’t quite have an answer yet. Getting animations to replicate on objects that aren’t the player’s own character seems more difficult or over-thought than it should be. Sorry I couldn’t be of much help in that regard.
Once their custom rig has been set a local script would then enable the animate script, starting the animations for their character. However, as it stood I had the same problem as @RuizuKun_Dev, in that the animations do not replicate to other clients, demonstrates below:
The solution is really quite simple, @colbert2677 was on the right tracks. You need to create an Animator object on the server for the rig. I did that by simply calling Humanoid:LoadAnimation() on the morphs humanoid whilst in studio, this is the one liner I used:
Aha! Now that would make sense. Considering animation replication is controlled by the Animator object and is part of the rig construction process, you can take that work out by creating it manually. LoadAnimation is typically supposed to create this though if one doesn’t exist.
A client can take themselves out of replication by removing the Animator object and creating their own so that they can run animations on other characters for themselves, so backwards would be having the server create the Animator object for the character.
Good catch, it’s all up to confirming that users having issues with animation replication can use that method to fix their own cases.
Nice solution! This frustrated me in a while ago while I was writing my own custom Animate script. I solved this problem by loading less animations. Initially I called humanoid:LoadAnimation() for over 10 times, later I only use one for all character movement animations. It greatly reduced the chance of it happening.
It still happens sometimes but really rarely, and I usually see it fixed by simply playing another animation, such as a character changing from walking animation to idle (Using the same LoadAnimation). It’s like “Activating the Animator”. I think playing a dummy animation (it can be a animation with nothing) and stop it on the server side might solve it.
Hey so I’m a bit confused soo we have to load the animation server-side as well? So should it be something like this?
Server side
local Anims = game.ReplicatedStorage.Animations
game.Players.PlayerAdded:Connect(function(plr)
plr.CharacterAdded:Connect(function(char)
while char.Parent == nil do
char.AncestryChanged:wait()
end
local Humanoid = char.Humanoid
local PortArmsTrack = Humanoid:LoadAnimation(Anims.PortArms)
local AimingTrack = Humanoid:LoadAnimation(Anims.Aiming)
end)
end)
Hey so I’m a bit confused soo we have to load the animation server-side as well? So should it be something like this?
Server side
local Anims = game.ReplicatedStorage.Animations
game.Players.PlayerAdded:Connect(function(plr)
plr.CharacterAdded:Connect(function(char)
while char.Parent == nil do
char.AncestryChanged:wait()
end
local Humanoid = char.Humanoid
local PortArmsTrack = Humanoid:LoadAnimation(Anims.PortArms)
local AimingTrack = Humanoid:LoadAnimation(Anims.Aiming)
end)
end