Animação para Roblox

Moon Animator travou? Os 5 pontos de falha, em ordem

O Moon Animator não abre, não move o rig ou exporta uma animação que não toca no jogo. Cada um desses sintomas tem uma causa diferente — este texto separa os cinco e te dá um auditor de rig para rodar antes de animar.

por Gustavo Cantino11 min de leituraIntermediário

Rascunho assistido por IA, revisado, testado e editado por um humano antes de publicar. Ver Política Editorial. · Revisado por Gustavo Cantino, 20/09/2026 Política Editorial

Placa tipográfica com a categoria Animação para Roblox em destaque, o nível intermediário abaixo, e um campo de barras verticais verde-limão sobre fundo escuro.

"Moon animator not working" não é um problema: são cinco, e eles não se consertam do mesmo jeito. Ou o botão do plugin não aparece na aba Plugins, ou a janela abre e a timeline fica vazia, ou você mexe o rig e nada se move, ou o Export dá erro, ou a animação sobe bonitinha e no jogo o personagem continua em T-pose. Antes de reinstalar o plugin pela terceira vez — o que resolve exatamente um desses cinco casos — descubra qual dos cinco é o seu. Leva três minutos e economiza a tarde.

Cinco sintomas diferentes chamados de "não funciona"

A) O botão não aparece. Você instalou pelo site, voltou pro Studio e a aba Plugins não mudou. Isso é instalação ou ativação, nunca rig. Custa uns 20 minutos de gente procurando em menu errado.

B) A janela abre, a timeline fica vazia. Você clica em adicionar o rig e ele não entra na lista, ou entra e some. Aqui o suspeito é o rig (sem Humanoid, sem Motor6D) ou um conflito de duas versões do plugin instaladas ao mesmo tempo.

C) O rig não se move. Você arrasta o braço, a curva aparece na timeline, e a parte fica parada. Isso é junta: Motor6D ausente, Part0/Part1 vazios, ou uma parte com Anchored = true no meio do galho.

D) O Export falha. O plugin pede o nome, você confirma e vem erro, ou nada acontece e o Output cospe uma linha vermelha. Aqui é permissão de conta/grupo ou rig inválido para virar KeyframeSequence.

E) Sobe e não toca. Esse é o mais caro dos cinco, porque só aparece no fim do ciclo. Você animou 40 movimentos, exportou tudo, colou os IDs, deu Play e nada. Cada ciclo animar → exportar → testar leva de 5 a 15 minutos; descobrir no item 40 que os 40 estão na conta errada é uma hora de re-upload mais a troca de todos os IDs espalhados nos scripts.

A ordem de diagnóstico abaixo segue a frequência real: começa no mais barato de checar e termina no mais caro de consertar.

Diagnóstico em ordem: plugin, permissão, rig, save, export

1. Plugin instalado não é plugin ativado (30 segundos). Vá em Plugins → Manage Plugins. Se o Moon Animator está na lista mas desmarcado, marque e reabra o Studio. Se não está na lista, você comprou/instalou logado em uma conta e abriu o Studio em outra — acontece muito com quem tem conta de teste. E se você instalou com o Studio aberto, feche todas as janelas do Studio e abra de novo: plugin novo só carrega na inicialização.

2. Duas versões brigando (2 minutos). Plugins soltos como arquivo .rbxm na pasta local de plugins do Studio carregam junto com os da loja. Se você já baixou o Moon Animator manualmente algum dia e depois instalou pela loja, existem dois botões e um deles está quebrado — normalmente o antigo, que perdeu API. Abra a pasta local de plugins pelo botão Plugins Folder do Studio, apague duplicatas e cópias antigas do Moon Animator 1, e reabra. Com o Output aberto (View → Output), procure a primeira linha vermelha com o nome do plugin: ela é a única que importa, o resto é consequência.

3. Permissão negada não pergunta de novo. Plugin que pede acesso a script ou a requisições externas mostra o prompt uma vez. Se você clicou Deny naquele dia, o plugin segue rodando meio funcional para sempre e você não vê aviso nenhum. Volte em Manage Plugins, abra as permissões do Moon Animator e libere o que estiver bloqueado.

4. O rig — aqui mora a maioria dos casos B e C. O Moon Animator anima Motor6D, e só. Ele não anima Weld, não anima WeldConstraint, não anima parte ancorada e não anima parte cujo Motor6D está com Part0 ou Part1 vazio (o caso clássico de rig importado do Blender via FBX e montado na mão depois).

Checklist do rig que funciona:

  • Model com PrimaryPart definido (normalmente a HumanoidRootPart);
  • um Humanoid ou um AnimationController dentro do Model;
  • todas as partes com Anchored = false;
  • um Motor6D por junta, com Part0 sendo o pai e Part1 o filho;
  • nome único por parte — duas partes chamadas "Handle" e o plugin escolhe uma delas no export.

Junta faltando você cria na mão:

Barra de comando do Studio (View → Command Bar)
local rig = workspace.Dummy
local joint = Instance.new("Motor6D")
joint.Name = "Neck"
joint.Part0 = rig.UpperTorso
joint.Part1 = rig.Head
joint.C0 = rig.UpperTorso.CFrame:Inverse() * rig.Head.CFrame
joint.Parent = rig.UpperTorso

Em vez de conferir isso item por item em cada rig, rode o auditor da próxima seção. Ele devolve a lista de problemas em um print.

5. Teste do arquivo limpo (90 segundos). Este é o passo que separa "o plugin quebrou" de "o meu arquivo quebrou", e é o que quase ninguém faz. Abra um Baseplate novo, gere um dummy pelo Rig Builder, abra o Moon Animator, crie dois keyframes e salve. Funcionou? Então o plugin está inteiro e o problema é o seu lugar: save corrompido, rig bagunçado ou outro plugin conflitando. Não funcionou nem no arquivo limpo? Aí sim é instalação/versão, e você volta pros passos 1 a 3 com a consciência tranquila.

6. Export. Rig sem Humanoid/AnimationController e rig com junta inválida derrubam o export. Resolvidos esses, o que sobra é permissão de publicação: se o jogo é de grupo, a animação precisa ser criada como o grupo. Confira a opção de dono na janela de export antes de clicar em salvar — é um clique que decide se você vai refazer tudo depois.

O auditor de rig que você roda antes de abrir a timeline

O artefato desta página é um Script com --!strict que varre o seu rig e imprime os problemas que travam o Moon Animator: PrimaryPart vazio, falta de Humanoid/AnimationController, partes ancoradas, nomes duplicados, Motor6D com Part0/Part1 nulos, junta apontando pra fora do rig e juntas faltando no padrão R6 ou R15 (ele detecta qual dos dois seu rig está mais perto de ser).

Como usar: cole em um Script dentro de ServerScriptService, troque RIG_NAME pelo nome do Model do rig no Workspace e aperte Run (F8) — Run, não Play, porque você quer o estado de edição do rig, não o personagem que o jogo cria. Leia o Output: linhas de warn são o que precisa consertar, a linha que começa com OK é o resumo. Roda em menos de um segundo em rig de 15 juntas e substitui a inspeção manual no Explorer.

O segundo artefato é o rig-check.json: o mesmo checklist em formato de dado, para ficar ao lado do .blend e do seu script de exportação. Serve pra travar o padrão do projeto quando mais de uma pessoa monta rig — inclusive o dono do asset no export, que é a causa do erro da próxima seção.

O erro caro: a animação exportada na conta errada

Animação no Roblox só carrega se o dono do asset for o mesmo dono da experiência. Jogo de grupo exige animação criada pelo grupo. Se você exportou pela sua conta pessoal, o ID existe, abre no site, toca no editor — e no jogo publicado não acontece nada. O sintoma é traiçoeiro justamente por isso: você jura que o Moon Animator não funciona, quando o problema é de propriedade do asset.

E tem um agravante que dobra a confusão:

Script em StarterCharacterScripts — o jeito ERRADO
local anim = Instance.new("Animation")
anim.AnimationId = "rbxassetid://0000000000"
humanoid:LoadAnimation(anim):Play() -- depreciado e engole o erro

A forma certa passa pelo Animator e checa o resultado:

Script em StarterCharacterScripts
local animator = humanoid:FindFirstChildOfClass("Animator") or Instance.new("Animator", humanoid)
local ok, track = pcall(function() return animator:LoadAnimation(anim) end)
if not ok then warn("animacao nao carregou:", anim.AnimationId, track) return end
track.Priority = Enum.AnimationPriority.Action
track:Play()

Sem o warn, falha de carregamento vira silêncio e você passa uma hora procurando bug de script. Com ele, o Output te entrega o ID exato do asset que está na conta errada.

O conserto: re-exporte a animação escolhendo o grupo como dono e troque o ID. Se forem 40 animações, cada re-upload leva algo entre 30 e 60 segundos, mais a troca do ID no código — é a diferença entre um minuto de atenção no export e uma hora de trabalho repetido. Se seus IDs estão hardcoded espalhados em vários scripts, esse prejuízo dobra.

O que medir depois

Duas métricas dizem se o seu pipeline de animação está saudável. A primeira é o tempo do ciclo: quantos minutos entre "terminei o movimento na timeline" e "vi ele rodando no jogo publicado". Cronometre uma vez. Se passa de 15 minutos, o gargalo quase sempre é export manual e ID colado na mão.

A segunda é quantos warns o auditor devolve no primeiro Run de cada rig novo. Rig que nasce com zero warn não gera nenhum dos casos B, C e D deste texto. Se todo rig seu nasce com três ou quatro warns, o problema não é o Moon Animator: é o seu processo de montar rig. Salve um rig aprovado como template em ReplicatedStorage e clone a partir dele em vez de montar de novo.

Feito isso, tire os IDs de animação de dentro dos scripts e coloque todos num ModuleScript único, com fallback e warn no carregamento. Assim, o dia em que você precisar re-exportar tudo para um grupo, a troca acontece em um arquivo só.

Artefato pronto pra usar

Script em ServerScriptService (rode com Run / F8)
lua
--!strict
-- Auditor de rig para Moon Animator.
-- Onde mora: Script dentro de ServerScriptService.
-- Como rodar: ajuste RIG_NAME, aperte Run (F8) e leia o Output.
-- Warn = conserte antes de abrir a timeline. OK = resumo.

local RIG_NAME: string = "Dummy"

local R15: { string } = {
	"Root", "Waist", "Neck",
	"LeftShoulder", "LeftElbow", "LeftWrist",
	"RightShoulder", "RightElbow", "RightWrist",
	"LeftHip", "LeftKnee", "LeftAnkle",
	"RightHip", "RightKnee", "RightAnkle",
}

local R6: { string } = {
	"RootJoint", "Neck",
	"Left Shoulder", "Right Shoulder",
	"Left Hip", "Right Hip",
}

type Report = { string }

local function contains(list: { string }, value: string): boolean
	for _, v in list do
		if v == value then
			return true
		end
	end
	return false
end

local function audit(rigName: string): Report
	local report: Report = {}

	local rig = workspace:FindFirstChild(rigName)
	if not rig or not rig:IsA("Model") then
		table.insert(report, "FATAL: nao existe Model chamado " .. rigName .. " no Workspace.")
		return report
	end

	-- 1. PrimaryPart: sem ele o plugin erra a referencia de raiz
	if not rig.PrimaryPart then
		table.insert(report, "PrimaryPart vazio: defina a HumanoidRootPart como PrimaryPart do Model.")
	end

	-- 2. Controlador: sem Humanoid nem AnimationController o rig nao aparece na lista
	local hasController = rig:FindFirstChildOfClass("Humanoid") ~= nil
		or rig:FindFirstChildOfClass("AnimationController") ~= nil
	if not hasController then
		table.insert(report, "Sem Humanoid e sem AnimationController: adicione um dos dois dentro do Model.")
	end

	local joints: { Motor6D } = {}
	local partNames: { [string]: number } = {}

	for _, d in rig:GetDescendants() do
		if d:IsA("Motor6D") then
			table.insert(joints, d)
			local p0, p1 = d.Part0, d.Part1
			if p0 == nil or p1 == nil then
				table.insert(report, "Motor6D " .. d:GetFullName() .. " com Part0 ou Part1 vazio.")
			elseif not p0:IsDescendantOf(rig) or not p1:IsDescendantOf(rig) then
				table.insert(report, "Motor6D " .. d.Name .. " aponta para parte fora do rig.")
			end
		elseif d:IsA("BasePart") then
			if d.Anchored then
				table.insert(report, "Parte ancorada: " .. d.Name .. " (Anchored = true trava tudo abaixo dela).")
			end
			partNames[d.Name] = (partNames[d.Name] or 0) + 1
		elseif d:IsA("Weld") or d:IsA("WeldConstraint") then
			table.insert(report, "Junta rigida " .. d.ClassName .. " em " .. d:GetFullName() .. ": troque por Motor6D se essa parte precisa animar.")
		end
	end

	-- 3. Nomes duplicados quebram o export do KeyframeSequence
	for name, count in partNames do
		if count > 1 then
			table.insert(report, "Nome duplicado: " .. tostring(count) .. " partes chamadas " .. name .. ".")
		end
	end

	if #joints == 0 then
		table.insert(report, "FATAL: zero Motor6D no rig. O Moon Animator so move Motor6D.")
		return report
	end

	-- 4. Descobre se o rig esta mais perto de R6 ou R15 e cobra as juntas faltando
	local jointNames: { string } = {}
	for _, j in joints do
		table.insert(jointNames, j.Name)
	end

	local r15Hits, r6Hits = 0, 0
	for _, n in jointNames do
		if contains(R15, n) then
			r15Hits += 1
		end
		if contains(R6, n) then
			r6Hits += 1
		end
	end

	local isR15 = r15Hits >= r6Hits
	local expected: { string } = if isR15 then R15 else R6
	local label: string = if isR15 then "R15" else "R6"

	for _, n in expected do
		if not contains(jointNames, n) then
			table.insert(report, "Junta " .. label .. " faltando: " .. n .. ".")
		end
	end

	table.insert(report, "OK: " .. tostring(#joints) .. " Motor6D encontrados, padrao mais proximo: " .. label .. ".")
	return report
end

local result = audit(RIG_NAME)
print("=== AUDITOR DE RIG: " .. RIG_NAME .. " ===")
for _, line in result do
	if string.sub(line, 1, 2) == "OK" then
		print(line)
	else
		warn(line)
	end
end
print("=== " .. tostring(#result) .. " linha(s) no relatorio ===")
Arquivo rig-check.json na pasta do projeto, ao lado do .blend do rig
json
{
  "rigName": "Dummy",
  "rigType": "R15",
  "primaryPart": "HumanoidRootPart",
  "controller": "Humanoid",
  "requiredMotor6D": [
    "Root", "Waist", "Neck",
    "LeftShoulder", "LeftElbow", "LeftWrist",
    "RightShoulder", "RightElbow", "RightWrist",
    "LeftHip", "LeftKnee", "LeftAnkle",
    "RightHip", "RightKnee", "RightAnkle"
  ],
  "reject": {
    "anchoredParts": true,
    "duplicatePartNames": true,
    "weldOnAnimatedParts": true,
    "nullJointParts": true
  },
  "export": {
    "assetOwner": "group",
    "groupId": 0,
    "defaultPriority": "Action",
    "namePrefix": "anim_",
    "notes": "groupId 0 = preencher com o grupo dono da experiencia. Animacao de conta pessoal nao carrega em jogo de grupo."
  }
}
Neste artigo

Continue por aqui