
Key RequiredUniversal

--// Universal Animation Logger GUI
--// Put this LocalScript in StarterPlayerScripts or StarterGui
--// Logs animation IDs from Self / NPCs / All
--// Local-only logger
local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local player = Players.LocalPlayer
--========================
-- EDIT HERE
--========================
local guiTitle = "Animation Logger"
local smallButtonText = "Open"
local defaultScope = "All" -- "All", "Self", "NPCs"
local maxLogRows = 200
--========================
local scopeModes = {"All", "Self", "NPCs"}
local scopeIndex = 1
for i, mode in ipairs(scopeModes) do
if mode == defaultScope then
scopeIndex = i
break
end
end
local screenGui = Instance.new("ScreenGui")
screenGui.Name = "AnimationLoggerGui"
screenGui.ResetOnSpawn = false
screenGui.IgnoreGuiInset = true
screenGui.Parent = player:WaitForChild("PlayerGui")
local mainFrame = Instance.new("Frame")
mainFrame.Size = UDim2.new(0, 340, 0, 390)
mainFrame.Position = UDim2.new(0.5, -170, 0.5, -195)
mainFrame.BackgroundColor3 = Color3.fromRGB(25, 25, 25)
mainFrame.BorderSizePixel = 0
mainFrame.Active = true
mainFrame.ClipsDescendants = true
mainFrame.Parent = screenGui
local mainCorner = Instance.new("UICorner")
mainCorner.CornerRadius = UDim.new(0, 12)
mainCorner.Parent = mainFrame
local titleBar = Instance.new("TextLabel")
titleBar.Size = UDim2.new(1, 0, 0, 35)
titleBar.BackgroundColor3 = Color3.fromRGB(35, 35, 35)
titleBar.BorderSizePixel = 0
titleBar.Text = guiTitle
titleBar.TextColor3 = Color3.fromRGB(255, 255, 255)
titleBar.TextScaled = true
titleBar.Font = Enum.Font.GothamBold
titleBar.Active = true
titleBar.Parent = mainFrame
local titleCorner = Instance.new("UICorner")
titleCorner.CornerRadius = UDim.new(0, 12)
titleCorner.Parent = titleBar
local hideButton = Instance.new("TextButton")
hideButton.Size = UDim2.new(0, 60, 0, 25)
hideButton.Position = UDim2.new(1, -65, 0, 5)
hideButton.BackgroundColor3 = Color3.fromRGB(70, 70, 70)
hideButton.Text = "Hide"
hideButton.TextColor3 = Color3.fromRGB(255, 255, 255)
hideButton.TextScaled = true
hideButton.Font = Enum.Font.Gotham
hideButton.BorderSizePixel = 0
hideButton.Parent = mainFrame
local hideCorner = Instance.new("UICorner")
hideCorner.CornerRadius = UDim.new(0, 8)
hideCorner.Parent = hideButton
local deleteButton = Instance.new("TextButton")
deleteButton.Size = UDim2.new(0, 25, 0, 25)
deleteButton.Position = UDim2.new(1, -30, 0, 5)
deleteButton.BackgroundColor3 = Color3.fromRGB(170, 50, 50)
deleteButton.Text = "X"
deleteButton.TextColor3 = Color3.fromRGB(255, 255, 255)
deleteButton.TextScaled = true
deleteButton.Font = Enum.Font.GothamBold
deleteButton.BorderSizePixel = 0
deleteButton.Parent = mainFrame
local deleteCorner = Instance.new("UICorner")
deleteCorner.CornerRadius = UDim.new(0, 8)
deleteCorner.Parent = deleteButton
local scrollFrame = Instance.new("ScrollingFrame")
scrollFrame.Size = UDim2.new(1, 0, 1, -35)
scrollFrame.Position = UDim2.new(0, 0, 0, 35)
scrollFrame.BackgroundTransparency = 1
scrollFrame.BorderSizePixel = 0
scrollFrame.ScrollBarThickness = 5
scrollFrame.CanvasSize = UDim2.new(0, 0, 0, 0)
scrollFrame.Parent = mainFrame
local content = Instance.new("Frame")
content.Size = UDim2.new(1, -10, 0, 0)
content.Position = UDim2.new(0, 5, 0, 5)
content.BackgroundTransparency = 1
content.BorderSizePixel = 0
content.Parent = scrollFrame
local layout = Instance.new("UIListLayout")
layout.Padding = UDim.new(0, 6)
layout.SortOrder = Enum.SortOrder.LayoutOrder
layout.Parent = content
layout:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function()
content.Size = UDim2.new(1, -10, 0, layout.AbsoluteContentSize.Y)
scrollFrame.CanvasSize = UDim2.new(0, 0, 0, layout.AbsoluteContentSize.Y + 10)
end)
local function roundify(obj, radius)
local c = Instance.new("UICorner")
c.CornerRadius = UDim.new(0, radius)
c.Parent = obj
return c
end
local function makeLabel(text, height)
local lbl = Instance.new("TextLabel")
lbl.Size = UDim2.new(1, 0, 0, height or 22)
lbl.BackgroundTransparency = 1
lbl.Text = text
lbl.TextColor3 = Color3.fromRGB(255, 255, 255)
lbl.TextScaled = true
lbl.Font = Enum.Font.Gotham
lbl.Parent = content
return lbl
end
local function makeBox(labelText, defaultText)
local row = Instance.new("Frame")
row.Size = UDim2.new(1, 0, 0, 50)
row.BackgroundColor3 = Color3.fromRGB(32, 32, 32)
row.BorderSizePixel = 0
row.Parent = content
roundify(row, 10)
local lbl = Instance.new("TextLabel")
lbl.Size = UDim2.new(1, -12, 0, 17)
lbl.Position = UDim2.new(0, 6, 0, 3)
lbl.BackgroundTransparency = 1
lbl.Text = labelText
lbl.TextColor3 = Color3.fromRGB(255, 255, 255)
lbl.TextScaled = true
lbl.Font = Enum.Font.Gotham
lbl.Parent = row
local box = Instance.new("TextBox")
box.Size = UDim2.new(1, -12, 0, 22)
box.Position = UDim2.new(0, 6, 0, 24)
box.BackgroundColor3 = Color3.fromRGB(45, 45, 45)
box.Text = defaultText
box.TextColor3 = Color3.fromRGB(255, 255, 255)
box.TextScaled = true
box.Font = Enum.Font.Gotham
box.BorderSizePixel = 0
box.ClearTextOnFocus = false
box.Parent = row
roundify(box, 8)
return box
end
local function makeButton(text, color, height)
local btn = Instance.new("TextButton")
btn.Size = UDim2.new(1, 0, 0, height or 30)
btn.BackgroundColor3 = color
btn.Text = text
btn.TextColor3 = Color3.fromRGB(255, 255, 255)
btn.TextScaled = true
btn.Font = Enum.Font.GothamBold
btn.BorderSizePixel = 0
btn.Parent = content
roundify(btn, 10)
return btn
end
makeLabel("Live animation logger", 22)
local scopeButton = makeButton("Scope: " .. scopeModes[scopeIndex], Color3.fromRGB(80, 80, 140), 30)
local refreshButton = makeButton("Refresh", Color3.fromRGB(80, 120, 80), 30)
local copiedBox = makeBox("Copied ID", "")
local statusLabel = makeLabel("Status: Ready", 22)
local clearButton = makeButton("Clear Logs", Color3.fromRGB(120, 80, 40), 30)
local logSectionTitle = makeLabel("Logs", 22)
local smallButton = Instance.new("TextButton")
smallButton.Size = UDim2.new(0, 70, 0, 30)
smallButton.Position = UDim2.new(0, 10, 0.5, -15)
smallButton.BackgroundColor3 = Color3.fromRGB(35, 35, 35)
smallButton.Text = smallButtonText
smallButton.TextColor3 = Color3.fromRGB(255, 255, 255)
smallButton.TextScaled = true
smallButton.Font = Enum.Font.GothamBold
smallButton.BorderSizePixel = 0
smallButton.Visible = false
smallButton.Active = true
smallButton.Parent = screenGui
local smallCorner = Instance.new("UICorner")
smallCorner.CornerRadius = UDim.new(0, 10)
smallCorner.Parent = smallButton
local logsContainer = Instance.new("Frame")
logsContainer.Size = UDim2.new(1, 0, 0, 0)
logsContainer.BackgroundTransparency = 1
logsContainer.BorderSizePixel = 0
logsContainer.Parent = content
local logsLayout = Instance.new("UIListLayout")
logsLayout.Padding = UDim.new(0, 6)
logsLayout.SortOrder = Enum.SortOrder.LayoutOrder
logsLayout.Parent = logsContainer
logsLayout:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function()
logsContainer.Size = UDim2.new(1, 0, 0, logsLayout.AbsoluteContentSize.Y)
end)
local hookedAnimators = {}
local logRows = {}
local seenAnimationIds = {}
local function updateStatus(text)
statusLabel.Text = "Status: " .. text
end
local function trimText(s)
return (tostring(s or ""):gsub("^%s+", ""):gsub("%s+$", ""))
end
local function normalizeAnimationId(text)
text = trimText(text)
if text == "" then
return "Unknown"
end
local id = text:match("(%d+)")
if id then
return "rbxassetid://" .. id
end
return text
end
local function canUseScope(model)
local mode = scopeModes[scopeIndex]
if mode == "All" then
return true
elseif mode == "Self" then
return model == player.Character
elseif mode == "NPCs" then
if not model then
return false
end
if model == player.Character then
return false
end
return Players:GetPlayerFromCharacter(model) == nil
end
return true
end
local function getSourceInfo(animator)
local model = animator:FindFirstAncestorOfClass("Model")
if model == player.Character then
return "Self", player.Name, model
end
local plr = model and Players:GetPlayerFromCharacter(model)
if plr then
return "Player", plr.Name, model
end
if model then
return "NPC", model.Name, model
end
return "Unknown", "Unknown", model
end
local function copyText(text)
local ok = false
if typeof(setclipboard) == "function" then
ok = pcall(setclipboard, text)
end
copiedBox.Text = text
return ok
end
local function clearLogRows()
for _, child in ipairs(logsContainer:GetChildren()) do
if child:IsA("Frame") and child:GetAttribute("IsLogRow") then
child:Destroy()
end
end
table.clear(logRows)
table.clear(seenAnimationIds)
updateStatus("Logs cleared")
end
local function enforceMaxRows()
while #logRows > maxLogRows do
local old = table.remove(logRows, 1)
if old and old.Parent then
local oldId = old:GetAttribute("AnimIdKey")
if oldId then
seenAnimationIds[oldId] = nil
end
old:Destroy()
end
end
end
local function addLogRow(sourceKind, sourceName, animName, animId)
if seenAnimationIds[animId] then
return
end
seenAnimationIds[animId] = true
local row = Instance.new("Frame")
row.Name = "LogRow"
row.Size = UDim2.new(1, 0, 0, 62)
row.BackgroundColor3 = Color3.fromRGB(32, 32, 32)
row.BorderSizePixel = 0
row.Parent = logsContainer
row:SetAttribute("IsLogRow", true)
row:SetAttribute("AnimIdKey", animId)
roundify(row, 10)
local title = Instance.new("TextLabel")
title.Size = UDim2.new(1, -70, 0, 24)
title.Position = UDim2.new(0, 8, 0, 6)
title.BackgroundTransparency = 1
title.TextXAlignment = Enum.TextXAlignment.Left
title.Text = "[" .. sourceKind .. "] " .. sourceName .. " - " .. animName
title.TextColor3 = Color3.fromRGB(255, 255, 255)
title.TextScaled = true
title.Font = Enum.Font.GothamBold
title.Parent = row
local idLabel = Instance.new("TextLabel")
idLabel.Size = UDim2.new(1, -70, 0, 20)
idLabel.Position = UDim2.new(0, 8, 0, 33)
idLabel.BackgroundTransparency = 1
idLabel.TextXAlignment = Enum.TextXAlignment.Left
idLabel.Text = animId
idLabel.TextColor3 = Color3.fromRGB(220, 220, 220)
idLabel.TextScaled = true
idLabel.Font = Enum.Font.Gotham
idLabel.Parent = row
local copyButton = Instance.new("TextButton")
copyButton.Size = UDim2.new(0, 52, 0, 36)
copyButton.Position = UDim2.new(1, -60, 0.5, -18)
copyButton.BackgroundColor3 = Color3.fromRGB(70, 110, 180)
copyButton.Text = "Copy"
copyButton.TextColor3 = Color3.fromRGB(255, 255, 255)
copyButton.TextScaled = true
copyButton.Font = Enum.Font.GothamBold
copyButton.BorderSizePixel = 0
copyButton.Parent = row
roundify(copyButton, 8)
copyButton.MouseButton1Click:Connect(function()
copyText(animId)
copyButton.Text = "Done"
task.delay(0.8, function()
if copyButton and copyButton.Parent then
copyButton.Text = "Copy"
end
end)
end)
table.insert(logRows, row)
enforceMaxRows()
end
local function getAnimationName(track)
local anim = track and track.Animation
if anim and anim.Name and anim.Name ~= "" then
return anim.Name
end
if track and track.Name and track.Name ~= "" and track.Name ~= "AnimationTrack" then
return track.Name
end
return "Unknown"
end
local function getAnimationId(track)
local anim = track and track.Animation
if anim and anim.AnimationId and anim.AnimationId ~= "" then
return normalizeAnimationId(anim.AnimationId)
end
return "Unknown"
end
local function logTrack(animator, track)
if not animator or not track then
return
end
local sourceKind, sourceName, model = getSourceInfo(animator)
if not canUseScope(model) then
return
end
local animId = getAnimationId(track)
if animId == "Unknown" then
return
end
local animName = getAnimationName(track)
addLogRow(sourceKind, sourceName, animName, animId)
updateStatus("Logged " .. animName)
end
local function scanCurrentTracks()
clearLogRows()
for _, obj in ipairs(workspace:GetDescendants()) do
if obj:IsA("Animator") then
if not hookedAnimators[obj] then
local conn
conn = obj.AnimationPlayed:Connect(function(track)
logTrack(obj, track)
end)
hookedAnimators[obj] = conn
end
local ok, tracks = pcall(function()
return obj:GetPlayingAnimationTracks()
end)
if ok and tracks then
for _, track in ipairs(tracks) do
logTrack(obj, track)
end
end
end
end
updateStatus("Refreshed")
end
local function hookAnimator(animator)
if hookedAnimators[animator] then
return
end
local conn
conn = animator.AnimationPlayed:Connect(function(track)
logTrack(animator, track)
end)
hookedAnimators[animator] = conn
end
local function refreshScopeText()
scopeButton.Text = "Scope: " .. scopeModes[scopeIndex]
end
scopeButton.MouseButton1Click:Connect(function()
scopeIndex += 1
if scopeIndex > #scopeModes then
scopeIndex = 1
end
refreshScopeText()
updateStatus("Scope set to " .. scopeModes[scopeIndex])
scanCurrentTracks()
end)
refreshButton.MouseButton1Click:Connect(function()
scanCurrentTracks()
end)
clearButton.MouseButton1Click:Connect(function()
clearLogRows()
end)
hideButton.MouseButton1Click:Connect(function()
mainFrame.Visible = false
smallButton.Visible = true
end)
smallButton.MouseButton1Click:Connect(function()
mainFrame.Visible = true
smallButton.Visible = false
end)
deleteButton.MouseButton1Click:Connect(function()
for _, conn in pairs(hookedAnimators) do
if conn then
conn:Disconnect()
end
end
table.clear(hookedAnimators)
clearLogRows()
screenGui:Destroy()
end)
local function makeDraggable(handle, target)
local dragging = false
local dragInput
local dragStart
local startPos
handle.InputBegan:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseButton1
or input.UserInputType == Enum.UserInputType.Touch then
dragging = true
dragStart = input.Position
startPos = target.Position
input.Changed:Connect(function()
if input.UserInputState == Enum.UserInputState.End then
dragging = false
end
end)
end
end)
handle.InputChanged:Connect(function(input)
if input.UserInputType == Enum.UserInputType.MouseMovement
or input.UserInputType == Enum.UserInputType.Touch then
dragInput = input
end
end)
UserInputService.InputChanged:Connect(function(input)
if input == dragInput and dragging then
local delta = input.Position - dragStart
target.Position = UDim2.new(
startPos.X.Scale,
startPos.X.Offset + delta.X,
startPos.Y.Scale,
startPos.Y.Offset + delta.Y
)
end
end)
end
makeDraggable(titleBar, mainFrame)
makeDraggable(smallButton, smallButton)
workspace.DescendantAdded:Connect(function(obj)
if obj:IsA("Animator") then
hookAnimator(obj)
task.defer(function()
local ok, tracks = pcall(function()
return obj:GetPlayingAnimationTracks()
end)
if ok and tracks then
for _, track in ipairs(tracks) do
logTrack(obj, track)
end
end
end)
end
end)
for _, obj in ipairs(workspace:GetDescendants()) do
if obj:IsA("Animator") then
hookAnimator(obj)
end
end
updateStatus("Ready")
scanCurrentTracks()No comments yet for this script.



