Struggling with a particular Animation problem

Alright take your time, you’ve been more than helpful to me so far.

I’ll do an attempt to sort out the problem, but I’m afraid I’ll screw something up at this point.

1 Like

Let me see if I can write some code for this, give me a sec.

1 Like

Put in some print()s so I can see where the code just breaks off.

1 Like

The animation isn’t even playing :rofl:
Add Animation:Play() at the end.

1 Like

Alright here it is.

Output: image

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(Animation) -- 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 = keyframeTable[count] -- 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

& there is no error. It only printed 1 and 2, which is odd.

GetKeyframeSequenceAsync() is a webcall method. It must be the Animation’s ID set as the parameter, I believe.

keyframes = KeyframeSequence:GetKeyframeSequenceAsync(AnimationId)

Hopefully that gets us farther down the code!

1 Like

Nope. Same effect, it outputted 1 and 2 again.

Try this.

Code (on the client):

local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character.Humanoid or Character:WaitForChild("Humanoid")
local KeyframeSequence = game:GetService("KeyframeSequenceProvider")

local function playAnimation() -- Call this function when you want to play the animation
    local Animation = Instance.new("Animation")
    Animation.AnimationId = "http://www.roblox.com/asset/?id=4820283660"

    local success = pcall(function()
        keyframeSequence = KeyframeSequence:GetKeyframeSequenceAsync(Animation) 
    end)

    if success then
        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

playAnimation()
1 Like

I saved the code I was using with @Spraden just in-case your code doesn’t work. I had to do some modifications to the code since the final end was underlined. Another thing is

keyframes = keyframeSequence:GetKeyframes() 

“keyframes” in the code above was underlined too in red.

Modified version of code:

local Character = game.Workspace.RobertJr_YT
local Humanoid = Character.Humanoid or Character:WaitForChild("Humanoid")
local KeyframeSequence = game:GetService("KeyframeSequenceProvider")

local function playAnimation() -- Call this function when you want to play the animation
    local Animation = Instance.new("Animation")
    Animation.AnimationId = "http://www.roblox.com/asset/?id=4820283660"

    local success = pcall(function()
        keyframeSequence = KeyframeSequence:GetKeyframeSequenceAsync(Animation) 
    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()

		playAnimation()
    end
end

EDIT: There is no output.
EDIT2: Even when moving “playAnimation()” to the very bottom to where it was before, there still is no output.

Ohhh! You want to play an animation on an NPC! Lemme write some code for that.

1 Like

Good thing I saved @Spraden 's code just in-case.

His code is basically what I have done—though it animates the player, and it’s cleaned up (His looks much nicer admittedly). This is very odd to work on as there is no documentation on inserting Markers and then connecting them to a function. It is possible to create Markers in the animation editor, then rename one on the last frame to “ReachedLastFrame”. That would drastically reduce the code and simplify just about everything.

You wouldn’t have to search through the KeyframeSequence to find the last frame, you wouldn’t have to add the marker to the frame, etc… You’d simply play the animation as you normally would then use the GetMarkerReachedSignal() method.

animTrack:GetMarkerReachedSignal("ReachedLastFrame"):Connect(function()
    animTrack:AdjustSpeed(0)
end)

But damn do I wanna figure this out. I’ve been stumped on this for hours… and it’s getting to me! :joy:

I have been through so many pages trying to find proper documentation for being able to reference the KeyframeSequence. Maybe we have to clone the original from the animation, then add the marker to the last keyframe, then turn the new KeyframeSequence into an animation track.

Whatever the answer is, it better be out there. I hope I find it

Edit: Here’s how to do it in the animation editor

1 Like

You probably are one of the most helpful person I’ve interacted with on the forum. Going all this way just to a person you don’t know I find very respectful and kind of you. Especially constantly trying to find a solution for me. I almost feel bad for myself to be honest, too bad I don’t have much coding experience myself.

like I said before, take your time if you still have the desire. I’ll be working on some other things for the game in the meantime.

Alright. Make sure to take into account what @Spraden said in the post above.

I think I figured it out!

Try this code:

local Character = game.Workspace.RobertJr_YT
local Humanoid = Character.Humanoid or Character:WaitForChild("Humanoid")
local KeyframeSequence = game:GetService("KeyframeSequenceProvider")

local function playAnimation() -- 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 - 1]

        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

playAnimation()

It worked for one of my animations, so let me know if you have any issues.

2 things with this script. 1, It stops the animation a little too soon. 2, It doesn’t work to be connected with the event from before. I tried changing it to work with the RemoteEvent, but I ended up screwing the script up anyway.

1 Like

Can you explain exactly what you’ve changed por favor? It looks like you added , err to the pcall function and set the last frame to be one minus #keyframes.

Did the , err end up actually getting you through that block of code? @RobertJr_YT

Edit: It seems it did work! Nice job @xBearByte.

Robert you should be able to use #keyframes instead of #keyframes - 1, that is most likely why your animation is stopping short.

Change

local lastFrame = keyframes[#keyframes - 1]
to
local lastFrame = keyframes[#keyframes]

It was the KeyframeSequence:GetKeyframeSequenceAsync() function call. The parameter is the animation’s id not the animation itself.

We did that before, just calling the ID. I wonder why it didn’t work then