My character runs in Place

Is the animation looped? This is likely your problem.

Also, because it just plays an animation on running, if the animation still is playing when you let it go, it will look unnatural. If you want to fix that, stop the animation on InputEnded event if the animation is still playing with animation:Stop().

So should I make the animation not looped?

Yes, you are not stopping the animation ever in the code, it would be obvious to not set it looped if you can’t stop it.

Using GetState in my cases have proven to be very unreliable if you want to make the character stop the animation when you’re still, I’d recommend the Running event and checking if the speed is 0.

Can you please give an example of how to do so? I checked the roblox developer site and still coludn’t really understand how to use it for the player to run while his speed is not 0

And I have tried unlooping it but the character just runs for a couple of seconds and then stop

Checking for the velocity of the player’s HumanoidRootPart would suffice. Example:


local uis = game:GetService("UserInputService")
local character = game.Players.LocalPlayer.Character;
local root = character:WaitForChild("Humanoid");



local run = game:GetService("RunService");

run.RenderStepped:Connect(function(dt)
    uis.InputBegan:Connect(function(inp, gpe)
        if gpe then return; end

        if not (root.Velocity.Magnitude > 0) then runAnim:Stop(); return; end;

        if inp.KeyCode == Enum.KeyCode.K then
           
           if runAnim.IsPlaying then return; end
           if final.IsPlaying then return; end

           runAnim:Play();
           final:Play();
       end
    end)

    uis.InputEnded:Connect(function(inp, gpe)
        if gpe then return; end

        if inp.KeyCode == Enum.KeyCode.K then
            if runAnim.IsPlaying or final.IsPlaying then return; end

            runAnim:Stop(); final:Stop();
        end
    end
end

this may not be the best method, but it works (haven’t tested it yet though)

(I used final for tween service)

change final.IsPlaying to final.PlaybackState == Enum.PlaybackState.Playing or final.PlaybackState.Completed

Optionally, you can shorten these by defining a variable with it

local playing = Enum.PlaybackState.Playing;
local completed = Enum.PlaybackState.Completed;

What do you mean?

If you mean how it looks unnatural because it doesn’t stop when you stop holding the shift button, you have to manually stop it with InputEnded event connected function as I said before.

I’ve experienced this issue before, the problem is that the animation still plays even when the player isn’t moving, which is clearly unwanted. So while my solution may not be the best or well-optimised, I’m pretty certain it’d work

Here’s how I’d do it.

local UserInputService = game:GetService("UserInputService")

local player = game:GetService("Players").LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
character:WaitForChild("Humanoid")

local sprinting = false

UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if gameProcessed then
		return
	end
	
	if (input.KeyCode == Enum.KeyCode.LeftShift and (UserInputService:IsKeyDown(Enum.KeyCode.W)) and not sprinting then
		sprinting = true
		print("Start running!")
		
		local running = nil
		running = character.Humanoid.Running:Connect(function(speed)
			if speed < 1 then
				print("Stop running!")
				sprinting = false
				running:Disconnect()
			end
		end)
	end
	
end)

Checking every frame just for a simple sprint script is horribly inefficient, you should always look for other methods before you use a loop.

This may be considered inefficient to some people, but if you’re using a localscript you can use Humanoid.MoveDirection to determine whether the player’s moving or not.

For instance:

local Hum = Character:WaitForChild("Humanoid")
game:GetService("RunService").RenderStepped:Connect(function()
if Hum.MoveDirection == Vector3.new(0,0,0) then
-- not moving
else
-- moving
end
end)

While it is extremely inefficient, it actually causes no issues at all, especially since it is on the client.

Also, your method relies on mostly on UIS, which also makes inefficient. W is a game-processed event. (not sure about this one)

I fail to see your point on how my code is “inefficient”, when it’s leagues more efficient than creating event connections every single frame, which would cause a memory leak.You should generally use RenderStepped for creating camera systems. I used IsKeyDown as it’s a very simple method.

Would you also mind linking a source as to ‘W’ being a game processed event?

I’m not sure what you mean by inefficient but creating a new connection under renderstepped event is much more of an issue. Please take a look at memory leaks and don’t go calling methods and functions “inefficient” without any explanations why.

This does not need to run every RenderStepped. Why are you looping when you’re listening to events? I have so many questions and so many things I could add, but this is BEYOND inefficient to the point of real harm.

Connecting the same event again and again (in RS) seems quite dangerous, much more inefficient than xKai’s one (not saying xKai’s one is inefficient).

Oh, anyway, if you think UIS is inefficient, what are you going to use for user input? GuiObject.InputBegan? CAS?

Your comment is quite harsh, by the way, have you researched on what you were saying?

Apparently I mixed Dracolyx with your code, I meant to reply to his which it included MoveDirection and RenderStepped when I found out about yours, turns out I actually replied to the wrong person and the wrong code since I was half-awake at this time, my bad