Walk Animating in Animate script not working?

Hi, I was making a custom animation script for an npc. Specifically, the run animation. Whenever I test it, It doesn’t work and it doesn’t have an animation. How can I fix this? (I used the regular roblox animation script.)

image

Thanks, Vaekarr.

5 Likes

Can you actually provide the whole code?

1 Like

You probably should be using AnimationTrack.Priority in this scenario

3 Likes

Well, I clearly said “regular animate” script. So, it’s just the animate inside your character. Just for your sake, I’ll put the whole code in.

local Character = script.Parent
local Humanoid = Character:WaitForChild("Humanoid")
local pose = "Standing"

local userNoUpdateOnLoopSuccess, userNoUpdateOnLoopValue = pcall(function() return 
UserSettings():IsUserFeatureEnabled("UserNoUpdateOnLoop") end)
local userNoUpdateOnLoop = userNoUpdateOnLoopSuccess and userNoUpdateOnLoopValue

local animateScriptEmoteHookFlagExists, animateScriptEmoteHookFlagEnabled = pcall(function()
return UserSettings():IsUserFeatureEnabled("UserAnimateScriptEmoteHook")
end)
local FFlagAnimateScriptEmoteHook = animateScriptEmoteHookFlagExists and 
animateScriptEmoteHookFlagEnabled

local AnimationSpeedDampeningObject = script:FindFirstChild("ScaleDampeningPercent")
local HumanoidHipHeight = 2

local EMOTE_TRANSITION_TIME = 0.1

local currentAnim = ""
local currentAnimInstance = nil
local currentAnimTrack = nil
local currentAnimKeyframeHandler = nil
local currentAnimSpeed = 1.0

local runAnimTrack = nil
local runAnimKeyframeHandler = nil

local PreloadedAnims = {}

local animTable = {}
local animNames = { 
idle = 	{	
			{ id = "rbxassetid://4855872238", weight = 1 }
		},
walk = 	{ 	
			{ id = "rbxassetid://4855826648", weight = 10 } 
		}, 
run = 	{
			{ id = "rbxassetid://4855826648", weight = 10 } 
		}, 
swim = 	{
			{ id = "http://www.roblox.com/asset/?id=507784897", weight = 10 } 
		}, 
swimidle = 	{
			{ id = "http://www.roblox.com/asset/?id=507785072", weight = 10 } 
		}, 
jump = 	{
			{ id = "http://www.roblox.com/asset/?id=507765000", weight = 10 } 
		}, 
fall = 	{
			{ id = "http://www.roblox.com/asset/?id=507767968", weight = 10 } 
		}, 
climb = {
			{ id = "http://www.roblox.com/asset/?id=507765644", weight = 10 } 
		}, 
sit = 	{
			{ id = "http://www.roblox.com/asset/?id=2506281703", weight = 10 } 
		},	
toolnone = {
			{ id = "http://www.roblox.com/asset/?id=507768375", weight = 10 } 
		},
toolslash = {
			{ id = "http://www.roblox.com/asset/?id=522635514", weight = 10 } 
		},
toollunge = {
			{ id = "http://www.roblox.com/asset/?id=522638767", weight = 10 } 
		},
wave = {
			{ id = "http://www.roblox.com/asset/?id=507770239", weight = 10 } 
		},
point = {
			{ id = "http://www.roblox.com/asset/?id=507770453", weight = 10 } 
		},
dance = {
			{ id = "http://www.roblox.com/asset/?id=507771019", weight = 10 }, 
			{ id = "http://www.roblox.com/asset/?id=507771955", weight = 10 }, 
			{ id = "http://www.roblox.com/asset/?id=507772104", weight = 10 } 
		},
dance2 = {
			{ id = "http://www.roblox.com/asset/?id=507776043", weight = 10 }, 
			{ id = "http://www.roblox.com/asset/?id=507776720", weight = 10 }, 
			{ id = "http://www.roblox.com/asset/?id=507776879", weight = 10 } 
		},
dance3 = {
			{ id = "http://www.roblox.com/asset/?id=507777268", weight = 10 }, 
			{ id = "http://www.roblox.com/asset/?id=507777451", weight = 10 }, 
			{ id = "http://www.roblox.com/asset/?id=507777623", weight = 10 } 
		},
laugh = {
			{ id = "http://www.roblox.com/asset/?id=507770818", weight = 10 } 
		},
cheer = {
			{ id = "http://www.roblox.com/asset/?id=507770677", weight = 10 } 
		},
}

-- Existance in this list signifies that it is an emote, the value indicates if it is a looping emote
local emoteNames = { wave = false, point = false, dance = true, dance2 = true, dance3 = true, laugh     = false, cheer = false}

math.randomseed(tick())

function findExistingAnimationInSet(set, anim)
if set == nil or anim == nil then
	return 0
end

for idx = 1, set.count, 1 do 
	if set[idx].anim.AnimationId == anim.AnimationId then
		return idx
	end
    end

return 0
end

    function configureAnimationSet(name, fileList)
	if (animTable[name] ~= nil) then
	for _, connection in pairs(animTable[name].connections) do
		connection:disconnect()
	end
    end
	animTable[name] = {}
	animTable[name].count = 0
	animTable[name].totalWeight = 0	
	animTable[name].connections = {}

local allowCustomAnimations = true

local success, msg = pcall(function() allowCustomAnimations = 
game:GetService("StarterPlayer").AllowCustomAnimations end)
if not success then
	allowCustomAnimations = true
end

-- check for config values
local config = script:FindFirstChild(name)
if (allowCustomAnimations and config ~= nil) then
	table.insert(animTable[name].connections, config.ChildAdded:connect(function(child) 
configureAnimationSet(name, fileList) end))
	table.insert(animTable[name].connections, config.ChildRemoved:connect(function(child) 
configureAnimationSet(name, fileList) end))
	
	local idx = 0
	for _, childPart in pairs(config:GetChildren()) do
		if (childPart:IsA("Animation")) then
			local newWeight = 1
			local weightObject = childPart:FindFirstChild("Weight")
			if (weightObject ~= nil) then
				newWeight = weightObject.Value
			end
			animTable[name].count = animTable[name].count + 1
			idx = animTable[name].count
			animTable[name][idx] = {}
			animTable[name][idx].anim = childPart
			animTable[name][idx].weight = newWeight
			animTable[name].totalWeight = animTable[name].totalWeight + animTable[name][idx].weight
			table.insert(animTable[name].connections, childPart.Changed:connect(function(property) 
configureAnimationSet(name, fileList) end))
			table.insert(animTable[name].connections, childPart.ChildAdded:connect(function(property)         
configureAnimationSet(name, fileList) end))
			table.insert(animTable[name].connections,     
childPart.ChildRemoved:connect(function(property) configureAnimationSet(name, fileList) end))
		end
	end
end

-- fallback to defaults
if (animTable[name].count <= 0) then
	for idx, anim in pairs(fileList) do
		animTable[name][idx] = {}
		animTable[name][idx].anim = Instance.new("Animation")
		animTable[name][idx].anim.Name = name
		animTable[name][idx].anim.AnimationId = anim.id
		animTable[name][idx].weight = anim.weight
		animTable[name].count = animTable[name].count + 1
		animTable[name].totalWeight = animTable[name].totalWeight + anim.weight
	end
end

-- preload anims
for i, animType in pairs(animTable) do
	for idx = 1, animType.count, 1 do
		if PreloadedAnims[animType[idx].anim.AnimationId] == nil then
			Humanoid:LoadAnimation(animType[idx].anim)
			PreloadedAnims[animType[idx].anim.AnimationId] = true
		end				
	end
end
end



function configureAnimationSetOld(name, fileList)
if (animTable[name] ~= nil) then
	for _, connection in pairs(animTable[name].connections) do
		connection:disconnect()
	end
end
animTable[name] = {}
animTable[name].count = 0
animTable[name].totalWeight = 0	
animTable[name].connections = {}

local allowCustomAnimations = true

local success, msg = pcall(function() allowCustomAnimations = game:GetService("StarterPlayer").AllowCustomAnimations end)
if not success then
	allowCustomAnimations = true
end

-- check for config values
local config = script:FindFirstChild(name)
if (allowCustomAnimations and config ~= nil) then
	table.insert(animTable[name].connections, config.ChildAdded:connect(function(child) configureAnimationSet(name, fileList) end))
	table.insert(animTable[name].connections, config.ChildRemoved:connect(function(child) configureAnimationSet(name, fileList) end))
	local idx = 1
	for _, childPart in pairs(config:GetChildren()) do
		if (childPart:IsA("Animation")) then
			table.insert(animTable[name].connections, childPart.Changed:connect(function(property) configureAnimationSet(name, fileList) end))
			animTable[name][idx] = {}
			animTable[name][idx].anim = childPart
			local weightObject = childPart:FindFirstChild("Weight")
			if (weightObject == nil) then
				animTable[name][idx].weight = 1
			else
				animTable[name][idx].weight = weightObject.Value
			end
			animTable[name].count = animTable[name].count + 1
			animTable[name].totalWeight = animTable[name].totalWeight + animTable[name][idx].weight
			idx = idx + 1
		end
	end
end

-- fallback to defaults
if (animTable[name].count <= 0) then
	for idx, anim in pairs(fileList) do
		animTable[name][idx] = {}
		animTable[name][idx].anim = Instance.new("Animation")
		animTable[name][idx].anim.Name = name
		animTable[name][idx].anim.AnimationId = anim.id
		animTable[name][idx].weight = anim.weight
		animTable[name].count = animTable[name].count + 1
		animTable[name].totalWeight = animTable[name].totalWeight + anim.weight
		-- print(name .. " [" .. idx .. "] " .. anim.id .. " (" .. anim.weight .. ")")
	end
end

-- preload anims
for i, animType in pairs(animTable) do
	for idx = 1, animType.count, 1 do 
		Humanoid:LoadAnimation(animType[idx].anim)
	end
end
end

-- Setup animation objects
function scriptChildModified(child)
local fileList = animNames[child.Name]
if (fileList ~= nil) then
	configureAnimationSet(child.Name, fileList)
end	
end

script.ChildAdded:connect(scriptChildModified)
script.ChildRemoved:connect(scriptChildModified)


for name, fileList in pairs(animNames) do 
configureAnimationSet(name, fileList)
end	

-- ANIMATION

-- declarations
local toolAnim = "None"
local toolAnimTime = 0

local jumpAnimTime = 0
local jumpAnimDuration = 0.31

local toolTransitionTime = 0.1
local fallTransitionTime = 0.2

local currentlyPlayingEmote = false

-- functions

function stopAllAnimations()
local oldAnim = currentAnim

-- return to idle if finishing an emote
if (emoteNames[oldAnim] ~= nil and emoteNames[oldAnim] == false) then
	oldAnim = "idle"
end

if FFlagAnimateScriptEmoteHook and currentlyPlayingEmote then
	oldAnim = "idle"
	currentlyPlayingEmote = false
end

currentAnim = ""
currentAnimInstance = nil
if (currentAnimKeyframeHandler ~= nil) then
	currentAnimKeyframeHandler:disconnect()
end

if (currentAnimTrack ~= nil) then
	currentAnimTrack:Stop()
	currentAnimTrack:Destroy()
	currentAnimTrack = nil
end

-- clean up walk if there is one
if (runAnimKeyframeHandler ~= nil) then
	runAnimKeyframeHandler:disconnect()
end

if (runAnimTrack ~= nil) then
	runAnimTrack:Stop()
	runAnimTrack:Destroy()
	runAnimTrack = nil
end

return oldAnim
end

function getHeightScale()
if Humanoid then
	if not Humanoid.AutomaticScalingEnabled then
		return 1
    	end
    	
	local scale = Humanoid.HipHeight / HumanoidHipHeight
	if AnimationSpeedDampeningObject == nil then
	AnimationSpeedDampeningObject = script:FindFirstChild("ScaleDampeningPercent")
	end
	if AnimationSpeedDampeningObject ~= nil then
		scale = 1 + (Humanoid.HipHeight - HumanoidHipHeight) *                         																																																												 
   AnimationSpeedDampeningObject.Value / HumanoidHipHeight
	end
	return scale
end	
return 1
end

	local smallButNotZero = 0.0001
	function setRunSpeed(speed)
local speedScaled = speed * 1.25
local heightScale = getHeightScale()
local runSpeed = speedScaled / heightScale

if runSpeed ~= currentAnimSpeed then
	if runSpeed < 0.33 then
		currentAnimTrack:AdjustWeight(1.0)		
		runAnimTrack:AdjustWeight(smallButNotZero)
	elseif runSpeed < 0.66 then
		local weight = ((runSpeed - 0.33) / 0.33)
		currentAnimTrack:AdjustWeight(1.0 - weight + smallButNotZero)
		runAnimTrack:AdjustWeight(weight + smallButNotZero)
	else
		currentAnimTrack:AdjustWeight(smallButNotZero)
		runAnimTrack:AdjustWeight(1.0)
	end
	currentAnimSpeed = runSpeed
	runAnimTrack:AdjustSpeed(runSpeed)
	currentAnimTrack:AdjustSpeed(runSpeed)
end	
	end

	function setAnimationSpeed(speed)
if currentAnim == "walk" then
		setRunSpeed(speed)
else
	if speed ~= currentAnimSpeed then
		currentAnimSpeed = speed
		currentAnimTrack:AdjustSpeed(currentAnimSpeed)
	end
end
	end

function keyFrameReachedFunc(frameName)
if (frameName == "End") then
	if currentAnim == "walk" then
		if userNoUpdateOnLoop == true then
			if runAnimTrack.Looped ~= true then
				runAnimTrack.TimePosition = 0.0
			end
			if currentAnimTrack.Looped ~= true then
				currentAnimTrack.TimePosition = 0.0
			end
		else
			runAnimTrack.TimePosition = 0.0
			currentAnimTrack.TimePosition = 0.0
		end
	else
		local repeatAnim = currentAnim
		-- return to idle if finishing an emote
		if (emoteNames[repeatAnim] ~= nil and emoteNames[repeatAnim] == false) then
			repeatAnim = "idle"
		end
		
		if FFlagAnimateScriptEmoteHook and currentlyPlayingEmote then
			if currentAnimTrack.Looped then
				-- Allow the emote to loop
				return
			end
			
			repeatAnim = "idle"
			currentlyPlayingEmote = false
		end
		
		local animSpeed = currentAnimSpeed
		playAnimation(repeatAnim, 0.15, Humanoid)
		setAnimationSpeed(animSpeed)
	end
end
end

	function rollAnimation(animName)
local roll = math.random(1, animTable[animName].totalWeight) 
local origRoll = roll
local idx = 1
while (roll > animTable[animName][idx].weight) do
	roll = roll - animTable[animName][idx].weight
	idx = idx + 1
end
return idx
end

	local function switchToAnim(anim, animName, transitionTime, humanoid)
-- switch animation		
if (anim ~= currentAnimInstance) then
	
	if (currentAnimTrack ~= nil) then
		currentAnimTrack:Stop(transitionTime)
		currentAnimTrack:Destroy()
	end

	if (runAnimTrack ~= nil) then
		runAnimTrack:Stop(transitionTime)
		runAnimTrack:Destroy()
		if userNoUpdateOnLoop == true then
			runAnimTrack = nil
		end
	end

	currentAnimSpeed = 1.0

	-- load it to the humanoid; get AnimationTrack
	currentAnimTrack = humanoid:LoadAnimation(anim)
	currentAnimTrack.Priority = Enum.AnimationPriority.Core
	 
	-- play the animation
	currentAnimTrack:Play(transitionTime)
	currentAnim = animName
	currentAnimInstance = anim

	-- set up keyframe name triggers
	if (currentAnimKeyframeHandler ~= nil) then
		currentAnimKeyframeHandler:disconnect()
	end
	currentAnimKeyframeHandler = 																 
   currentAnimTrack.KeyframeReached:connect(keyFrameReachedFunc)
	
	-- check to see if we need to blend a walk/run animation
	if animName == "walk" then
		local runAnimName = "run"
		local runIdx = rollAnimation(runAnimName)

		runAnimTrack = humanoid:LoadAnimation(animTable[runAnimName][runIdx].anim)
		runAnimTrack.Priority = Enum.AnimationPriority.Core
		runAnimTrack:Play(transitionTime)		
		
		if (runAnimKeyframeHandler ~= nil) then
			runAnimKeyframeHandler:disconnect()
		end
		runAnimKeyframeHandler = 
runAnimTrack.KeyframeReached:connect(keyFrameReachedFunc)	
	end
end
end

function playAnimation(animName, transitionTime, humanoid) 	
local idx = rollAnimation(animName)
local anim = animTable[animName][idx].anim

switchToAnim(anim, animName, transitionTime, humanoid)
currentlyPlayingEmote = false
end

function playEmote(emoteAnim, transitionTime, humanoid)
switchToAnim(emoteAnim, emoteAnim.Name, transitionTime, humanoid)
currentlyPlayingEmote = true
end


local toolAnimName = ""
local toolAnimTrack = nil
local toolAnimInstance = nil
local currentToolAnimKeyframeHandler = nil

function toolKeyFrameReachedFunc(frameName)
if (frameName == "End") then
	playToolAnimation(toolAnimName, 0.0, Humanoid)
end
end


function playToolAnimation(animName, transitionTime, humanoid, priority)	 		
	local idx = rollAnimation(animName)
	local anim = animTable[animName][idx].anim

	if (toolAnimInstance ~= anim) then
		
		if (toolAnimTrack ~= nil) then
			toolAnimTrack:Stop()
			toolAnimTrack:Destroy()
			transitionTime = 0
		end
				
		-- load it to the humanoid; get AnimationTrack
		toolAnimTrack = humanoid:LoadAnimation(anim)
		if priority then
			toolAnimTrack.Priority = priority
		end
		 
		-- play the animation
		toolAnimTrack:Play(transitionTime)
		toolAnimName = animName
		toolAnimInstance = anim

		currentToolAnimKeyframeHandler = 
toolAnimTrack.KeyframeReached:connect(toolKeyFrameReachedFunc)
	end
end

function stopToolAnimations()
local oldAnim = toolAnimName

if (currentToolAnimKeyframeHandler ~= nil) then
	currentToolAnimKeyframeHandler:disconnect()
end

toolAnimName = ""
toolAnimInstance = nil
if (toolAnimTrack ~= nil) then
	toolAnimTrack:Stop()
	toolAnimTrack:Destroy()
	toolAnimTrack = nil
end

return oldAnim
end

function onRunning(speed)	
if speed > 0.75 then
	local scale = 16.0
	playAnimation("walk", 0.2, Humanoid)
	setAnimationSpeed(speed / scale)
	pose = "Running"
else
	if emoteNames[currentAnim] == nil and not currentlyPlayingEmote then
		playAnimation("idle", 0.2, Humanoid)
		pose = "Standing"
	end
end
end

function onDied()
pose = "Dead"
end

function onJumping()
playAnimation("jump", 0.1, Humanoid)
jumpAnimTime = jumpAnimDuration
pose = "Jumping"
end

function onClimbing(speed)
local scale = 5.0
playAnimation("climb", 0.1, Humanoid)
setAnimationSpeed(speed / scale)
pose = "Climbing"
end

function onGettingUp()
pose = "GettingUp"
end

function onFreeFall()
if (jumpAnimTime <= 0) then
	playAnimation("fall", fallTransitionTime, Humanoid)
end
pose = "FreeFall"
end

 function onFallingDown()
pose = "FallingDown"
 end

function onSeated()
pose = "Seated"
end

function onPlatformStanding()
pose = "PlatformStanding"
end


function onSwimming(speed)
if speed > 1.00 then
	local scale = 10.0
	playAnimation("swim", 0.4, Humanoid)
	setAnimationSpeed(speed / scale)
	pose = "Swimming"
else
	playAnimation("swimidle", 0.4, Humanoid)
	pose = "Standing"
end
end

function animateTool()
if (toolAnim == "None") then
	playToolAnimation("toolnone", toolTransitionTime, Humanoid, Enum.AnimationPriority.Idle)
	return
end

if (toolAnim == "Slash") then
	playToolAnimation("toolslash", 0, Humanoid, Enum.AnimationPriority.Action)
	return
end

if (toolAnim == "Lunge") then
	playToolAnimation("toollunge", 0, Humanoid, Enum.AnimationPriority.Action)
	return
end
end

function getToolAnim(tool)
for _, c in ipairs(tool:GetChildren()) do
	if c.Name == "toolanim" and c.className == "StringValue" then
		return c
	end
end
return nil
end

 local lastTick = 0

function stepAnimate(currentTime)
local amplitude = 1
local frequency = 1
local deltaTime = currentTime - lastTick
lastTick = currentTime

local climbFudge = 0
local setAngles = false

if (jumpAnimTime > 0) then
	jumpAnimTime = jumpAnimTime - deltaTime
end

if (pose == "FreeFall" and jumpAnimTime <= 0) then
	playAnimation("fall", fallTransitionTime, Humanoid)
elseif (pose == "Seated") then
	playAnimation("sit", 0.5, Humanoid)
	return
elseif (pose == "Running") then
	playAnimation("walk", 0.2, Humanoid)
elseif (pose == "Dead" or pose == "GettingUp" or pose == "FallingDown" or pose == "Seated" or pose == "PlatformStanding") then
	stopAllAnimations()
	amplitude = 0.1
	frequency = 1
	setAngles = true
end

-- Tool Animation handling
local tool = Character:FindFirstChildOfClass("Tool")
if tool and tool:FindFirstChild("Handle") then
	local animStringValueObject = getToolAnim(tool)

	if animStringValueObject then
		toolAnim = animStringValueObject.Value
		-- message recieved, delete StringValue
		animStringValueObject.Parent = nil
		toolAnimTime = currentTime + .3
     	end

	if currentTime > toolAnimTime then
		toolAnimTime = 0
		toolAnim = "None"
	    end

	animateTool()		
else
	stopToolAnimations()
	toolAnim = "None"
	toolAnimInstance = nil
	toolAnimTime = 0
end
end

-- connect events
Humanoid.Died:connect(onDied)
Humanoid.Running:connect(onRunning)
Humanoid.Jumping:connect(onJumping)
Humanoid.Climbing:connect(onClimbing)
Humanoid.GettingUp:connect(onGettingUp)
Humanoid.FreeFalling:connect(onFreeFall)
Humanoid.FallingDown:connect(onFallingDown)
Humanoid.Seated:connect(onSeated)
Humanoid.PlatformStanding:connect(onPlatformStanding)
Humanoid.Swimming:connect(onSwimming)

 -- setup emote chat hook
 game:GetService("Players").LocalPlayer.Chatted:connect(function(msg)
local emote = ""
if (string.sub(msg, 1, 3) == "/e ") then
	emote = string.sub(msg, 4)
elseif (string.sub(msg, 1, 7) == "/emote ") then
	emote = string.sub(msg, 8)
end

if (pose == "Standing" and emoteNames[emote] ~= nil) then
	playAnimation(emote, EMOTE_TRANSITION_TIME, Humanoid)
end
end)

-- emote bindable hook
if FFlagAnimateScriptEmoteHook then
script:WaitForChild("PlayEmote").OnInvoke = function(emote)
	-- Only play emotes when idling
	if pose ~= "Standing" then
		return
	end

	if emoteNames[emote] ~= nil then
		-- Default emotes
		playAnimation(emote, EMOTE_TRANSITION_TIME, Humanoid)
		
		return true
	elseif typeof(emote) == "Instance" and emote:IsA("Animation") then
		-- Non-default emotes
		playEmote(emote, EMOTE_TRANSITION_TIME, Humanoid)
		return true
	end
	
	-- Return false to indicate that the emote could not be played
	return false
end
end

-- initialize to idle
playAnimation("idle", 0.1, Humanoid)
pose = "Standing"

-- loop to handle timed state transitions and tool animations
while Character.Parent ~= nil do
local _, currentGameTime = wait(0.1)
stepAnimate(currentGameTime)
end
3 Likes

I set it to movement but it didn’t work. Sorry for the late reply btw.

Hey.

I had a similar issue a few days, ago however we did eventually fix it, it was to do with the string values.

You can find our thread here.

Try deleting all the string values and animation objects in the script, and put your custom animations in the table instead.

1 Like