Animation is skipping Key Frames while Playtesting but plays normally in Animation Editor

One of the Attack Animations I made for a custom rig I made isn’t playing correctly. The Animation is supposed to be the Character performing an attack with its tail. However, it seems to completely skip past several important key frames.

For reference:

  • All animations have Enum.AnimationPriority.Action2
  • All animations use linear easing style
  • All animations are 24fps
  • The 1st 4 animations are 1.5 seconds long (36 Frames)
  • The last animation is 68 Frames

The animation with the issue is the very last animation that plays in the combo. The animation is one of 5 attacks that make up a combo in a basic combat system I’m trying to implement.

I loaded the Attack Animations’ AnimationIds into an Array like this. There are other Animations, but I’ve ruled them out as possible causes for this problem:

--[ Variables to hold a reference to different Animation tracks for different actions ]
local AttackAnimations = {
	'rbxassetid://13969847411', --[ 1: Left Hand Slash ]
	'rbxassetid://13969855098', --[ 2: Right Hand Slash ]
	'rbxassetid://13969859796', --[ 3: Right Leg Front Kick ]
	'rbxassetid://13969869363', --[ 4: Lunge to Bite ]
	'rbxassetid://13969878167'  --[ 5: Tail Slam (THE ONE WITH THE ISSUE) ]
}

I’m not entirely sure if the issue with the animation has anything to do with my code, but here’s the code that I use for playing the animations. When the Combo variable equals 5, the animation with the issue plays:

--[ If its been enough time since the last Attack, since the last Combo String ended, and if other Variables are just right, evaluate... ]
		if Input.UserInputType == Enum.UserInputType.MouseButton1 and tick() - LastTimeM1 > 2.0 and tick() - LastM1End > 4 and LightOfDay == false and IsRoaring == false and IsAttacking == false and IsBlocking == false then
			--[ Set attacking to true ]
			IsAttacking = true
			
			--[ If it's been too long since the last attack in a Combo String, reset the Combo String ]
			if tick() - LastTimeM1 > 3.0 then
				Combo = 1
			end
			
			--[ Record the time at which this attack was performed ]
			LastTimeM1 = tick()
			
			--[ Variables to hold a reference to the new Animation that's about to play and if the Character is going to perform an Air Attack ]
			local AttackAnimation = Instance.new("Animation", Humanoid)
			local Air = nil
			
			--[ If Space is pressed during the 4th Attack in a Combo String, prepair for the Up-Slam attack ]
			if UserInputService:IsKeyDown("Space") and Combo == 4 and CanAir == true then
				CanAir = false
				Air = "Up"
				AttackAnimation.AnimationId = AirAttackAnimations[1]
			--[ Else if Space isn't pressed during the 5th Attack in a Combo String while the Character is mid-air, prepair for the Down-Slam attack ]	
			elseif not UserInputService:IsKeyDown("Space") and Combo == 5 and CanAir == false then
				Air = "Down"
				AttackAnimation.AnimationId = AirAttackAnimations[2]
			--[ Else, just Load the normal Animation for the Attack ]	
			else
				AttackAnimation.AnimationId = AttackAnimations[Combo]
			end
			
			--[ Load the Animation into the Humanoid and Play it ]
			AnimationTrack2 = Humanoid:LoadAnimation(AttackAnimation)
			AnimationTrack2:Play()
			
			--[ Destroy the reference to the AttackAnimation as we no longer need it ]
			AttackAnimation:Destroy()
			
			--[ Function for when the Animation reaches the KeyFrame to generate a Hitbox to deal damage to a possible Target ]
			AnimationTrack2:GetMarkerReachedSignal("DetectHit"):Connect(function()
				--[ Generates a Hitbox and returns any Target within it ]
				local Target = GenerateHitBox(Vector3.new(20, 20, 60), HumanoidRootPart.CFrame * CFrame.new(0, 0, -20), {Character}, Character)
				
				--[ If there is a Target, communicate to the Server to deal damage ]
				if Target then
					local AttackData = {
						["Target"] = Target,
						["Character"] = Character,
						["Combo"] = Combo,
						["Air"] = Air,
						["Action"] = "Attack"
					}

					CombatEvent:FireServer(AttackData)
				end
				
				--[ Update the value for the Combo Variable ]
				if Combo == #AttackAnimations then
					Combo = 1
					LastM1End = tick()
				else
					Combo += 1
				end
			end)
			
			--[ Adjust wait time based on which attack was performed ]
			local WaitTime
			if Combo < 5 then
				WaitTime = 2.0
			else
				WaitTime = 4.0
			end
			
			--[ Make the Player stay still until the Attack has been fully performed ]
			Humanoid.WalkSpeed = 0
			wait(WaitTime)
			IsAttacking = false
			Humanoid.WalkSpeed = 20
         end

What’s the Issue?

This is what the Animation looks like in Studio in the Animation Editor and how it should ideally play:

This is what the Animation looks like in game:

The issue with the Animation is that it seems to completely skip over several important Key Frames. It interpolates between Frame 24 and Frame 40 as if there were no Key Frames in between. I have been looking up solutions for the past 2 days non-stop but all of the solutions don’t work and/or are outdated.

I’ve tried to do all of the following to no avail:

  • publishing the same animation as a different animation and using the ID from the copy
  • using a server script meant to only play the animation to see if it’s something else causing the issue. It still had the issue
  • setting the animation’s Priority to Action4
  • Tested it through Roblox instead of playtesting in Roblox Studio
  • Adding extra Key Frames in between the period where the animation plays incorrectly
  • changing the easing direction to InOut

Any help is much appreciated.

3 Likes

Your animations are fighting themselves. The fix is giving the animations a higher priority or a higher value

I thought that was the issue when I first ran into it. I tried setting this animation’s priority to Action4 (which is higher than any other animation I use for this character) and it still skips the key frames in the middle.