Still the same effect, and no error for some reason.
Good morning!
Move AnimationTrack:Play()
to the very end, should work!
Good morning. I moved it to the end and there is still the same effect, and no error sadly.
The method I tried in the reply was wrong. I attempted to retrieve the Keyframes from an Animation instance, but you can only do so from a KeyframeSequence!
edit: Accidentally deleted message with a reply
Put a ServerScript inside the NPC. Define the Humanoid (script.Parent.Humanoid). Put the animation inside the script.
local Animation = Humanoid:LoadAnimation(script.Animation)
Animation:Play()
It automatically plays the animation on the NPC, replicating to ALL clients at the same time, because the NPC is animated on the server – therefor automatically replicating for everybody.
I have no clue what RemoteEvents here would be useful for, especially “onClicked()”. This is literally a few lines of code! If your animation plays and resets back to the start when it’s finished, you simply need to make the animation visually looping - if it starts on the NPC crossing arms, make it end on the NPC crossing arms again.
edit: formatting
I remember us trying this before. I got this same error.
09:33:27.741 - GetKeyframes is not a valid member of Animation
Sorry, this GetMarkerReachedSignal() method is very new to me, so I’m trying to understand it right now just as you are. I’m quite sure this is what you need to do. Before you load the animation into the humanoid, you need to add the Marker.
local NPCevent = game:GetService("ReplicatedStorage"):WaitForChild("NPCevent")
local Humanoid = game.Workspace.RobertJr_YT:FindFirstChild("Humanoid")
local function onRemoteFiredFromServer() -- Function for when remote is fired at client
local Animation = Instance.new("Animation")
Animation.AnimationId = "http://www.roblox.com/asset/?id=4820283660"
local success = pcall(function()
keyframes = KeyframeSequence:GetKeyframeSequenceAsync(Animation) -- proper method to retrieve the KeyframeSequence
end)
if success then
keyframeTable = keyframes:GetKeyframes() -- creates a table containing the keyframes
local lastframe = keyframeTable[#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 AnimationTrack = Humanoid:LoadAnimation(Animation) -- Now we load the AnimationTrack after the Marker has been added
local function reachedLastFrame()
AnimationTrack:AdjustSpeed(0)
end
local onLastFrame = AnimationTrack:GetMarkerReachedSignal("ReachedLastFrame")
onLastFrame:Connect(reachedLastFrame)
end
end
NPCevent.OnClientEvent:Connect(onRemoteFiredFromServer) -- Will call onRemoteFired() when the remote is fired from the server
Phew. There was a lot of learning for me through the process of writing this. Really hope this works!
No it’s completely fine, I’m just shocked your willing to help me this far. Your the best.
I tried it and got an error, but maybe because these two words are underlined?
I’m more than happy to help you out. Once we have this all figured out, I’ll create a community tutorial to make sure there’s some better documentation out there haha.
Alright, here’s what we need to do:
Add the single line
local keyframeTable
Before the pcall function.
Then add
local KeyframeSequence = game:GetService("KeyframeSequenceProvider")
to the top of the script.
I’ve said it a thousand times, but that should be all fixed!
Agh, yet again another error. This one I haven’t seen before yet.
10:01:52.359 - Players.RobertJr_YT.PlayerGui.Visuals:18: attempt to get length of global 'keyframes' (a nil value)
EDIT: The error happened on this line.
local lastframe = keyframeTable[#keyframes] -- identifies the last frame
I forgot to change #keyframes
to #keyframeTable
. That’s all it is
edit: a letter
Gargh! This is very frustrating. I changed it and I still get another error.
10:05:19.034 - Players.RobertJr_YT.PlayerGui.Visuals:18: attempt to get length of upvalue 'keyframeTable' (a nil value)
Guess what buster, we’re gonna count the items in the table ourselves!
local NPCevent = game:GetService("ReplicatedStorage"):WaitForChild("NPCevent")
local Humanoid = game.Workspace.RobertJr_YT:FindFirstChild("Humanoid")
local function onRemoteFiredFromServer() -- Function for when remote is fired at client
local Animation = Instance.new("Animation")
Animation.AnimationId = "http://www.roblox.com/asset/?id=4820283660"
local success = pcall(function()
keyframes = KeyframeSequence:GetKeyframeSequenceAsync(Animation) -- proper method to retrieve the KeyframeSequence
end)
if success then
keyframeTable = keyframes:GetKeyframes() -- creates a table containing the keyframes
local count = 0
for _ in pairs(keyframeTable) do count = count + 1 end -- Iterates through every item and adds 1 to the counter.
local lastframe = keyframeTable[count] -- 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 AnimationTrack = Humanoid:LoadAnimation(Animation) -- Now we load the AnimationTrack after the Marker has been added
local function reachedLastFrame()
AnimationTrack:AdjustSpeed(0)
end
local onLastFrame = AnimationTrack:GetMarkerReachedSignal("ReachedLastFrame")
onLastFrame:Connect(reachedLastFrame)
end
end
NPCevent.OnClientEvent:Connect(onRemoteFiredFromServer) -- Will call onRemoteFired() when the remote is fired from the server
Yet again, there is no effect and no error. I wish I’m able to script to this level so I can at least help a bit.
The current script in its form:
local NPCevent = game:GetService("ReplicatedStorage"):WaitForChild("NPCevent")
local Humanoid = game.Workspace.RobertJr_YT:FindFirstChild("Humanoid")
local keyframeTable
local KeyframeSequence = game:GetService("KeyframeSequenceProvider")
local function onRemoteFiredFromServer() -- Function for when remote is fired at client
local Animation = Instance.new("Animation")
Animation.AnimationId = "http://www.roblox.com/asset/?id=4820283660"
local success = pcall(function()
keyframes = KeyframeSequence:GetKeyframeSequenceAsync(Animation) -- proper method to retrieve the KeyframeSequence
end)
if success then
keyframeTable = keyframes:GetKeyframes() -- creates a table containing the keyframes
local count = 0
for _ in pairs(keyframeTable) do count = count + 1 end -- Iterates through every item and adds 1 to the counter.
local lastframe = keyframeTable[count] -- 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 AnimationTrack = Humanoid:LoadAnimation(Animation) -- Now we load the AnimationTrack after the Marker has been added
local function reachedLastFrame()
AnimationTrack:AdjustSpeed(0)
end
local onLastFrame = AnimationTrack:GetMarkerReachedSignal("ReachedLastFrame")
onLastFrame:Connect(reachedLastFrame)
end
end
NPCevent.OnClientEvent:Connect(onRemoteFiredFromServer) -- Will call onRemoteFired() when the remote is fired from the server
We’re trying to get the animation to freeze/stop on the final frame so the NPC doesn’t teleport back to the start of the animation.
EDIT: I was already working with @Spraden on this we are basically almost through with a solution. I didn’t much take into account on what he said since there would be no point redoing the script.
That can still be done on the server.
Edit: Actually, this can be done on the client. When you play an animation on the client, it automatically replicates to all other clients.
Something that just occurred to me:
Detect when it stops, Play() it again, but as you play it, then set AnimationTrack.TimePosition and do AnimationTrack:AdjustSpeed(0).
I believe our problem earlier may have been we didn’t play it again. Unfortunately it’s kind of hacky, and the one we’re trying now is much less so.
Try out what I typed above while I research more and try to figure out what’s messing us up!
Animation’s should be done on the client because it makes the work flow easier, and it makes more sense to do the client’s visuals on the client.
They (Animations) replicate to the server which replicates to all other peers. Why would harder when you can work smarter.
Yep, I just made that edit.