Hello Developers,
I’m trying to animate a model using moon animator and then trying to have that animation play in game when needed.
When it fires, I want the animation to play properly without stopping.
The animation is definitely playing because the part visibly moves but only a small amount compared to what I actually animated. It looks like the animation is being cut short or barely getting started before something resets it.
How it’s supposed to look:
How it looks in game:
Everything is welded with Motor6D’s.
Part 0 is always the HumanoidRootPart and part is every other part in the model
Code: how animations get set up (shared by every tower type in my game)
function TowerCombatUtils.SetupTowerAnimations(towerModel, config)
local idleId = config:FindFirstChild("Idle")
local attackId = config:FindFirstChild("Fire")
if not idleId and not attackId then return nil end
local controller = towerModel:FindFirstChildOfClass("Humanoid") or towerModel:FindFirstChildOfClass("AnimationController")
if not controller then return nil end
local animator = controller:FindFirstChildOfClass("Animator")
if not animator then
animator = Instance.new("Animator")
animator.Parent = controller
end
local tracks = {}
if idleId and idleId:IsA("Animation") then
local success, trackOrError = pcall(function() return animator:LoadAnimation(idleId) end)
if success then
trackOrError.Priority = Enum.AnimationPriority.Idle
trackOrError.Looped = true
trackOrError:Play()
tracks.Idle = trackOrError
end
end
if attackId and attackId:IsA("Animation") then
local success, trackOrError = pcall(function() return animator:LoadAnimation(attackId) end)
if success then
trackOrError.Priority = Enum.AnimationPriority.Action
trackOrError.Looped = false
tracks.Attack = trackOrError
end
end
return tracks
end
Code: how the attack animation actually gets played and synced to firing
Right now I think this part could be the most important. Cooldown here is the tower’s fire rate. This whole thing runs every time the tower attacks:
if animationTracks and animationTracks.Attack then
local attackAnim = animationTracks.Attack
local animLength = attackAnim.Length
if animLength > 0 and cooldown < animLength then
attackAnim:AdjustSpeed(animLength / cooldown)
else
attackAnim:AdjustSpeed(1)
end
attackAnim.TimePosition = 0
attackAnim:Play()
local fireMarkerConnection
local keyframeConnection
fireMarkerConnection = attackAnim:GetMarkerReachedSignal("Fire"):Connect(performAttack)
keyframeConnection = attackAnim.KeyframeReached:Connect(function(keyName)
if keyName == "Fire" or keyName == "fire" then performAttack() end
end)
local waitTime = attackAnim.Length > 0 and (attackAnim.Length / attackAnim.Speed) or 1
task.delay(waitTime + 0.05, function()
if not fired then performAttack() end
if fireMarkerConnection then fireMarkerConnection:Disconnect() end
if keyframeConnection then keyframeConnection:Disconnect() end
end)
else
performAttack()
end
The animation’s length is not longer than the cooldown.
I don’t believe it’s an issue with animation priority either. Because this logic works for all my other humanoid towers and they work exactly the same.
If anyone has any idea why this is occuring it would be great to know.
All help is appreciated!
