What do you want to achieve?
Basically, I’m trying to achieve a working animation to be played on an NPC that will be showed on all clients at the same time.
What is the issue?
No matter what I’ve tried so far, the animation I made hasn’t even moved. The layout of my animation is in a screenshot below.
What solutions have you tried so far?
I’ve been struggling for a while now trying to use different pieces of code edit into my script to make this work, but so far no luck yet. I looked into the Developer Hub, even though I’m not the best scripter, I still gave it a shot. Nothing in specific helped me out on this topic, unless I missed it.
on = false
function onClicked()
if on == false then
on = true
script.Parent.BackgroundColor3 = Color3.fromRGB(0, 255, 0)
-- I attempted multiple codes in here
script.Parent.BackgroundColor3 = Color3.fromRGB(255, 0, 0)
on = false
end
end
script.Parent.MouseButton1Click:Connect(onClicked)
Note: I appreciate any responses in attempt to help me solve this problem I’ve been having.
If you want it to be showed on all clients at the same time, use a remote event.
You will need to fire the remote from the client in the onClicked() function.
In the server script you must use the .OnServerEvent() event to detect when the remote has been fired from a client. In the function in your server script you will :FireAllClients(). The LocalScripts should have a function bound to .OnClientEvent() to detect when the remote has been fired from the server to their client.
In the receiving function in the LocalScript you can play the animation.
Here’s an example:
Local Script
local remote = game:GetService("ReplicatedStorage"):WaitForChild("RemoteEvent")
on = false
local function onClicked()
if on == false then
on = true
script.Parent.BackgroundColor3 = Color3.fromRGB(0, 255, 0)
remote:FireServer() -- Firing remote to the server
script.Parent.BackgroundColor3 = Color3.fromRGB(255, 0, 0)
on = false
end
end
script.Parent.MouseButton1Click:Connect(onClicked)
local function onRemoteFiredFromServer() -- Function for when remote is fired at client
-- play animation
end
remote.OnClientEvent:Connect(onRemoteFiredFromServer) -- Will call onRemoteFiredFromServer() when the remote is fired from the server
Server Script
local remote = game:GetService("ReplicatedStorage"):WaitForChild("RemoteEvent")
local function onRemoteFiredFromClient(player) -- Function for when remote is fired at server
remote:FireAllClients()
end
remote.OnServerEvent:Connect(onRemoteFiredFromClient) -- Will call onRemoteFiredFromClient() when the remote is fired from the client
This is a basic explanation of their use, I hope it helps!
Thanks for the thorough explanation on my problem.
I’ve done all the steps so far except for the last part on playing the animation. I’m not sure on how you would go about playing the animation. When I did an attempt on doing so, I got this error.
22:04:06.634 - Play is not a valid member of KeyframeSequence
That’s strange. I did that and I get yet another error…
22:10:38.286 - Unable to cast value to Object
This is also the script where the error got caused in. I’m not sure if I made any mistakes so if possible correct me if I’m wrong.
local NPCevent = game:GetService("ReplicatedStorage"):WaitForChild("NPCevent")
local function onRemoteFiredFromServer() -- Function for when remote is fired at client
local animationTrack = game.Workspace.RobertJr_YT.Humanoid:LoadAnimation(4820283660)
animationTrack:Play()
end
NPCevent.OnClientEvent:Connect(onRemoteFiredFromServer) -- Will call onRemoteFired() when the remote is fired from the server
In order to keep the NPC from reverting back to how it was before, place this in the onRemoteFiredFromServer() function. It will listen for when the animation stops, and when it does it will freeze the animation at the last frame.
local connection
local function freezeAnimationOnLastFrame()
animationTrack.Speed = 0 -- Sets its speed to zero so it will not change the frame it is on
animationTrack.TimePosition = animationTrack.Length -- Sets the frame it is stuck on to the last frame
connection:Disconnect() -- For efficiency
end
connection = animationTrack.Stopped:Connect(freezeAnimationOnLastFrame) -- Does the exact same as normally connecting a function, but we can call upon that connection object later to disconnect it
Hmm, nothing seems to have happened and it gave me a new error.
Here is the code:
local NPCevent = game:GetService("ReplicatedStorage"):WaitForChild("NPCevent")
local function onRemoteFiredFromServer() -- Function for when remote is fired at client
local Humanoid = game.Workspace.RobertJr_YT:FindFirstChild("Humanoid")
local Animation = Instance.new("Animation")
Animation.AnimationId = "http://www.roblox.com/asset/?id=4820283660"
local AnimationTrack = Humanoid:LoadAnimation(Animation)
AnimationTrack:Play()
local connection
local function freezeAnimationOnLastFrame()
AnimationTrack.Speed = 0 -- Sets its speed to zero so it will not change the frame it is on
AnimationTrack.TimePosition = AnimationTrack.Length -- Sets the frame it is stuck on to the last frame
connection:Disconnect() -- For efficiency
end
connection = AnimationTrack.Stopped:Connect(freezeAnimationOnLastFrame) -- Does the exact same as normally connecting a function, but we can call upon that connection object later to disconnect it
end
NPCevent.OnClientEvent:Connect(onRemoteFiredFromServer) -- Will call onRemoteFired() when the remote is fired from the server
Here we go, time to code for a bit! This should work my man. Place it in the OnRemoteFiredServer function as we did before.
As I understand it, you should be checking when it reaches the last frame instead checking when it ends because you can only adjust the speed when you initially Play() the anim (through the Play() parameters) or while it is playing.
This code identifies the last frame of the animation and creates a KeyframeMarker for the last frame which will be used to call reachedLastFrame().
local keyframes = Animation:GetKeyframes() -- gets all keyframes from the anim and places them in an array
local lastframe = keyframes[#keyframes] -- identifies the last frame
local marker = Instance.new("KeyframeMarker") -- creates the marker
marker.Name = "ReachedLastFrame"
lastframe:AddMarker(marker) -- parents the marker to the last keyframe
local function reachedLastFrame()
AnimationTrack:AdjustSpeed(0)
end
local onLastFrame = AnimationTrack:GetMarkerReachedSignal("ReachedLastFrame")
There are other methods of doing this, but this is a surefire way to identify a specific frame. It also has an easy-to-understand event when it reaches that marker.
I seriously appreciate you helping with this. Sadly, yet again another issue with the code.
The code:
local NPCevent = game:GetService("ReplicatedStorage"):WaitForChild("NPCevent")
local Humanoid = game.Workspace.RobertJr_YT:FindFirstChild("Humanoid")
local Animation = Instance.new("Animation")
Animation.AnimationId = "http://www.roblox.com/asset/?id=4820283660"
local AnimationTrack = Humanoid:LoadAnimation(Animation)
local function onRemoteFiredFromServer() -- Function for when remote is fired at client
AnimationTrack:Play()
local keyframes = Animation:GetKeyframes() -- gets all keyframes from the anim and places them in an array
local lastframe = keyframes[#keyframes] -- identifies the last frame
local marker = Instance.new("KeyframeMarker") -- creates the marker
marker.Name = "ReachedLastFrame"
lastframe:AddMarker(marker) -- parents the marker to the last keyframe
local function reachedLastFrame()
AnimationTrack:AdjustSpeed(0)
end
local onLastFrame = AnimationTrack:GetMarkerReachedSignal("ReachedLastFrame")
end
NPCevent.OnClientEvent:Connect(onRemoteFiredFromServer) -- Will call onRemoteFired() when the remote is fired from the server
The error:
23:23:53.366 - GetKeyframes is not a valid member of Animation
Well, this time there is no error. Which I’m not sure if that’s a good or bad thing. Anyways, it still teleports back to the start. EDIT: The keyframe layout for the KeyframeSequence is in the picture I sent way above.
The code:
local NPCevent = game:GetService("ReplicatedStorage"):WaitForChild("NPCevent")
local Humanoid = game.Workspace.RobertJr_YT:FindFirstChild("Humanoid")
local Animation = Instance.new("Animation")
Animation.AnimationId = "http://www.roblox.com/asset/?id=4820283660"
local AnimationTrack = Humanoid:LoadAnimation(Animation)
local function onRemoteFiredFromServer() -- Function for when remote is fired at client
AnimationTrack:Play()
local keyframes = game.Workspace.RobertJr_YT.OfficialDrummer_RobertJr_YT:GetKeyframes() -- gets all keyframes from the anim and places them in an array
local lastframe = keyframes[#keyframes] -- identifies the last frame
local marker = Instance.new("KeyframeMarker") -- creates the marker
marker.Name = "ReachedLastFrame"
lastframe:AddMarker(marker) -- parents the marker to the last keyframe
local function reachedLastFrame()
AnimationTrack:AdjustSpeed(0)
end
local onLastFrame = AnimationTrack:GetMarkerReachedSignal("ReachedLastFrame")
end
NPCevent.OnClientEvent:Connect(onRemoteFiredFromServer) -- Will call onRemoteFired() when the remote is fired from the server
Unless I added the strip of code in the wrong area, there is still the same effect and no error.
The code:
local NPCevent = game:GetService("ReplicatedStorage"):WaitForChild("NPCevent")
local Humanoid = game.Workspace.RobertJr_YT:FindFirstChild("Humanoid")
local Animation = Instance.new("Animation")
Animation.AnimationId = "http://www.roblox.com/asset/?id=4820283660"
local AnimationTrack = Humanoid:LoadAnimation(Animation)
local function onRemoteFiredFromServer() -- Function for when remote is fired at client
AnimationTrack:Play()
local keyframes = game.Workspace.RobertJr_YT.OfficialDrummer_RobertJr_YT:GetKeyframes() -- gets all keyframes from the anim and places them in an array
local lastframe = keyframes[#keyframes - 1] -- identifies the last frame
local marker = Instance.new("KeyframeMarker") -- creates the marker
marker.Name = "ReachedLastFrame"
lastframe:AddMarker(marker) -- parents the marker to the last keyframe
local function reachedLastFrame()
AnimationTrack:AdjustSpeed(0)
end
local onLastFrame = AnimationTrack:GetMarkerReachedSignal("ReachedLastFrame")
onLastFrame:Connect(reachedLastFrame)
end
NPCevent.OnClientEvent:Connect(onRemoteFiredFromServer) -- Will call onRemoteFired() when the remote is fired from the server