Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- cloneref = type(cloneref) == "function" and cloneref or function(...) return ... end
- local CoreGui = cloneref(game:GetService("CoreGui"))
- local Players = cloneref(game:GetService("Players"))
- local RunService = cloneref(game:GetService("RunService"))
- local UserInputService = cloneref(game:GetService("UserInputService"))
- if CoreGui:FindFirstChild("AnimationManager") then
- CoreGui.AnimationManager:Destroy()
- end
- local Gui = Instance.new("ScreenGui")
- Gui.Name = "AnimationManager"
- Gui.ZIndexBehavior = Enum.ZIndexBehavior.Global
- Gui.IgnoreGuiInset = true
- Gui.Parent = CoreGui
- local function New(class, props, children)
- local o = Instance.new(class)
- if props then
- for k, v in pairs(props) do
- o[k] = v
- end
- end
- if children then
- for _, c in ipairs(children) do
- c.Parent = o
- end
- end
- return o
- end
- local function MakeButton(text, size)
- local b = New("TextButton", {
- Size = size or UDim2.new(0, 150, 0, 36),
- BackgroundColor3 = Color3.fromRGB(40, 40, 40),
- Text = text,
- Font = Enum.Font.GothamBold,
- TextSize = 14,
- TextColor3 = Color3.fromRGB(235, 235, 235),
- AutoButtonColor = false
- })
- New("UICorner", { CornerRadius = UDim.new(0, 6), Parent = b })
- New("UIStroke", { Thickness = 1, Color = Color3.fromRGB(70, 70, 70), Parent = b })
- return b
- end
- local function MakeInput(placeholder, size)
- local tb = New("TextBox", {
- Size = size or UDim2.new(0, 306, 0, 36),
- BackgroundColor3 = Color3.fromRGB(25, 25, 25),
- PlaceholderText = placeholder,
- Font = Enum.Font.Gotham,
- TextSize = 14,
- TextColor3 = Color3.fromRGB(235, 235, 235),
- BorderSizePixel = 0,
- ClearTextOnFocus = false
- })
- New("UICorner", { CornerRadius = UDim.new(0, 6), Parent = tb })
- New("UIStroke", { Thickness = 1, Color = Color3.fromRGB(70, 70, 70), Parent = tb })
- return tb
- end
- local function MakeSlider(labelText, minValue, maxValue, defaultValue, width)
- local holder = New("Frame", {
- Size = UDim2.new(0, width or 306, 0, 38),
- BackgroundColor3 = Color3.fromRGB(24, 24, 24),
- BackgroundTransparency = 0.25,
- BorderSizePixel = 0
- })
- New("UICorner", { CornerRadius = UDim.new(0, 6), Parent = holder })
- New("UIStroke", { Thickness = 1, Color = Color3.fromRGB(60, 60, 60), Parent = holder })
- local label = New("TextLabel", {
- BackgroundTransparency = 1,
- Text = labelText .. ": " .. string.format("%.2f", defaultValue),
- Font = Enum.Font.Gotham,
- TextSize = 12,
- TextColor3 = Color3.fromRGB(220, 220, 220),
- TextXAlignment = Enum.TextXAlignment.Left,
- Size = UDim2.new(1, -16, 0, 16),
- Position = UDim2.new(0, 8, 0, 4)
- })
- label.Parent = holder
- local bar = New("Frame", {
- BackgroundColor3 = Color3.fromRGB(40, 40, 40),
- BorderSizePixel = 0,
- Size = UDim2.new(1, -16, 0, 12),
- Position = UDim2.new(0, 8, 0, 22)
- })
- bar.Parent = holder
- New("UICorner", { CornerRadius = UDim.new(0, 6), Parent = bar })
- local fill = New("Frame", {
- BackgroundColor3 = Color3.fromRGB(90, 140, 90),
- BorderSizePixel = 0,
- Size = UDim2.new((defaultValue - minValue) / (maxValue - minValue), 0, 1, 0)
- })
- fill.Parent = bar
- New("UICorner", { CornerRadius = UDim.new(0, 6), Parent = fill })
- local value = defaultValue
- local dragging = false
- bar.InputBegan:Connect(function(i)
- if i.UserInputType == Enum.UserInputType.MouseButton1 then
- dragging = true
- end
- end)
- bar.InputEnded:Connect(function(i)
- if i.UserInputType == Enum.UserInputType.MouseButton1 then
- dragging = false
- end
- end)
- bar.InputChanged:Connect(function(i)
- if dragging and i.UserInputType == Enum.UserInputType.MouseMovement then
- local total = bar.AbsoluteSize.X
- local px = math.clamp(i.Position.X - bar.AbsolutePosition.X, 0, total)
- local alpha = total > 0 and (px / total) or 0
- value = minValue + alpha * (maxValue - minValue)
- fill.Size = UDim2.new(alpha, 0, 1, 0)
- label.Text = labelText .. ": " .. string.format("%.2f", value)
- end
- end)
- local function get()
- return value
- end
- local function set(x)
- local alpha = math.clamp((x - minValue) / (maxValue - minValue), 0, 1)
- value = x
- fill.Size = UDim2.new(alpha, 0, 1, 0)
- label.Text = labelText .. ": " .. string.format("%.2f", value)
- end
- return holder, get, set
- end
- local Root = New("Frame", {
- Name = "Root",
- Size = UDim2.new(0, 900, 0, 600),
- Position = UDim2.new(0.5, -450, 0.5, -300),
- BackgroundColor3 = Color3.fromRGB(15, 15, 15),
- Parent = Gui
- })
- local Header = New("Frame", {
- Name = "Header",
- Size = UDim2.new(1, 0, 0, 40),
- BackgroundColor3 = Color3.fromRGB(20, 20, 20),
- Parent = Root
- })
- local Title = New("TextLabel", {
- Text = "Animation Manager",
- Size = UDim2.new(1, -120, 1, 0),
- Position = UDim2.new(0, 10, 0, 0),
- BackgroundTransparency = 1,
- Font = Enum.Font.GothamBold,
- TextSize = 18,
- TextColor3 = Color3.fromRGB(240, 240, 240),
- TextXAlignment = Enum.TextXAlignment.Left,
- Parent = Header
- })
- local MinBtn = MakeButton("-", UDim2.new(0, 32, 0, 24))
- MinBtn.Position = UDim2.new(1, -74, 0, 8)
- MinBtn.Parent = Header
- local CloseBtn = MakeButton("X", UDim2.new(0, 32, 0, 24))
- CloseBtn.Position = UDim2.new(1, -38, 0, 8)
- CloseBtn.Parent = Header
- local Dragging = false
- local DragStart = nil
- local RootStart = nil
- local Minimized = false
- local StoredSize = Root.Size
- local StoredPos = Root.Position
- Header.InputBegan:Connect(function(i)
- if i.UserInputType == Enum.UserInputType.MouseButton1 then
- Dragging = true
- DragStart = i.Position
- RootStart = Root.Position
- end
- end)
- Header.InputChanged:Connect(function(i)
- if Dragging and i.UserInputType == Enum.UserInputType.MouseMovement then
- local d = i.Position - DragStart
- Root.Position = UDim2.new(RootStart.X.Scale, RootStart.X.Offset + d.X, RootStart.Y.Scale, RootStart.Y.Offset + d.Y)
- end
- end)
- Header.InputEnded:Connect(function(i)
- if i.UserInputType == Enum.UserInputType.MouseButton1 then
- Dragging = false
- end
- end)
- CloseBtn.MouseButton1Click:Connect(function()
- Gui:Destroy()
- end)
- local Body = New("Frame", {
- Name = "Body",
- Size = UDim2.new(1, 0, 1, -40),
- Position = UDim2.new(0, 0, 0, 40),
- BackgroundTransparency = 1,
- Parent = Root
- })
- MinBtn.MouseButton1Click:Connect(function()
- Minimized = not Minimized
- if Minimized then
- StoredSize = Root.Size
- StoredPos = Root.Position
- Root.Size = UDim2.new(0, 360, 0, 40)
- Body.Visible = false
- else
- Root.Size = StoredSize
- Root.Position = StoredPos
- Body.Visible = true
- end
- end)
- local LeftPane = New("Frame", {
- Name = "LeftPane",
- Size = UDim2.new(0.42, 0, 1, 0),
- BackgroundTransparency = 1,
- Parent = Body
- })
- local RightPane = New("Frame", {
- Name = "RightPane",
- Size = UDim2.new(0.58, 0, 1, 0),
- Position = UDim2.new(0.42, 0, 0, 0),
- BackgroundTransparency = 1,
- Parent = Body
- })
- local TopBarLeft = New("Frame", {
- Name = "TopBarLeft",
- Size = UDim2.new(1, -12, 0, 36),
- Position = UDim2.new(0, 6, 0, 6),
- BackgroundTransparency = 1,
- Parent = LeftPane
- })
- local SearchBar = MakeInput("Filter by name or ID", UDim2.new(1, 0, 1, 0))
- SearchBar.Parent = TopBarLeft
- local AnimLogger = New("ScrollingFrame", {
- Name = "AnimLogger",
- Size = UDim2.new(1, -12, 1, -56),
- Position = UDim2.new(0, 6, 0, 50),
- BackgroundColor3 = Color3.fromRGB(12, 12, 12),
- BackgroundTransparency = 0.15,
- ScrollBarThickness = 8,
- ScrollingDirection = Enum.ScrollingDirection.Y,
- CanvasSize = UDim2.new(0, 0, 0, 0),
- Active = true,
- Parent = LeftPane
- })
- local AnimLoggerLayout = New("UIListLayout", {
- Padding = UDim.new(0, 6),
- SortOrder = Enum.SortOrder.LayoutOrder,
- Parent = AnimLogger
- })
- local TopBarRight = New("Frame", {
- Name = "TopBarRight",
- Size = UDim2.new(1, -12, 0, 36),
- Position = UDim2.new(0, 6, 0, 6),
- BackgroundTransparency = 1,
- Parent = RightPane
- })
- local AnimIdInput = MakeInput("numeric or rbxassetid://", UDim2.new(1, 0, 1, 0))
- AnimIdInput.Parent = TopBarRight
- local PreviewContainer = New("Frame", {
- Name = "PreviewContainer",
- BackgroundColor3 = Color3.fromRGB(16, 16, 16),
- BackgroundTransparency = 0.15,
- BorderSizePixel = 0,
- Size = UDim2.new(1, -12, 0.48, -50),
- Position = UDim2.new(0, 6, 0, 50),
- Parent = RightPane
- })
- local Viewport = New("ViewportFrame", {
- Name = "Viewport",
- BackgroundColor3 = Color3.fromRGB(8, 8, 8),
- BackgroundTransparency = 0.2,
- BorderSizePixel = 0,
- Size = UDim2.new(1, 0, 1, 0),
- Active = true,
- Parent = PreviewContainer
- })
- local Camera = New("Camera", { Parent = Viewport })
- Viewport.CurrentCamera = Camera
- local RotateBtn = MakeButton("🔁", UDim2.new(0, 28, 0, 22))
- RotateBtn.Position = UDim2.new(1, -34, 0, 6)
- RotateBtn.Parent = PreviewContainer
- local AutoRotate = false
- RotateBtn.MouseButton1Click:Connect(function()
- AutoRotate = not AutoRotate
- RotateBtn.Text = AutoRotate and "⏸" or "🔁"
- end)
- local ResizeHandle = New("Frame", {
- Name = "ResizeHandle",
- Size = UDim2.new(0, 16, 0, 16),
- AnchorPoint = Vector2.new(1, 1),
- Position = UDim2.new(1, 0, 1, 0),
- BackgroundColor3 = Color3.fromRGB(180, 180, 180),
- BackgroundTransparency = 0.3,
- BorderSizePixel = 0,
- Parent = Root
- })
- New("UICorner", { CornerRadius = UDim.new(0, 3), Parent = ResizeHandle })
- local resizing = false
- local resizeStartPos = nil
- local resizeStartSize = nil
- ResizeHandle.InputBegan:Connect(function(input)
- if input.UserInputType == Enum.UserInputType.MouseButton1 then
- resizing = true
- resizeStartPos = UserInputService:GetMouseLocation()
- resizeStartSize = Root.Size
- end
- end)
- UserInputService.InputEnded:Connect(function(input)
- if input.UserInputType == Enum.UserInputType.MouseButton1 then
- resizing = false
- end
- end)
- UserInputService.InputChanged:Connect(function(input)
- if resizing and input.UserInputType == Enum.UserInputType.MouseMovement then
- local delta = UserInputService:GetMouseLocation() - resizeStartPos
- Root.Size = UDim2.new(
- resizeStartSize.X.Scale, math.max(600, resizeStartSize.X.Offset + delta.X),
- resizeStartSize.Y.Scale, math.max(380, resizeStartSize.Y.Offset + delta.Y)
- )
- end
- end)
- local MenuPanel = New("Frame", {
- Name = "MenuPanel",
- BackgroundColor3 = Color3.fromRGB(16, 16, 16),
- BackgroundTransparency = 0.15,
- BorderSizePixel = 0,
- AnchorPoint = Vector2.new(0, 1),
- Position = UDim2.new(0, 6, 1, -6),
- Size = UDim2.new(1, -12, 0.48, -6),
- Active = true,
- Parent = RightPane
- })
- local MenuScroll = New("ScrollingFrame", {
- Name = "MenuScroll",
- BackgroundTransparency = 1,
- Size = UDim2.new(1, 0, 1, 0),
- ScrollBarThickness = 8,
- ScrollingDirection = Enum.ScrollingDirection.Y,
- CanvasSize = UDim2.new(0, 0, 0, 0),
- Parent = MenuPanel
- })
- local MenuGrid = New("UIGridLayout", {
- CellSize = UDim2.new(0, 150, 0, 36),
- CellPadding = UDim2.new(0, 6, 0, 6),
- FillDirection = Enum.FillDirection.Horizontal,
- SortOrder = Enum.SortOrder.LayoutOrder,
- Parent = MenuScroll
- })
- MenuGrid:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function()
- MenuScroll.CanvasSize = UDim2.new(0, 0, 0, MenuGrid.AbsoluteContentSize.Y + 12)
- end)
- local PlayBtn = MakeButton("Play")
- PlayBtn.Parent = MenuScroll
- local StopBtn = MakeButton("Stop")
- StopBtn.Parent = MenuScroll
- local ResumeBtn = MakeButton("Resume")
- ResumeBtn.Parent = MenuScroll
- local FreezeBtn = MakeButton("Freeze")
- FreezeBtn.Parent = MenuScroll
- local UnfreezeBtn = MakeButton("Unfreeze")
- UnfreezeBtn.Parent = MenuScroll
- local SpeedSlider, SpeedGet, SpeedSet = MakeSlider("Speed", 0.1, 5.0, 1.0, 306)
- SpeedSlider.Parent = MenuScroll
- local WeightSlider, WeightGet, WeightSet = MakeSlider("Weight", 0, 1, 1, 306)
- WeightSlider.Parent = MenuScroll
- local BlendSlider, BlendGet, BlendSet = MakeSlider("Blend", 0, 1, 0.5, 306)
- BlendSlider.Parent = MenuScroll
- local PlayCFrameBtn = MakeButton("Play CFrame")
- PlayCFrameBtn.Parent = MenuScroll
- local StopCFrameBtn = MakeButton("Stop CFrame")
- StopCFrameBtn.Parent = MenuScroll
- local ResumeCFrameBtn = MakeButton("Resume CFrame")
- ResumeCFrameBtn.Parent = MenuScroll
- local SyncToggleBtn = MakeButton("Sync Preview: OFF")
- SyncToggleBtn.Parent = MenuScroll
- local ModeToggleBtn = MakeButton("Mode: Preview")
- ModeToggleBtn.Parent = MenuScroll
- local QuickPlayBtn = MakeButton("Quick Play Latest")
- QuickPlayBtn.Parent = MenuScroll
- local QuickCFrameBtn = MakeButton("Quick CFrame Latest")
- QuickCFrameBtn.Parent = MenuScroll
- local SaveTableBtn = MakeButton("Save Table")
- SaveTableBtn.Parent = MenuScroll
- local SaveAllBtn = MakeButton("Save All")
- SaveAllBtn.Parent = MenuScroll
- local ClearListBtn = MakeButton("Clear List")
- ClearListBtn.Parent = MenuScroll
- local CopyIdBtn = MakeButton("Copy ID")
- CopyIdBtn.Parent = MenuScroll
- local InjectBtn = MakeButton("Inject Manual")
- InjectBtn.Parent = MenuScroll
- local AlignBtn = MakeButton("Align Preview")
- AlignBtn.Parent = MenuScroll
- local ReloadBtn = MakeButton("Reload Preview")
- ReloadBtn.Parent = MenuScroll
- local BatchSaveBtn = MakeButton("Batch Save")
- BatchSaveBtn.Parent = MenuScroll
- local DedupToggleBtn = MakeButton("Dedup: OFF")
- DedupToggleBtn.Parent = MenuScroll
- local TablePlayBtn = MakeButton("Play Table")
- TablePlayBtn.Parent = MenuScroll
- local TableLoadBtn = MakeButton("Load Table")
- TableLoadBtn.Parent = MenuScroll
- local function EnsureFolder(name)
- if isfolder and not isfolder(name) then
- if makefolder then
- makefolder(name)
- end
- end
- end
- local function normalizeId(input)
- if typeof(input) == "number" then
- return "rbxassetid://" .. tostring(input)
- end
- if typeof(input) == "string" then
- local num = input:match("%d+")
- if num then
- return "rbxassetid://" .. num
- end
- end
- return nil
- end
- local function GetObject(input)
- local assetId = normalizeId(input)
- if not assetId then
- return nil
- end
- local ok, obj = pcall(function()
- return game:GetObjects(assetId)[1]
- end)
- if not ok or not obj then
- return nil
- end
- if obj:IsA("KeyframeSequence") then
- local kfs = obj:GetKeyframes()
- table.sort(kfs, function(a, b)
- return a.Time < b.Time
- end)
- local frames = {}
- for _, kf in ipairs(kfs) do
- local data = {}
- for _, pose in ipairs(kf:GetDescendants()) do
- if pose:IsA("Pose") then
- data[pose.Name] = pose.CFrame
- end
- end
- table.insert(frames, { Time = kf.Time, Data = data })
- end
- return frames
- end
- return nil
- end
- local function ExportFrames(frames, id, animName)
- EnsureFolder("AnimExports")
- local key = animName or tostring(id):match("%d+") or "Animation"
- local s = "return {\n"
- s = s .. " [\"" .. key .. "\"] = {\n"
- for _, f in ipairs(frames) do
- s = s .. " { Time = " .. string.format("%.3f", f.Time) .. ", Data = {\n"
- for part, cf in pairs(f.Data) do
- local c = { cf:GetComponents() }
- s = s .. " [\"" .. part .. "\"] = CFrame.new(" .. table.concat(c, ", ") .. "),\n"
- end
- s = s .. " }},\n"
- end
- s = s .. " }\n"
- s = s .. "}"
- local file = tostring(id):match("%d+")
- if file and writefile then
- local path = "AnimExports/" .. file .. ".lua"
- if isfile and isfile(path) and delfile then
- delfile(path)
- end
- writefile(path, s)
- end
- end
- local Blacklist = {
- ["507766666"] = true,
- ["507766951"] = true,
- ["507767714"] = true,
- ["507767968"] = true,
- ["507768375"] = true,
- ["507768133"] = true,
- ["507767999"] = true,
- ["507766388"] = true,
- ["507771019"] = true,
- ["507771955"] = true
- }
- local LocalPlayer = Players.LocalPlayer
- local Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()
- local Humanoid = Character:FindFirstChildOfClass("Humanoid") or Character:WaitForChild("Humanoid")
- local RotY = 0
- local RotX = -0.2
- local Dist = 14
- local PreviewModel = nil
- local PreviewHumanoid = nil
- local PreviewAnimator = nil
- local PreviewTrack = nil
- local ActiveCharTrack = nil
- local UseCharacter = false
- local SyncEnabled = false
- local DedupEnabled = false
- local function BuildPreview()
- if PreviewModel then
- PreviewModel:Destroy()
- end
- PreviewModel = Instance.new("Model")
- PreviewModel.Name = "PreviewModel"
- PreviewModel.Parent = Viewport
- for _, d in ipairs(Character:GetDescendants()) do
- if d:IsA("BasePart") or d:IsA("MeshPart") or d:IsA("Motor6D") or d:IsA("Humanoid") then
- local c = d:Clone()
- c.Parent = PreviewModel
- end
- end
- local hrp = PreviewModel:FindFirstChild("HumanoidRootPart") or PreviewModel:FindFirstChildWhichIsA("BasePart")
- if hrp then
- PreviewModel.PrimaryPart = hrp
- end
- if PreviewModel.PrimaryPart then
- PreviewModel:SetPrimaryPartCFrame(CFrame.new(0, 6, 0))
- end
- PreviewHumanoid = PreviewModel:FindFirstChildOfClass("Humanoid")
- if PreviewHumanoid then
- PreviewAnimator = PreviewHumanoid:FindFirstChildOfClass("Animator") or Instance.new("Animator", PreviewHumanoid)
- else
- local controller = Instance.new("AnimationController")
- controller.Parent = PreviewModel
- PreviewAnimator = Instance.new("Animator")
- PreviewAnimator.Parent = controller
- end
- end
- BuildPreview()
- local function IsOver(gui)
- local mp = UserInputService:GetMouseLocation()
- local abs = gui.AbsolutePosition
- local size = gui.AbsoluteSize
- return mp.X >= abs.X and mp.X <= abs.X + size.X and mp.Y >= abs.Y and mp.Y <= abs.Y + size.Y
- end
- Viewport.InputBegan:Connect(function(i)
- if i.UserInputType == Enum.UserInputType.MouseButton1 then
- Viewport:SetAttribute("DragCam", true)
- Viewport:SetAttribute("CamStart", i.Position)
- elseif i.UserInputType == Enum.UserInputType.MouseWheel then
- Dist = Dist - i.Position.Z * 2
- end
- end)
- Viewport.InputEnded:Connect(function(i)
- if i.UserInputType == Enum.UserInputType.MouseButton1 then
- Viewport:SetAttribute("DragCam", false)
- end
- end)
- Viewport.InputChanged:Connect(function(i)
- if i.UserInputType ~= Enum.UserInputType.MouseMovement then
- return
- end
- if Viewport:GetAttribute("DragCam") then
- local last = Viewport:GetAttribute("CamStart") or i.Position
- local d = i.Position - last
- Viewport:SetAttribute("CamStart", i.Position)
- RotY = RotY - d.X * 0.005
- RotX = RotX - d.Y * 0.005
- end
- end)
- RunService.RenderStepped:Connect(function(dt)
- if AutoRotate then
- RotY = RotY + dt * 0.5
- end
- if PreviewModel and PreviewModel.PrimaryPart then
- local center = PreviewModel.PrimaryPart.Position
- local rotation = CFrame.Angles(0, RotY, 0) * CFrame.Angles(RotX, 0, 0)
- local camCF = CFrame.new(center) * rotation * CFrame.new(0, 0, Dist)
- Camera.CFrame = CFrame.lookAt(camCF.Position, center + Vector3.new(0, 2, 0))
- end
- end)
- local function ResetMotorsModel(model)
- for _, m in ipairs(model:GetDescendants()) do
- if m:IsA("Motor6D") then
- m.Transform = CFrame.new()
- end
- end
- end
- ModeToggleBtn.MouseButton1Click:Connect(function()
- UseCharacter = not UseCharacter
- ModeToggleBtn.Text = UseCharacter and "Mode: Character" or "Mode: Preview"
- end)
- SyncToggleBtn.MouseButton1Click:Connect(function()
- SyncEnabled = not SyncEnabled
- SyncToggleBtn.Text = SyncEnabled and "Sync Preview: ON" or "Sync Preview: OFF"
- BuildPreview()
- ResetMotorsModel(PreviewModel)
- end)
- DedupToggleBtn.MouseButton1Click:Connect(function()
- DedupEnabled = not DedupEnabled
- DedupToggleBtn.Text = DedupEnabled and "Dedup: ON" or "Dedup: OFF"
- end)
- RunService.RenderStepped:Connect(function()
- if not SyncEnabled then
- return
- end
- if not Character or not PreviewModel then
- return
- end
- local src = {}
- for _, p in ipairs(Character:GetDescendants()) do
- if p:IsA("Motor6D") then
- src[p.Part1 and p.Part1.Name or p.Name] = p
- end
- end
- local dst = {}
- for _, m in ipairs(PreviewModel:GetDescendants()) do
- if m:IsA("Motor6D") then
- dst[m.Part1 and m.Part1.Name or m.Name] = m
- end
- end
- for name, dm in pairs(dst) do
- local sm = src[name]
- if sm then
- dm.Transform = sm.Transform
- end
- end
- end)
- local function PlayIdSmart(id)
- local s = normalizeId(id)
- if not s then
- return
- end
- if UseCharacter then
- if Humanoid then
- if ActiveCharTrack then
- ActiveCharTrack:Stop()
- ActiveCharTrack = nil
- end
- local anim = Instance.new("Animation")
- anim.AnimationId = s
- local track = Humanoid:LoadAnimation(anim)
- ActiveCharTrack = track
- track:Play()
- track:AdjustSpeed(SpeedGet())
- track:AdjustWeight(WeightGet())
- end
- else
- if PreviewAnimator then
- if PreviewTrack then
- PreviewTrack:Stop()
- PreviewTrack = nil
- end
- local anim = Instance.new("Animation")
- anim.AnimationId = s
- PreviewTrack = PreviewAnimator:LoadAnimation(anim)
- PreviewTrack:Play()
- PreviewTrack:AdjustSpeed(SpeedGet())
- PreviewTrack:AdjustWeight(WeightGet())
- end
- end
- end
- local ActiveCharCFrameConn = nil
- local ActivePreviewCFrameConn = nil
- local CFrameFrames = nil
- local CFramePlaying = false
- local CFrameLoop = true
- local CFrameSpeed = 1
- local function stopCFrameAll()
- CFramePlaying = false
- if ActiveCharCFrameConn then
- ActiveCharCFrameConn:Disconnect()
- ActiveCharCFrameConn = nil
- end
- if ActivePreviewCFrameConn then
- ActivePreviewCFrameConn:Disconnect()
- ActivePreviewCFrameConn = nil
- end
- end
- local function StopAll()
- stopCFrameAll()
- if PreviewTrack then
- PreviewTrack:Stop()
- PreviewTrack = nil
- end
- if ActiveCharTrack then
- ActiveCharTrack:Stop()
- ActiveCharTrack = nil
- end
- ResetMotorsModel(UseCharacter and Character or PreviewModel)
- end
- local function playCFrameOnModel(model, frames, speed, loop, blend)
- local map = {}
- for _, m in ipairs(model:GetDescendants()) do
- if m:IsA("Motor6D") and m.Part1 then
- map[m.Part1.Name] = m
- end
- end
- local idx = 1
- local timer = 0
- local playing = true
- local conn
- conn = RunService.RenderStepped:Connect(function(dt)
- if not playing then
- conn:Disconnect()
- return
- end
- timer = timer + dt * (speed or 1)
- local a = frames[idx]
- local b = frames[idx + 1]
- if not a then
- return
- end
- local t = a.Time
- local nt = b and b.Time or a.Time
- local span = math.max(nt - t, 1e-6)
- local alpha = math.clamp((timer - t) / span, 0, 1)
- local blended = {}
- for k, v in pairs(a.Data) do
- local vb = b and b.Data[k] or v
- blended[k] = v:Lerp(vb, alpha)
- end
- for n, cf in pairs(blended) do
- local j = map[n]
- if j then
- j.Transform = (blend and blend < 1) and j.Transform:Lerp(cf, blend) or cf
- end
- end
- if timer >= nt then
- idx = idx + 1
- if idx >= #frames then
- if loop then
- idx = 1
- timer = 0
- else
- playing = false
- conn:Disconnect()
- end
- end
- end
- end)
- return conn
- end
- local function PlayCFrameSmart(idOrFrames, loop)
- stopCFrameAll()
- local frames = typeof(idOrFrames) == "table" and idOrFrames or GetObject(idOrFrames)
- if not frames then
- return
- end
- if DedupEnabled then
- local result = {}
- local last = nil
- for i = 1, #frames do
- local f = frames[i]
- if not last then
- table.insert(result, f)
- last = f
- else
- local changed = false
- for name, cf in pairs(f.Data) do
- local prev = last.Data[name]
- if not prev then
- changed = true
- break
- end
- local dp = (cf.Position - prev.Position).Magnitude
- local ax, ay, az = cf:ToOrientation()
- local bx, by, bz = prev:ToOrientation()
- local dr = math.abs(ax - bx) + math.abs(ay - by) + math.abs(az - bz)
- if dp > 1e-5 or dr > 1e-5 then
- changed = true
- break
- end
- end
- if changed then
- table.insert(result, f)
- last = f
- end
- end
- end
- frames = result
- end
- if UseCharacter then
- ResetMotorsModel(Character)
- ActiveCharCFrameConn = playCFrameOnModel(Character, frames, CFrameSpeed, loop ~= false, BlendGet())
- else
- ResetMotorsModel(PreviewModel)
- ActivePreviewCFrameConn = playCFrameOnModel(PreviewModel, frames, CFrameSpeed, loop ~= false, BlendGet())
- end
- CFrameFrames = frames
- CFramePlaying = true
- end
- local function LatestId()
- local last = nil
- local children = AnimLogger:GetChildren()
- for i = #children, 1, -1 do
- local c = children[i]
- if c:IsA("TextButton") then
- last = c
- break
- end
- end
- if not last then
- return nil
- end
- local id = last.Text:match("rbxassetid://%d+") or last.Text:match("%d+")
- return id
- end
- PlayBtn.MouseButton1Click:Connect(function()
- local id = AnimIdInput.Text
- stopCFrameAll()
- ResetMotorsModel(UseCharacter and Character or PreviewModel)
- PlayIdSmart(id)
- end)
- StopBtn.MouseButton1Click:Connect(function()
- StopAll()
- end)
- ResumeBtn.MouseButton1Click:Connect(function()
- local id = AnimIdInput.Text
- if UseCharacter then
- PlayIdSmart(id)
- else
- if PreviewTrack then
- PreviewTrack:AdjustSpeed(SpeedGet())
- PreviewTrack:Play()
- else
- PlayIdSmart(id)
- end
- end
- end)
- FreezeBtn.MouseButton1Click:Connect(function()
- if PreviewTrack then
- PreviewTrack:AdjustSpeed(0)
- end
- if ActiveCharTrack then
- ActiveCharTrack:AdjustSpeed(0)
- end
- CFramePlaying = false
- end)
- UnfreezeBtn.MouseButton1Click:Connect(function()
- if PreviewTrack then
- PreviewTrack:AdjustSpeed(SpeedGet())
- end
- if ActiveCharTrack then
- ActiveCharTrack:AdjustSpeed(SpeedGet())
- end
- if CFrameFrames and #CFrameFrames > 0 then
- CFramePlaying = true
- end
- end)
- PlayCFrameBtn.MouseButton1Click:Connect(function()
- local id = AnimIdInput.Text
- local frames = GetObject(id)
- if frames and #frames > 0 then
- CFrameSpeed = math.max(0.05, math.min(10, SpeedGet()))
- PlayCFrameSmart(frames, true)
- else
- stopCFrameAll()
- ResetMotorsModel(UseCharacter and Character or PreviewModel)
- PlayIdSmart(id)
- task.delay(0.1, function()
- local live = {}
- local motors = {}
- for _, m in ipairs((UseCharacter and Character or PreviewModel):GetDescendants()) do
- if m:IsA("Motor6D") and m.Part1 then
- motors[m.Part1.Name] = m
- end
- end
- local start = tick()
- local conn = RunService.Heartbeat:Connect(function()
- local elapsed = tick() - start
- local data = {}
- for name, mot in pairs(motors) do
- data[name] = mot.Transform
- end
- table.insert(live, { Time = elapsed, Data = data })
- if elapsed >= 8 then
- conn:Disconnect()
- end
- end)
- task.delay(8.1, function()
- if #live > 0 then
- CFrameSpeed = math.max(0.05, math.min(10, SpeedGet()))
- PlayCFrameSmart(live, true)
- end
- end)
- end)
- end
- end)
- StopCFrameBtn.MouseButton1Click:Connect(function()
- stopCFrameAll()
- end)
- ResumeCFrameBtn.MouseButton1Click:Connect(function()
- if CFrameFrames and #CFrameFrames > 0 then
- CFrameSpeed = math.max(0.05, math.min(10, SpeedGet()))
- PlayCFrameSmart(CFrameFrames, CFrameLoop)
- end
- end)
- local SliderWatcher = Instance.new("BindableEvent")
- SliderWatcher.Event:Connect(function()
- local s = SpeedGet()
- local w = WeightGet()
- if PreviewTrack then
- PreviewTrack:AdjustSpeed(s)
- PreviewTrack:AdjustWeight(w)
- end
- if ActiveCharTrack then
- ActiveCharTrack:AdjustSpeed(s)
- ActiveCharTrack:AdjustWeight(w)
- end
- CFrameSpeed = math.max(0.05, math.min(10, s))
- end)
- SpeedSlider.InputChanged:Connect(function()
- SliderWatcher:Fire()
- end)
- WeightSlider.InputChanged:Connect(function()
- SliderWatcher:Fire()
- end)
- BlendSlider.InputChanged:Connect(function()
- SliderWatcher:Fire()
- end)
- CopyIdBtn.MouseButton1Click:Connect(function()
- local id = normalizeId(AnimIdInput.Text) or AnimIdInput.Text
- if setclipboard then
- setclipboard(tostring(id))
- end
- end)
- InjectBtn.MouseButton1Click:Connect(function()
- local id = AnimIdInput.Text
- local nid = normalizeId(id) or id
- local item = MakeButton("Manual\n" .. nid, UDim2.new(1, -8, 0, 48))
- item.Parent = AnimLogger
- item.MouseButton1Click:Connect(function()
- if setclipboard then
- setclipboard(tostring(nid))
- end
- stopCFrameAll()
- ResetMotorsModel(UseCharacter and Character or PreviewModel)
- PlayIdSmart(id)
- end)
- AnimLogger.CanvasSize = UDim2.new(0, 0, 0, AnimLoggerLayout.AbsoluteContentSize.Y + 12)
- end)
- AlignBtn.MouseButton1Click:Connect(function()
- if PreviewModel and PreviewModel.PrimaryPart then
- PreviewModel:SetPrimaryPartCFrame(CFrame.new(0, 6, 0))
- end
- end)
- ReloadBtn.MouseButton1Click:Connect(function()
- stopCFrameAll()
- if PreviewTrack then
- PreviewTrack:Stop()
- PreviewTrack = nil
- end
- BuildPreview()
- ResetMotorsModel(UseCharacter and Character or PreviewModel)
- end)
- QuickPlayBtn.MouseButton1Click:Connect(function()
- local id = LatestId()
- if id then
- stopCFrameAll()
- ResetMotorsModel(UseCharacter and Character or PreviewModel)
- PlayIdSmart(id)
- end
- end)
- QuickCFrameBtn.MouseButton1Click:Connect(function()
- local id = LatestId()
- if id then
- local frames = GetObject(id)
- if frames and #frames > 0 then
- CFrameSpeed = math.max(0.05, math.min(10, SpeedGet()))
- PlayCFrameSmart(frames, true)
- else
- stopCFrameAll()
- ResetMotorsModel(UseCharacter and Character or PreviewModel)
- PlayIdSmart(id)
- task.delay(0.1, function()
- local live = {}
- local motors = {}
- for _, m in ipairs((UseCharacter and Character or PreviewModel):GetDescendants()) do
- if m:IsA("Motor6D") and m.Part1 then
- motors[m.Part1.Name] = m
- end
- end
- local start = tick()
- local conn = RunService.Heartbeat:Connect(function()
- local elapsed = tick() - start
- local data = {}
- for name, mot in pairs(motors) do
- data[name] = mot.Transform
- end
- table.insert(live, { Time = elapsed, Data = data })
- if elapsed >= 8 then
- conn:Disconnect()
- end
- end)
- task.delay(8.1, function()
- if #live > 0 then
- CFrameSpeed = math.max(0.05, math.min(10, SpeedGet()))
- PlayCFrameSmart(live, true)
- end
- end)
- end)
- end
- end
- end)
- SaveTableBtn.MouseButton1Click:Connect(function()
- local id = AnimIdInput.Text
- local nid = tostring(id):match("%d+")
- if not nid or Blacklist[nid] then
- return
- end
- local frames = GetObject(id)
- if frames and #frames > 0 then
- ExportFrames(frames, id, AnimIdInput.Text ~= "" and AnimIdInput.Text or nil)
- end
- end)
- SaveAllBtn.MouseButton1Click:Connect(function()
- for _, child in ipairs(AnimLogger:GetChildren()) do
- if child:IsA("TextButton") then
- local id = child.Text:match("rbxassetid://(%d+)")
- if id and not Blacklist[id] then
- local frames = GetObject(id)
- if frames and #frames > 0 then
- ExportFrames(frames, id, child.Text:match("^(.-)\n") or nil)
- end
- end
- end
- end
- end)
- BatchSaveBtn.MouseButton1Click:Connect(function()
- local raw = AnimIdInput.Text
- local list = {}
- for num in tostring(raw):gmatch("%d+") do
- table.insert(list, num)
- end
- for _, id in ipairs(list) do
- if not Blacklist[id] then
- local frames = GetObject(id)
- if frames and #frames > 0 then
- ExportFrames(frames, id, tostring(id))
- end
- end
- end
- end)
- TableLoadBtn.MouseButton1Click:Connect(function()
- local id = AnimIdInput.Text
- local file = tostring(id):match("%d+")
- if file and readfile and isfile and isfile("AnimExports/" .. file .. ".lua") then
- local ok, tbl = pcall(function()
- return loadstring(readfile("AnimExports/" .. file .. ".lua"))()
- end)
- if ok and typeof(tbl) == "table" then
- for _, v in pairs(tbl) do
- if typeof(v) == "table" and #v > 0 then
- CFrameFrames = v
- break
- end
- end
- end
- end
- end)
- TablePlayBtn.MouseButton1Click:Connect(function()
- if CFrameFrames and #CFrameFrames > 0 then
- CFrameSpeed = math.max(0.05, math.min(10, SpeedGet()))
- PlayCFrameSmart(CFrameFrames, true)
- end
- end)
- ClearListBtn.MouseButton1Click:Connect(function()
- for _, child in ipairs(AnimLogger:GetChildren()) do
- if child:IsA("TextButton") then
- child:Destroy()
- end
- end
- AnimLogger.CanvasSize = UDim2.new(0, 0, 0, 0)
- end)
- local Logged = {}
- local function PassesFilter(name, id)
- local f = SearchBar.Text
- if f == nil or f == "" then
- return true
- end
- f = f:lower()
- local n = (name or ""):lower()
- local s = (id or ""):lower()
- return string.find(n, f, 1, true) or string.find(s, f, 1, true)
- end
- local function MakeLogItem(name, id)
- local btn = MakeButton(name .. "\n" .. id, UDim2.new(1, -8, 0, 48))
- btn.Parent = AnimLogger
- btn.MouseButton1Click:Connect(function()
- local nid = normalizeId(id) or id
- if setclipboard then
- setclipboard(nid)
- end
- stopCFrameAll()
- ResetMotorsModel(UseCharacter and Character or PreviewModel)
- PlayIdSmart(id)
- end)
- return btn
- end
- local function LogAnim(name, id)
- id = (id and tostring(id)) or ""
- if id == "" then
- return
- end
- local nid = normalizeId(id) or id
- if Logged[nid] then
- return
- end
- if not PassesFilter(name, nid) then
- return
- end
- Logged[nid] = true
- MakeLogItem(name ~= "" and name or "Unknown", nid)
- AnimLogger.CanvasSize = UDim2.new(0, 0, 0, AnimLoggerLayout.AbsoluteContentSize.Y + 12)
- end
- Humanoid.AnimationPlayed:Connect(function(track)
- local a = track and track.Animation
- LogAnim(a and a.Name or "Unknown", a and a.AnimationId or "")
- end)
- SearchBar:GetPropertyChangedSignal("Text"):Connect(function()
- for _, child in ipairs(AnimLogger:GetChildren()) do
- if child:IsA("TextButton") then
- child:Destroy()
- end
- end
- AnimLogger.CanvasSize = UDim2.new(0, 0, 0, 0)
- Logged = {}
- end)
- Players.LocalPlayer.CharacterAdded:Connect(function(c)
- Character = c
- Humanoid = Character:WaitForChild("Humanoid")
- BuildPreview()
- ResetMotorsModel(PreviewModel)
- end)
- CloseBtn.MouseButton1Click:Connect(function()
- StopAll()
- Gui:Destroy()
- end)
Advertisement
Add Comment
Please, Sign In to add comment