Best way to replicate animation from server to client?

Local scripts don’t run in workspace. Does changing “Run Context” make it run on the client?

1 Like

Yes, that’s what the new roblox feature does. Your local script will run on the client even if it’s in workspace if it’s set to that run context.

1 Like

Ah I see, thanks for the clarification. What about other custom animations played on the server? Do I just remote event and make my own script on the client?

1 Like

Just convert your server script to the client script by switching it’s RunContext. If it needs to talk to other server scripts, you could build an interface using remote events.

6cd5055ee8c550cd3ce6157c707373006985d64f_2_267x500

1 Like

The custom animations are like Attack animation, Shoot animation, etc. It is triggered by the server. Does that mean I should use remote events to create the animation on the client and play it on the client?

1 Like

What was the problem with playing the animations on the server? I read the first post, but I don’t understand the problem. I run all my npc animations from the server, and they work just fine. Roblox does a good job or replicating server animations to the clients.

1 Like

The problem is that when I call :AdjustSpeed() from the server, it doesn’t affect the client. The client does not see any difference.

1 Like

Ah, I see, I thought they had fixed the issue with speed replication.

So… In that case, you would need to have the animation play on the client.

This is how I would go about it.
In each npc I would have 2 scripts, one server and one client

The server script controls the npc, etc…
The client script will play the animation and adjust speeds

So how to communicate between the two?
You could use remote events, but in truth, you only need one way communication from server to client scripts. So you can just have the server set Attributes on the npc, and the client script detect a change in those attributes.

1 Like

In that case I think a module script would be useful. Do you have any ideas on the outline of how the module script should be scripted

1 Like

I would just use two scripts
image

Server

local npc = script.Parent


function PlayAnimation(id,speed)
	npc:SetAttribute("AnimationId",id)
	npc:SetAttribute("AnimationSpeed",speed)
end

function AdjustAnimationSpeed(speed)
	npc:SetAttribute("AnimationSpeed",speed)
end


Client

local npc = script.Parent
local currentAnim = {
	Id = nil,
	Track = nil
}


npc:GetAttributeChangedSignal("AnimationId"):Connect(function()
	local id = npc:GetAttribute("AnimationId")
	local speed = npc:GetAttribute("AnimationSpeed")
	
	if currentAnim.Id ~= id then
		if currentAnim.Track then
			currentAnim.Track:Stop()
		end
		if id then
			local anim = Instance.new("Animation")
			anim.AnimationId = id
			currentAnim.Id = id
			currentAnim.Track = npc.Humanoid:LoadAnimation(anim)
			currentAnim.Track:Play()
			if speed then
				currentAnim.Track:AdjustSpeed(speed) 
			end
		else
			currentAnim.Id = nil
			currentAnim.Track = nil
		end
	end
end)

npc:GetAttributeChangedSignal("AnimationSpeed"):Connect(function()
	local id = npc:GetAttribute("AnimationId")
	local speed = npc:GetAttribute("AnimationSpeed")
	
	if currentAnim.Id and currentAnim.Track then
		currentAnim.Track:AdjustSpeed(speed)
	end
end)
1 Like

I agree with this, definitely play the animation locally. Things regarding visual effects, and things not crucial to gameplay should be on the client, always. This way you sync things up, and customize even further things that would take too much of the server’s time, and it solves your :AdjustSpeed() problem.

2 Likes

Yes

The AI is controlled on the server side. Whenever the NPC does something, you perform the action/checking on the server side and fire a remote event to the client on it.

Example: AI Fires a gun.

  1. Animation script is set to Client for RunContext, parented to Model
  2. RemoteEvent parented to the Model, let’s call it AnimationAction
  3. NPC shoots a laser gun:
    a. Server Side: Spawn the laser hitbox and do the damage
    b. Server Side: AnimationAction:FireAllClient(“Shoot”, animationSpeed, startPos, stopPos)
    c. Client Side: Received animationName, animationSpeed, startPos, stopPos
    d. Client Side: Play the gun recoil animation using animationSpeed
    e. Client Side: (optional) Spawn the laser visual based on startPos/stopPos

You now have 100% control over the animation and can play it smoothly.

This is what most modern Roblox games with lots of NPCs use. Think about every time you’ve played an AI swarm game and saw smooth and responsive animations and visual effects without lag stuttering (example: most modern tower defense games)

2 Likes

It seems like it only allows one animation to be played at a time. However I definitely would need more than just one animation at a time played, for example walking and shooting at the same time. I have come up with a simple script that uses remote events to communicate instead of attributes…

1 Like