KSP_Track

Run Settings
LanguageLua
Language Version
Run Command
local TweenService = game:GetService("TweenService") local Signal = {} Signal.__index = Signal -- Constructor function Signal.new() return setmetatable({ _bindable = Instance.new("BindableEvent"), _args = nil, _argCount = nil, },Signal) end function Signal:Fire(...) self._args = {...} self._argCount = select("#", ...) self._bindable:Fire() end function Signal:fire(...) return self:Fire(...) end function Signal:Connect(handler) if not (type(handler) == "function") then error(("connect(%s)"):format(typeof(handler)), 2) end return self._bindable.Event:Connect(function() handler(unpack(self._args or {})) end) end function Signal:connect(...) return self:Connect(...) end function Signal:Wait() self._bindableEvent.Event:Wait() assert(self._argData, "Missing argument data, likely due to :TweenSize/Position corrupting.") return unpack(self._args, 1, self._argCount) end function Signal:wait() return self:Wait() end function Signal:Destroy() if self._bindable then self._bindable:Destroy() self._bindable = nil end self._args = nil self._argCount = nil setmetatable(self, nil) end function Signal:destroy() return self:Destroy() end local Track = {} Track.__index = Track function Track.new(Animator : any, Transform : any, Character : Model, Sequence : KeyframeSequence) local NewTrack = setmetatable({}, Track) local TransformAmount = 0 NewTrack.Animator = Animator NewTrack.KeyframeReached = Signal.new() NewTrack.OnFinished = Signal.new() NewTrack.Playing = false NewTrack.Looped = Sequence.Loop NewTrack.Smooth = false NewTrack.FiredEvent = false NewTrack.Speed = 1 NewTrack.Character = Character NewTrack.Finished = 0 for _ in Transform do TransformAmount += 1 end NewTrack.TransformAmount = TransformAmount NewTrack.Transform = Transform local SequenceSorted = {} for _, Object in Sequence:GetChildren() do if Object:IsA("Keyframe") then table.insert(SequenceSorted, Object) end end table.sort(SequenceSorted, function(A, B) return A.Time < B.Time end) NewTrack.Keyframes = SequenceSorted return NewTrack end function Track:AdjustSpeed(Value : number) self.Speed = Value end function Track:Play(speed: number?) if self.Playing then return end if speed then assert(typeof(speed) == "number","Speed parameter must be a number") end self.Finished = 0 self.Speed = speed or 1 self.Playing = true end function Track:Reset() for Part1, Motor in self.Transform do Motor.Index = 1 Motor.Skip = 1 Motor.Done = false Motor.Alpha = 0 end end function Track:Stop() if not self.Playing then return end self.Finished = 0 self.Playing = false self:Reset() end function Track:IsFinished() return self.Finished >= self.TransformAmount end function Track:_update(DeltaTime : number) if self.Playing then for _,Motor in self.Transform do if Motor.Object:IsA("Weld") and not Motor.Object.Enabled then Motor.Object.Enabled = true end end else for _,Motor in self.Transform do if Motor.Object:IsA("Weld") and Motor.Object.Enabled then Motor.Object.Enabled = false end end end if not self.Playing then return end local Keyframes = self.Keyframes self.FiredEvent = false for Name, Motor in self.Transform do if Motor.Done then continue end local CurrentKeyframe = Keyframes[Motor.Index] local NextKeyframe = Keyframes[Motor.Index + Motor.Skip] if not NextKeyframe then continue end local CurrentPose = CurrentKeyframe:FindFirstChild(Name, true) if not CurrentPose then continue end local NextPose = NextKeyframe:FindFirstChild(Name, true) if not NextPose then Motor.Skip += 1 continue end Motor.Skip = 1 Motor.Alpha += DeltaTime * self.Speed local Alpha = Motor.Alpha / (NextKeyframe.Time - CurrentKeyframe.Time) if Alpha >= 1 then if not self.FiredEvent then self.KeyframeReached:Fire(NextKeyframe.Name,Motor.Index + Motor.Skip) self.FiredEvent = true end Motor.Alpha = 0 Motor.Index += 1 if Motor.Index >= #Keyframes - 1 then self.Finished += 1 Motor.Done = true end end local TweenedAlpha = TweenService:GetValue( math.clamp(Alpha, 0, 1), Enum.EasingStyle[CurrentPose.EasingStyle.Name], Enum.EasingDirection[CurrentPose.EasingDirection.Name] ) if Motor.Object:IsA("Weld") then Motor.Object.C0 = (Motor.Default * CurrentPose.CFrame):Lerp(Motor.Default * NextPose.CFrame, TweenedAlpha) else if self.Smooth then Motor.Object.CFrame = Motor.Object.CFrame:Lerp((Motor.Default * CurrentPose.CFrame):Lerp(Motor.Default * NextPose.CFrame, TweenedAlpha),10 * DeltaTime) else Motor.Object.CFrame = (Motor.Default * CurrentPose.CFrame):Lerp(Motor.Default * NextPose.CFrame, TweenedAlpha) end end end if self:IsFinished() then self.OnFinished:Fire() if self.Looped then self.Finished = 0 self:Reset() else self:Stop() end end end return Track
Editor Settings
Theme
Key bindings
Full width
Lines