A KeyframeSequence player

I made a function that plays KeyframeSequences

local function playKeyframes(rig : Model, keyframes : KeyframeSequence)
	local Humanoid = rig:FindFirstChildWhichIsA("Humanoid")
	local Animator = Humanoid.Animator
	
	for i, v in Animator:GetPlayingAnimationTracks() do
		v:Stop()
	end
	
	local offset = {}
	
	local function getMotor6DFromPose(pose : Pose) : Motor6D		
		for i, v in rig:GetDescendants() do
			if v:IsA("Motor6D") and v.Part1.Name == pose.Name and v.Part0.Name == pose.Parent.Name then -- and v.Part0.Name == poseParentName
				return v
			end
		end
	end
	
	local children : {Keyframe}? = keyframes:GetKeyframes()
	
	table.sort(children, function(a, b)
		return a.Time < b.Time
	end)
	
	for nth, keyframe in children do
		local time = 0

		if children[nth + 1] then
			time = children[nth + 1].Time - keyframe.Time
		end

		for _, pose : Pose? in keyframe:GetDescendants() do
			local limb = getMotor6DFromPose(pose)

			if limb and pose.CFrame ~= CFrame.new() then
				offset[limb] = offset[limb] or limb.C0

				local EasingStyle, EasingDirection = 
					Enum.EasingStyle[pose.EasingStyle.Name], 
					Enum.EasingDirection[pose.EasingDirection.Name]

				pcall(function() 
					TweenService:Create(limb, TweenInfo.new(time, EasingStyle, EasingDirection), {C0 = offset[limb] * pose.CFrame}):Play() 
				end)
			end
		end

		wait(time)
	end
	
	for i, v in offset do
		TweenService:Create(i, TweenInfo.new(0.5), {C0 = v}):Play() 
	end
end

Unrelated but if you want to get the Animation Rig type of a keyframe sequence just use this function

local function getAnimationRigType(keyframes : KeyframeSequence)
	local function rigLimbExists(keyframe, rigType)
		local result = Rigs[rigType]:FindFirstChild(keyframe.Name)
		return (result and result.Name ~= "HumanoidRootPart")
	end
	
	for _, keyframe in keyframes:GetDescendants() do
		if rigLimbExists(keyframe, "R6") then
			return "R6"
		elseif rigLimbExists(keyframe, "R15") then
			return "R15"		
		end
	end
end

Feedback will be appreciated

i dont see how this is better, its just manually animating the rig with tweens which is very performance impactful.

Ok Im just gonna name it to a keyframe sequence player

How do I make it less peformanec Impactful

perhaps try doing something other than tweens, like lerping

2 Likes

How is that any more performant?

Is this better @kalabgs

local function playKeyframes(rig : Model, keyframes : KeyframeSequence)
	local offset = {}
	
	local function getMotor6DFromPose(pose : Pose) : Motor6D		
		for i, v in rig:GetDescendants() do
			if v:IsA("Motor6D") and v.Part1.Name == pose.Name and v.Part0.Name == pose.Parent.Name then -- and v.Part0.Name == poseParentName
				return v
			end
		end
	end
	
	local children : {Keyframe}? = keyframes:GetKeyframes()
	
	table.sort(children, function(a, b)
		return a.Time < b.Time
	end)
	
	for nth, keyframe in children do
		local time = 0
		
		if children[nth + 1] then
			time = children[nth + 1].Time - keyframe.Time
		end
		
		for _, pose : Pose? in keyframe:GetDescendants() do
			local limb = getMotor6DFromPose(pose)

			if limb and pose.CFrame ~= CFrame.new() then
				offset[limb] = offset[limb] or limb.C0
				
				local EasingStyle, EasingDirection = 
					Enum.EasingStyle[pose.EasingStyle.Name], 
					Enum.EasingDirection[pose.EasingDirection.Name]

				local ticked = tick()

				spawn(function()
					--transform
					while tick() - ticked < time do
						local cframe = limb.C0

						-- n / time
						limb.C0 = cframe:Lerp(offset[limb] * pose.CFrame, TweenService:GetValue((tick() - ticked) / time, EasingStyle, EasingDirection))
						RunService.PreSimulation:Wait()	
					end

					limb.C0 = offset[limb] * pose.CFrame
				end)
			end
		end
		
		wait(time)
	end
end

it isn’t but its better. There is no way that it can be as performant as animations

I highly doubt there is a difference. They all do the same thing.