Better ways to handle character based animations

For a game I’m making, each ability holds a LoadAnimation function as shown below. This one is unique for the ability as there are two animations I want to load (Crouch and CrouchIdle) so I return a table instead of one animation.

function InvestigativeStance.LoadAnimation(animator: Animator, player)
	local tracks = {}
	
	for animName, anim in pairs(InvestigativeStance.Data.Animation) do
		local track = animator:LoadAnimation(anim)
		track.Looped = true
		tracks[tostring(animName)] = track
	end
	
	return tracks, InvestigativeStance.Name
end
local function loadAnimations() -- This is in a local script in the character.
	local characterName = player:GetAttribute("CurrentCharacter")
	if not characterName or characterName == "Waiting" then return end
	
	characterData = CharacterService.GetCharacter(characterName)
	if not characterData then return end
	
	local animData = characterData.Data.Animations
	
	if animData.idleAnimation then
		local anim = Instance.new("Animation")
		anim.AnimationId = animData.idleAnimation.AnimationId
		animations.idle = animator:LoadAnimation(anim)
		animations.idle.Priority = Enum.AnimationPriority.Core
		animations.idle.Looped = true
	end
	
	if animData.walkAnimation then
		local anim = Instance.new("Animation")
		anim.AnimationId = animData.walkAnimation.AnimationId
		animations.walk = animator:LoadAnimation(anim)
		animations.walk.Priority = Enum.AnimationPriority.Movement
		animations.walk.Looped = true
	end
	
	if animData.sprintAnimation then
		local anim = Instance.new("Animation")
		anim.AnimationId = animData.sprintAnimation.AnimationId
		animations.sprint = animator:LoadAnimation(anim)
		animations.sprint.Priority = Enum.AnimationPriority.Movement
		animations.sprint.Looped = true
	end
	
	for abilityName, ability in pairs(characterData.Abilities) do
		if ability.LoadAnimation then
			local track, name = ability.LoadAnimation(animator, player)
			if typeof(track) == "table" then
				for _, animTrack in pairs(track) do
					name = abilityName
					animations[name] = animTrack
				end
			end
			animations[name] = track
		end
	end
	
	print(animations)
end

However, when I call for the animations upon activating the ability, it calls for one animaiton using the abilities reference. I can’t set one of the crouch anims to the reference as there are two animations.

UserInputService.InputBegan:Connect(function(input, gpe)
	if gpe or player.Team == game.Teams.Waiting then return end

	local playerCharacter = player:GetAttribute("CurrentCharacter")
	if not playerCharacter or playerCharacter == "Waiting" then return end
	local currentCharacter = CharacterService.GetCharacter(playerCharacter)

	for _, ability in pairs(characterData.Abilities) do
		if input.KeyCode == ability.Keybind then
			local animation = animations[ability.Reference]
			if animation then
				animation:Play()
			else
				AbilityEvent:FireServer(currentCharacter.Name, ability.Reference)
			end
		end
	end
end)

If anyone has any ideas, please share! Or if you know a better way to handle abilities (specifically for an asym game) please share!