I’ve created a function to play Keyframe sequences without needing to convert them to animation.
PlayKeyframeSequence = function(Model, KeyFrameSequence, SpeedMult)
local AllKeyFrames = {}
for i,Keyframe in pairs(KeyFrameSequence:GetKeyframes()) do
table.insert(AllKeyFrames, {
Time = Keyframe.Time,
Keyframe = Keyframe
})
end
table.sort(AllKeyFrames, function(a, b)
return a.Time < b.Time
end)
local KeyFramePoses = {}
local function GetMotorFromPose(Pose, Keyframe)
local FullName = Pose:GetFullName()
local Path = string.split(FullName, ".")
local KFPosition = table.find(Path, Keyframe.Keyframe.Name)
local Motor6D
for i,v in pairs(Model:GetDescendants()) do
if v:IsA("Motor6D") and v.Part1.Name == Pose.Name and v.Part0.Name == Pose.Parent.Name then
Motor6D = v
end
end
return Motor6D
end
for i,Keyframe in pairs(AllKeyFrames) do
for i,Pose in pairs(Keyframe.Keyframe:GetDescendants()) do
if Pose:IsA("Pose") then
if not KeyFramePoses[Pose.Name] then
KeyFramePoses[Pose.Name] = {
Motor6D = nil,
Poses = {},
}
end
local Motor6D = KeyFramePoses[Pose.Name].Motor6D or GetMotorFromPose(Pose, Keyframe)
if not KeyFramePoses[Pose.Name].Motor6D then
KeyFramePoses[Pose.Name].Motor6D = Motor6D
end
if Motor6D then
table.insert(KeyFramePoses[Pose.Name].Poses, {Time = Keyframe.Time, Motor6D = Motor6D, Pose = Pose})
end
end
end
end
local function GetPositionBetween(T1, T2, Pos)
local TimeIn = Pos - T1
local MaxTime = T2 - T1
return TimeIn/MaxTime
end
local TimePassed = 0
local CurrentPoses = {}
local Running = true
local EditedMotor6Ds = {}
local Paused = false
local ForceStopped = false
local SpeedMult = SpeedMult or 1
task.spawn(function()
repeat
Running = false
local Poses = {}
for PoseName, PTB in pairs(KeyFramePoses) do
local Poses = PTB.Poses
if #Poses >= 2 then
local Motor6D = PTB.Motor6D
local PreviousSPT = Poses[1]
local NextSPT = Poses[2]
if NextSPT.Time < TimePassed then
repeat
table.remove(Poses, 1)
PreviousSPT = Poses[1]
NextSPT = Poses[2]
until not NextSPT or NextSPT.Time > TimePassed
end
if NextSPT then
local PositionBetween = GetPositionBetween(PreviousSPT.Time, NextSPT.Time, TimePassed)
local TargetCFrame = PreviousSPT.Pose.CFrame:Lerp(NextSPT.Pose.CFrame, PositionBetween)
Motor6D.Transform = TargetCFrame
if not table.find(EditedMotor6Ds, Motor6D) then
table.insert(EditedMotor6Ds, Motor6D)
end
Running = true
end
end
end
TimePassed += RenderStepped:Wait() * (Paused and 0 or SpeedMult)
until not Running or ForceStopped
for i,v in pairs(EditedMotor6Ds) do
TS:Create(v, TweenInfo.new(0.25, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), {Transform = CF})
end
end)
local function Stop()
ForceStopped = true
end
local function Pause()
Paused = true
end
local function Unpause()
Paused = false
PS: I'd love to hear feedback on any mistakes or unnecessary things in my code!