Feedback/Support on Animation on Keydown Script

Hey guys,

I’m working on a script that will play an animation when you press a key in-game. The animations are sort of like idle animations and the character doesn’t really move much. The code is working, but sometimes it lags when I go to use it and some times the animation doesn’t play even though they are loaded. I’ll put the code below, and any help would be greatly appreciated!!

(This function module is just a little module a made as practice for my scripting, but also to make things quicker when I’m writing certain scripts. I’ve included the functions I call just so you can see what’s going on better!)

FunctionModule
local module = {}

function module.NewInstance(InstanceType,Name,Parent)
	local New = Instance.new(InstanceType)
	New.Name = Name
	New.Parent = Parent
	return New
end

function module.NewAnimationSetup(Name,Parent,AnimationId)
	local NewAnimation = Instance.new("Animation")
	NewAnimation.Name = Name
	NewAnimation.Parent = Parent
	NewAnimation.AnimationId = "http://www.roblox.com/asset/?id="..AnimationId
	return NewAnimation
end
AnimationHandler (Server Script in ServerScriptService)
local FunctionModule = require(game.ServerScriptService:WaitForChild("FunctionModule"))

local Animations = {
	--Template: {AnimationName = "ToolName",AnimationId = AssetInt64}
	{AnimationName = "Idle1",AnimationId = "3567368976"};
	{AnimationName = "Idle3",AnimationId = "23456"}
}

local function OnAdded(Player)
	Player.CharacterAdded:Connect(function()
		local WorkspacePlayer = game:GetService("Workspace"):WaitForChild(Player.Name)
		local Animator = WorkspacePlayer.Humanoid:WaitForChild("Animator")
		local BostonAnimations = FunctionModule.NewInstance("StringValue","BostonAnimations",Animator)
		for i,v in pairs(Animations) do
			FunctionModule.NewAnimationSetup(v.AnimationName,BostonAnimations,v.AnimationId)
		end
	end)
end

game.Players.PlayerAdded:Connect(OnAdded)
AnimationTrigger (LocalScript in StarterGui)
wait(.2)
local RemoteEvent = game.ReplicatedStorage.AnimationEvent

local Player = game.Players.LocalPlayer
repeat wait() until Player.Character
local Character = Player.Character
local Debounce = false -- our debounce 
local UIS = game:GetService("UserInputService")

local Animations = {
	--Template: {AnimationName = "Name",AnimationId = "StringNumber",Key="LetterInCaps",LoadedAnimation = Character:FindFirstChild("Humanoid"):LoadAnimation(game.Workspace[Player.Name].Humanoid.Animator.BostonAnimations.[TheAnimation'sName])}
	{AnimationName = "Idle1",AnimationId = "3567368976",Key = "M",LoadedAnimation = Character:FindFirstChild("Humanoid"):LoadAnimation(game.Workspace[Player.Name].Humanoid.Animator.BostonAnimations.Idle1)};
}

UIS.InputBegan:Connect(function(Input,TypeCheck)
	if not TypeCheck then -- So that it wont fire when the player is chatting
		for i,v in pairs(Animations) do
			if Input.KeyCode == Enum.KeyCode[v.Key] and Debounce == false then
				Debounce = true
				v.LoadedAnimation:Play()
            	Debounce = false
			end
		end
	end
end)

Thank you for any help you can give!!!

3 Likes

Make sure your animation has the correct priority. If your animation is core or idle, or in some cases movement it can be overridden by the default Roblox animations. Also, I do not believe that :Play() yields the code, in which case your Debounce is pretty much useless since it waits for almost 0 seconds.

https://developer.roblox.com/en-us/api-reference/property/AnimationTrack/Priority

1 Like

This is pretty clean well done optimizing your code espacially using functions, and as @climethestair said :Play() doesn’t yield

Thank you! Priority was the issue and after changing that it fixed it all. I’m uploading a newer version of the code and marking this post as the solution just so if anyone else wants to use the script they are free to! Thanks again for the help!

Updated code below!
(This updated version has some checks in the LocalScript. Basically as soon as the Player moves the animation will end since in the context I’m making this script I’m only using it to make idle animations for a game rather than animations designed to use while moving. Also the Player must not be moving or holding a tool or else the animation won’t begin either. The tool part was just added because some tools will have custom keybinds unique to that tool and using a random animation while also using a tool could break the tool + means that if a tool uses the keybinds f,g,h,j,k,l and you don’t have to find other keybinds that aren’t those numbers and create a ton of keys for the player to have to remember #runonsentence)

FunctionModule
local module = {}

function module.NewInstance(InstanceType,Name,Parent)
	local New = Instance.new(InstanceType)
	New.Name = Name
	New.Parent = Parent
	return New
end

function module.NewAnimationSetup(Name,Parent,AnimationId)
	local NewAnimation = Instance.new("Animation")
	NewAnimation.Name = Name
	NewAnimation.Parent = Parent
	NewAnimation.AnimationId = "http://www.roblox.com/asset/?id="..AnimationId
	return NewAnimation
end
AnimationHandler (ServerScript in ServerScriptService)
local FunctionModule = require(game.ServerScriptService:WaitForChild("FunctionModule"))

local Animations = {
	--Template: {AnimationName = "Name",AnimationId = "StringNumber"}
	{AnimationName = "Idle1",AnimationId = "3567368976"};
	{AnimationName = "Idle3",AnimationId = "23456"}
}

local function OnAdded(Player)
	Player.CharacterAdded:Connect(function()
		local WorkspacePlayer = game:GetService("Workspace"):WaitForChild(Player.Name)
		local Animator = WorkspacePlayer.Humanoid:WaitForChild("Animator")
		local BostonAnimations = FunctionModule.NewInstance("StringValue","BostonAnimations",Animator)
		for i,v in pairs(Animations) do
			FunctionModule.NewAnimationSetup(v.AnimationName,BostonAnimations,v.AnimationId)
		end
	end)
end

game.Players.PlayerAdded:Connect(OnAdded)
AnimationTrigger (LocalScript in StarterGui)
local Player = game.Players.LocalPlayer
repeat wait() until Player.Character
local Character = Player.Character
local UIS = game:GetService("UserInputService")

local Animations = {
	--Template: {AnimationName = "Name",Key="LetterInCaps",LoadedAnimation = Character:FindFirstChild("Humanoid"):LoadAnimation(game.Workspace[Player.Name].Humanoid.Animator.BostonAnimations.[TheAnimation'sNameNoQuotations])}
	{AnimationName = "Idle1",Key = "M",LoadedAnimation = Character:FindFirstChild("Humanoid"):LoadAnimation(game.Workspace[Player.Name].Humanoid.Animator.BostonAnimations.Idle1)};
}

local ActiveAnimationStatus = false
local ActiveAnimation
local ReadyAndAble = true

local function Check()
	local Check1 = true --Check for stationary player
	local Check2 = true --Check for no tools equipped
	
	if Character.Humanoid.MoveDirection ~= Vector3.new(0,0,0) then --Character must be standing still
		Check1 = false
	end
	
	for i, Child in pairs(Character:GetChildren()) do --Character has no tools equipped
		if Child:IsA("Tool") then
			Check2 = false
		end
	end
	
	if Check1 == true and Check2 == true then
		ReadyAndAble = true
	else ReadyAndAble = false
	end
end

UIS.InputBegan:Connect(function(Input,TypeCheck)
	if not TypeCheck then --So that it wont fire when the player is chatting
		for i,v in pairs(Animations) do
			if Input.KeyCode == Enum.KeyCode[v.Key] then
				Check()
				if ReadyAndAble == true then
					v.LoadedAnimation.Priority = Enum.AnimationPriority.Action
					v.LoadedAnimation.Looped = true
					v.LoadedAnimation:Play()
					ActiveAnimationStatus = true
					ActiveAnimation = v.LoadedAnimation
				end
			elseif Input.KeyCode == Enum.KeyCode.W or Input.KeyCode == Enum.KeyCode.A or Input.KeyCode == Enum.KeyCode.S or Input.KeyCode == Enum.KeyCode.D then
				if ActiveAnimationStatus == true then
					if ActiveAnimation:IsA("AnimationTrack") then 
						ActiveAnimation:Stop()
						ActiveAnimationStatus = false
					end
				end
			end
		end
	end
end)
1 Like