Walk animation blending with run

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    Get rid of the “animation blending”.

  2. What is the issue? Include screenshots / videos if possible!
    I have been doing a remodel and was in the process of re-adding the ids in their correct scripts. The problem I encountered was that when the walk animation played, the run animation would sorta play too, the legs would jerk upward quickly like my run animation. This wouldn’t happen vice versa though, when the run animation played, it played 100%.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I re-did my walk animation, re-pasted all the ids into the animate script and my run script. I’ve played around in studio to try to fix it and have looked HEAVILY on the internet for similar posts on similar websites- the one I found that 100% addressed my situation was 3 years old and had no replies on scriptinghelpers. I’ve played around with animation weight and priority as well.

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

If you need more/diff info, or are confused, please ask.
Heres my leftshift runscript, the problem is to do with the animate script, this is here just to get a good idea of what might be going on, idk:

local UserInputService = game:GetService("UserInputService")
local player = game.Players.LocalPlayer
local character = player.character
local humanoid = character.Humanoid
local Anim = humanoid.Animator

local Run = script:WaitForChild("Run")
local Runanim = Anim:LoadAnimation(Run)
Run.AnimationId = "rbxassetid://6846184687"


local Walk = script.Parent:WaitForChild("Animate").walk.WalkAnim
Walk.AnimationId = "rbxassetid://6850398480"


UserInputService.InputBegan:Connect(function(input, event)
	if UserInputService.KeyboardEnabled == true then
		local LShift = UserInputService:IsKeyDown(Enum.KeyCode.LeftShift)
		
		if LShift then
			if humanoid.WalkSpeed == 16 then
				wait(.5)
				
				Walk.AnimationId = "rbxassetid://6846184687"
				humanoid.WalkSpeed = 48
				print(Walk.AnimationId)

			elseif humanoid.WalkSpeed == 48 then
				wait(.5)
				
				Walk.AnimationId = "rbxassetid://6850398480"
				humanoid.WalkSpeed = 16
				print(Walk.AnimationId)


			end
		end
		
	end
end)

Everything prints, the speed changes and so does the animation, technically. If I run, the run animation plays, if I walk, the wonky-merged-walk animation plays.

Here’s where I’m sure the blending occurs, line 484-499 in the animate script. I have no idea what this is supposed to do, but the rest of the script seems to be sort of reliant on this, so deleting it or part of it isn’t an option.

		-- 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

Again, if you have any questions, please ask.

Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category.

3 Likes

The thing you said about both animations merging, that’s probably because they have same animation priority and first animation doesn’t have animated keys on some of the character’s parts and other has them, so basically to fix your problem you have a few possible solutions: 1. Stop Running animation and play walking animation so only walking animation is playing 2. Set walking animation priority higher than running, so it overwrites running animation, here is the priority thing AnimationTrack | Roblox Creator Documentation

You should store each animation within their separate variables. When I say that, I mean having an animation track stored somewhere and placing the ID in there so it’s automatically stored, as well as all that being stored within a variable. Make sure to put this in a local script, and don’t worry, it will run the animations to the server since the changes are not changes within the workspace (please, please, please correct me if I’m wrong). Now, let’s say if a player sprints, you could do


local animation = game.Players.LocalPlayer.Character.Humanoid:LoadAnimation(--put the location of your animation track(s) in here)

--your code here
     yourWalkAnimation:Stop()
     yourRunAnimation:Play()

or vice versa,

yourRunAnimation:Stop()
yourWalkAnimation:Play()

Hopefully this helps, if you need a better explanation, I will be happy to help.

(edit)
just realized, I can’t tell if your animations are overlapping with your custom ones or the roblox ones, or both. If you don’t want the roblox animations, you should just disable the default animations script altogether. While if your custom animations are overlapping, I recommend you try what I said.

Also try setting your custom animation priority to Action, you wouldn’t even have to disable roblox’s default animation if you set your custom ones to action as that prioritizes your animations rather than roblox’s.

I cant really explain it very well, so heres a video i just recorded
robloxapp-20210522-1515183.wmv (2.3 MB)
Basically, the run and walk anims from the animate script are merging now and then the run button is clicked, and the walk animation id changes, then its clicked and instead of it going back to walking, it just ack i cant explain it.

I am trying out a new model for my game, and my strategies and scripts have worked for my old model so idk whats going on.

i can’t really understand what you actually want and what’s the problem but why don’t you just make 2 animations and instead of changing id of a single animation, just :Play() first animation and :Stop() second animation when needed

Honestly I dont know the problem either at this point, however, for me, having to manually switch between which animation plays would be way too hard and changing the walking ids has worked for me. I dont know 100% if the problem is one mess up, or two, I just know that something went REALLY wrong when I was setting up my new character…

Idk if this will help at all but heres the stuff from the animate script

	walk = 	{ 	
		{ id = "http://www.roblox.com/asset/?id=6850398480", weight = 10 } 
			}, 
	run = 	{
		{ id = "http://www.roblox.com/asset/?id=6846184687", weight = 10 } 
			}, 

With the animate script, the “run” is half merging half overriding the “walk” and because the run script relies on the animate scripts “walk”, anything that fudges up in there also would fudge up my run script as well as the walk/run animations in general. If that makes any sense.

It’s not exactly possible for two animations to “half merge” if they’re not a single animation. Unless they’re merging because they’re both playing at the same time.

You would have to stop the animation from playing and run the desired animation, otherwise they would both play and what I’m assuming your problem is, merge.

Store your animation id in an animationTrack and use the :Play() and :Stop() functions. If you don’t do this, your problem will most likely not be fixed. I know you said it would be “way too hard”, but can you specify on why it’s too hard?

If I were to use the :Play()/:Stop() where would I put it? also the problem is that two different animation ids are playing at the same time, even though they haven’t done that ever.

So following up on this, could i do this basically?


local Walk = script.Parent:WaitForChild("Animate").walk.WalkAnim
local Walkanimtrack = Anim:LoadAnimation("Walk") --Anim is the animator, will have been referenced
Walk.AnimationId = "rbxassetid://6850398480"

local Run = script:WaitForChild("Run")
local Runanim = Anim:LoadAnimation(Run)
Run.AnimationId = "rbxassetid://6846184687"

--check for button click/keyboard and stuff

if humanoid.MoveDirection > 0 then --I will have already referenced the humanoid

    if humanoid.WalkSpeed == 16 then
    Runanim:Play()
    humanoid.WalkSpeed = 48
    else
    Walkanimtrack:Play()
   humanoid.WalkSpeed = 16
    end


end

Just an idea of how I could play it, problem is, idk how to stop it without it maybe interfering with what the animate script does, as it basically controls the default animations for the humanoid, including when things stop and start.

EDIT: I disabled the run script and while looking through the animate script for mess ups I might have caused, I found this:

-- 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

You could do that, but you would have to stop the animations that’s already playing by doing :Stop() and then doing :Play() in the next line to prevent them from merging. If they still continue to merge maybe add a wait()

If it does end up interfering with the animation script, you could try to make your own custom one since roblox’s animation script is hard to modify.

Other than that, I wouldn’t see why it would mess with the script if you just did :Stop() for your animations, as all it does is just stops the animation you stop.

I don’t think the problem is with my current run script though, I made it so that it prints the walk animation id when fired, it prints and the id changes. Technically it “works”, it does some form of walk animation when the run is toggled off, the walk animation in general has some legs thrusting upward like its running, which isn’t how I animated it however.

When you animated it, you set the animation priority to action, right?

https://i.gyazo.com/d3877f33d32cb0f13b9179edbeb9abd6.mp4

If you don’t, it’ll prioritize other things rather than just yours. Set it to action and it’ll only play your animation when fired.

Did it using the explorer (idk if it makes a difference), didnt work

So I’ve been digging around and have learned a couple of things: 1: Animation blending is what is causing all of this. 2: It is happening in the animate script, just as I suspected.

3: I think it’s this part here, idk what it is supposed to do though exactly…
line 484-499

-- 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

While researching, I found a 3 year old post on scriptinghelpers that was dealing with the same problem, unfortunately, within the 3 year span, there was not a single reply on the matter.

Yes!! I believed I have fixed it!! I modified something in the animate script, line 574-593:

-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
-- STATE CHANGE HANDLERS

function onRunning(speed)
	local movedDuringEmote =
		userEmoteToRunThresholdChange and currentlyPlayingEmote and Humanoid.MoveDirection == Vector3.new(0, 0, 0)
	local speedThreshold = movedDuringEmote and Humanoid.WalkSpeed or 0.75
	if speed > speedThreshold then
		local scale = 20.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

I remembered a post I found with a problem like this that was basically fixed with playing around with the scale, so I did that! 16 was the default, where the run and walk blended. Anything lower than that would make the run override completely, like at 10. I tried 20, tested in studio, and it seems to have worked!! I feel kinda dumb for not looking over THIS part of the script but- at least it is solved, thx to all that helped!

4 Likes