Local scripts don’t run in workspace. Does changing “Run Context” make it run on the client?
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.
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?
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.
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?
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.
The problem is that when I call :AdjustSpeed() from the server, it doesn’t affect the client. The client does not see any difference.
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.
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
I would just use two scripts
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)
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.
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.
- Animation script is set to Client for RunContext, parented to Model
- RemoteEvent parented to the Model, let’s call it AnimationAction
- 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)
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…