Animation replication help

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!

What I’m trying to do is get the move in the video below to look like it does on the lefthand side for all clients and the server. The Roblox studio on the lefthand side is the local client and the one on the right is another client. This is a simplified version of what I’m actually trying to do but it includes everything I think is relevant to the problem

  1. What is the issue? Include screenshots / videos if possible!

https://gyazo.com/1bea490b37e6bd5900a75f273f5484ab

When the player has the tool equipped and presses M1 then the Fire function shown below is executed which plays an animation. This animation has a marker called fire which stops the animation, then invokes the server which waits 2 seconds, then prints something and then returns true which allows the client code to keep running so the animation resumes.

Where I believe the problem lies is when the marker is reached for the local client it somehow executes the following code:

anim:GetMarkerReachedSignal("Fire"):Connect(function()
	anim:AdjustSpeed(0)
	local arm = RemoteFunction:InvokeServer() 
	anim:AdjustSpeed(1)
end)

for all the other clients which is what I don’t understand. This is a problem because the animation that plays on other clients is delayed so the results I want can’t be achieved .

I’ll attach the relevant code below:

-- Client
function Fire(name,state,input)
	if state == Enum.UserInputState.Begin then		
		anim:Play()
	end	
end

anim:GetMarkerReachedSignal("Fire"):Connect(function()
	anim:AdjustSpeed(0)
	local arm = RemoteFunction:InvokeServer() 
	anim:AdjustSpeed(1)
end)

script.Parent.Equipped:Connect(function()
	CAS:BindActionAtPriority(script.Parent.Name,Fire,false,2,Enum.UserInputType.MouseButton1)
end)

script.Parent.Unequipped:Connect(function()
	CAS:UnbindAction(script.Parent.Name)
end)

--Server
RunFunctions.OnServerInvoke = function(player,attackName,func, info)
	wait(2)
	print("In sever core")
	return true
end
  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I don’t understand how animation replication works too well so I’m struggling to figure out how to make this work at all and I couldn’t find helpful information on this either.

Thanks in advance.

1 Like

Okay most people don’t answer here since this is a pretty complex topic. Providing code for this functionality is a mess since there are many parts that you need to take care of based on your use, but I will give you a high level overview of what it is that needs to be done.

Firstly, let’s make sure we understand the problem. Roblox uses automatic animation replication. Let’s say we have server S, client A and client B. When A plays the anim, Roblox automatically announces it to the server and then the server automatically replicates this animation to B. It’s normal that the animation on B will start later and there is nothing you can do to stop this. But what is very important is that an animation replication is heavier in terms of data size when it comes to initializing the animation, rather then just adjusting the animation speed (this is just a number, not a whole instance). So what happens is that, when client A stops his animation locally, client B may have barely started playing it, however because the replication of adjusting the animation’s speed is much faster, client B stops his animation much sooner then he should have.

So now you know what is causing you problem.

Step 1 would be to somehow prevent this automatic replication from taking place, since it is not something you can control, and it is clearly wrong in your usecase. This is not super convenient, but you can find a solution here as to how to stop the Server from replicating animations to the other clients: Stopping an Animations Auto-Replication

Step 2 , now that the punch doesn’t replicate on the other clients, you will need to code the replication yourself. This is not super hard. What you need to do is when client A plays the punch animation, send an event to the server. After this, the server has to send an event to all other clients (B, C,… etc) and let them know that A started playing the punch. Now what the other clients need to do, is implement a special Local Script functionality that plays the animations for other players, in the same way that you do in A with your own client.

Step 3 is make sure you re-enable normal Roblox animation replication after this is done, so that other animations such as walking/running function well.

In terms of code, I can try to give you some hints as to how you could make this easier.
Try to build a Local function that take in a character as an argument, and plays this animation locally for given character.

Now, when your local client punches, just use this function with your own character, and before starting it announce the server that you run the punch, so that he stops your animation replication on the other clients.
But also setup a listener locally, to listen for events from the server, as he might announce that someone else wants to punch, and now you can call the same function with some other player’s character, and animate it again locally so the punch animation will be smooth.

I know this is not the best explanation you could have gotten, and apologies if what I wrote is confusing. If you want you can ask me more details or code stuff and I will reply. I just didn’t feel like writing some code on your scenario would help, since what you provided is obviously just a prototype and at the end of the day my implementation could interfere with your needs.

3 Likes

dude is this related too? tool animations arent being replicated too.
this bug can be fixed by re-equipping the tool but I gotta tell the player first… I don’t know why this happens image

It depends on what you mean exactly, but if it’s like slashing animations then it’s probably not the exact same. In his case, he wants to apply specific behaviour based on the timeline position within an animation, which causes the replication issues, since the replication system isn’t super consistent and fluctuates a lot, especially when you need detail and precision.
For you I’d guess it’s just that the first time it takes longer to load the animation, therefore you see some weird behaviour taking place, where the animations aren’t initially loaded.

I think what you could do, is have some hidden dummy (for example under the map), that locally loads all animations. This way, when you will equip the tool, your animation will be preloaded :stuck_out_tongue: .

the thing is, we already pre-loaded the animations before giving them the tool

Yes this is different but I’m not entirely sure. I think preloading the asset is different from actually preloading the animation instance withing an animator and playing it. That’s why I would recommend you to try what I mentioned here:

However I am not sure it’s okay to discuss this here, if you want you can message me privately, we should leave this post clean since this discussion was meant to help @MED_SSJ.

Thanks for the reply I get what you’re saying but I have one thing that’s confusing me that I should’ve made clear before. I want to have some specific effects play on the server which are for a part to be instantiated and for it to be tweened instead of just waiting for 2 seconds.

The reason I’m confused is when I play the animation on the local client and then the server code executes the effects, that animation is gonna be earlier than it is for the other clients even if I use your anim replication method, so I wouldn’t get the desired effect. How would I make sure that the effects play at the correct time for the other clients because the only alternative I can think about is that they all individually fire the server and execute the effects but that won’t work because the effect will end up playing multiple times for each client.

You need to do this locally on each client. The server will tell them when they have to start, and when each player starts playing the animation locally, also starts the part instantiation (only on his client, locally). Basically, how custom replication works is, each client plays the effects locally, instead of the server playing them for everyone.

Oh okay I get what you’re saying but I don’t think that’s the best for my use case as the part is going to have to deal damage to player so it doesn’t seem appropriate to play this on the client. Do you know of any other solutions that can be used in order to deal with this problem.

I’m saying this a bit late but I don’t think it would’ve been worth it in terms of performance if I played my animation on the client for my use case so I just decided to play the animation on the server without changing the network owner and that stopped the delay that the other non local clients have.