- Change
keyframes[#keyframes - 1]
tokeyframes[#keyframes]
- You don’t need the remote event. You should run this code on the server and every client will see it!
I think it’s because you were using this: "http://www.roblox.com/asset/?id=4820283660"
. I used this: "rbxassetid://4820283660"
.
I changed that and it still only prints 1 and 2 to the Console.
The code:
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"
print("1")
local success = pcall(function()
print("2")
keyframes = KeyframeSequence:GetKeyframeSequenceAsync(4820283660) -- proper method to retrieve the KeyframeSequence
end)
if success then
keyframeTable = keyframes:GetKeyframes() -- creates a table containing the keyframes
print("3")
local count = 0
for _ in pairs(keyframeTable) do count = count + 1 end -- Iterates through every item and adds 1 to the counter.
print("4")
local lastFrame = keyframes[#keyframes] -- identifies the last frame
print("5")
local marker = Instance.new("KeyframeMarker") -- creates the marker
marker.Name = "ReachedLastFrame"
lastFrame:AddMarker(marker) -- parents the marker to the last keyframe
print("6")
local AnimationTrack = Humanoid:LoadAnimation(Animation) -- Now we load the AnimationTrack after the Marker has been added
print("7")
local function reachedLastFrame()
print("8")
AnimationTrack:AdjustSpeed(0)
print("9")
end
print("10")
local onLastFrame = AnimationTrack:GetMarkerReachedSignal("ReachedLastFrame")
onLastFrame:Connect(reachedLastFrame)
Animation:Play()
end
end
NPCevent.OnClientEvent:Connect(onRemoteFiredFromServer) -- Will call onRemoteFired() when the remote is fired from the server
You should try running my code on the server!
Sorry I’m working with two codes here. It gets very confusing working back and fourth between two people.
Currently this is the main code I’ve been using:
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 = "rbxassetid://4820283660"
print("1")
local success = pcall(function()
print("2")
keyframes = KeyframeSequence:GetKeyframeSequenceAsync(4820283660) -- proper method to retrieve the KeyframeSequence
end)
if success then
keyframeTable = keyframes:GetKeyframes() -- creates a table containing the keyframes
print("3")
local count = 0
for _ in pairs(keyframeTable) do count = count + 1 end -- Iterates through every item and adds 1 to the counter.
print("4")
local lastFrame = keyframes[#keyframes] -- identifies the last frame
print("5")
local marker = Instance.new("KeyframeMarker") -- creates the marker
marker.Name = "ReachedLastFrame"
lastFrame:AddMarker(marker) -- parents the marker to the last keyframe
print("6")
local AnimationTrack = Humanoid:LoadAnimation(Animation) -- Now we load the AnimationTrack after the Marker has been added
print("7")
local function reachedLastFrame()
print("8")
AnimationTrack:AdjustSpeed(0)
print("9")
end
print("10")
local onLastFrame = AnimationTrack:GetMarkerReachedSignal("ReachedLastFrame")
onLastFrame:Connect(reachedLastFrame)
Animation:Play()
end
end
NPCevent.OnClientEvent:Connect(onRemoteFiredFromServer) -- Will call onRemoteFired() when the remote is fired from the server
EDIT: I did multiple changes with statements you guys made above with the code. Still only prints in the Console 1 and 2.
Did my code work?
[30 characters]
So, how’s it going?
[30 characters]
Haven’t tried it yet, but I guess I’ll do it now. I gotta save @Spraden’s code for the time being to test yours.
Doesn’t work. The animation runs, but doesn’t stop on the final frame like it’s supposed to.
Your updated code:
local NPCevent = game:GetService("ReplicatedStorage"):WaitForChild("NPCevent")
local Character = game.Workspace.RobertJr_YT
local Humanoid = Character.Humanoid or Character:WaitForChild("Humanoid")
local KeyframeSequence = game:GetService("KeyframeSequenceProvider")
local function onRemoteFiredFromServer() -- Call this function when you want to play the animation
local Animation = Instance.new("Animation")
Animation.AnimationId = "rbxassetid://4820283660"
local success, err = pcall(function()
keyframeSequence = KeyframeSequence:GetKeyframeSequenceAsync(Animation.AnimationId)
end)
if success then
local keyframes = keyframeSequence:GetKeyframes()
local lastFrame = keyframes[#keyframes]
local marker = Instance.new("KeyframeMarker"); marker.Name = "ReachedLastFrame"
lastFrame:AddMarker(marker)
local animTrack = Humanoid:LoadAnimation(Animation)
animTrack:GetMarkerReachedSignal("ReachedLastFrame"):Connect(function()
animTrack:AdjustSpeed(0)
end)
animTrack:Play()
end
end
NPCevent.OnClientEvent:Connect(onRemoteFiredFromServer) -- Will call onRemoteFired() when the remote is fired from the server
I found some weird documentation… this got a hell of a lot more complicated!
local NPCevent = game:GetService("ReplicatedStorage"):WaitForChild("NPCevent")
local Character = workspace:WaitForChild("RobertJr_YT")
local Humanoid = Character.Humanoid or Character:WaitForChild("Humanoid")
local KeyframeSequence = game:GetService("KeyframeSequenceProvider")
local function onRemoteFiredFromServer()
local Animation = Instance.new("Animation")
Animation.AnimationId = "rbxassetid://4820283660"
keyframeSequence = KeyframeSequence:GetKeyframeSequenceAsync(Animation.AnimationId)
local newKeyframeSequence = Instance.new("KeyframeSequence"); keyframeSequence.Loop = false; keyframeSequence.Priority = Enum.AnimationPriority.Action
local keyframes = {}
for _, keyframe in pairs(keyframeSequence:GetKeyframes()) do
table.insert(keyframes, #keyframes + 1, keyframe)
newKeyframeSequence:AddKeyframe(keyframe)
end
lastframe = keyframes[#keyframes]
local marker = Instance.new("KeyframeMarker"); marker.Name = "ReachedLastFrame"
lastframe:AddMarker(marker)
local hashId = KeyframeSequenceProvider:RegisterKeyframeSequence(newKeyframeSequence)
if hashId then
local newAnimation = Instance.new("Animation")
newAnimation.AnimationId = hashId
local newAnimationTrack = Humanoid:LoadAnimation(newAnimation)
newAnimationTrack:GetMarkerReachedSignal("ReachedLastFrame"):Connect(function()
newAnimationTrack:AdjustSpeed(0)
end)
newAnimationTrack:Play()
end
end
NPCevent.OnClientEvent:Connect(onRemoteFiredFromServer)
Jeez. So in the Keyframe documentation I found you can create a temporary animation. Using this we are able to edit the keyframes then place them inside a new KeyframeSequence which can generate a HashId
for an animation that is only locally accessible and not published to Roblox. We can then use that new animation to load onto the NPC.
local Character = game.Workspace.RobertJr_YT
local Humanoid = Character.Humanoid or Character:WaitForChild("Humanoid")
local stopTime = 0.1 -- The amount of time to be subtracted from the animation before freezing
local function playAnimation() -- Call this function when you want to play the animation
local Animation = Instance.new("Animation")
Animation.AnimationId = "rbxassetid://4820283660"
local animTrack = Humanoid:LoadAnimation(Animation)
local animLength = animTrack.Length
animTrack:Play()
wait(animLength - stopTime)
animTrack:AdjustSpeed(0)
end
playAnimation()
Yet again with this solution, it does run the animation, but still teleports back to the start. I had to edit some things in the script though to make some underlined words go away.
Code:
local NPCevent = game:GetService("ReplicatedStorage"):WaitForChild("NPCevent")
local Character = workspace:WaitForChild("RobertJr_YT")
local Humanoid = Character.Humanoid or Character:WaitForChild("Humanoid")
local KeyframeSequenceProvider = game:GetService("KeyframeSequenceProvider")
local function onRemoteFiredFromServer()
local Animation = Instance.new("Animation")
Animation.AnimationId = "rbxassetid://4820283660"
local KeyframeSequence = KeyframeSequenceProvider:GetKeyframeSequenceAsync(Animation.AnimationId)
local newKeyframeSequence = Instance.new("KeyframeSequence"); KeyframeSequence.Loop = false; KeyframeSequence.Priority = Enum.AnimationPriority.Action
local keyframes = {}
for _, keyframe in pairs(KeyframeSequence:GetKeyframes()) do
table.insert(keyframes, #keyframes + 1, keyframe)
newKeyframeSequence:AddKeyframe(keyframe)
end
local lastframe = keyframes[#keyframes]
local marker = Instance.new("KeyframeMarker"); marker.Name = "ReachedLastFrame"
lastframe:AddMarker(marker)
local hashId = KeyframeSequenceProvider:RegisterKeyframeSequence(newKeyframeSequence)
if hashId then
local newAnimation = Instance.new("Animation")
newAnimation.AnimationId = hashId
local newAnimationTrack = Humanoid:LoadAnimation(newAnimation)
newAnimationTrack:GetMarkerReachedSignal("ReachedLastFrame"):Connect(function()
newAnimationTrack:AdjustSpeed(0)
end)
newAnimationTrack:Play()
end
end
NPCevent.OnClientEvent:Connect(onRemoteFiredFromServer)
I still don’t understand why a remote event is necessary. Can you explain?
Now especially it is a must. You can’t create or use a HashId for an animation on the server.
Honestly, I’m really happy that it played the animation first go. Add a print() to the function connected to GetMarkerReachedSignal()
so we can see if the function is ran.
It works, however like I said again it stops too soon.
Then change the stopTime
variable to a lower value.
Did it work for you?
[30 characters]