Moving variable is false when I switch keys

  1. What do you want to achieve? Keep it simple and clear!

I want my RPG movement system to work.

Video of the glitch:

  1. What is the issue? Include screenshots / videos if possible!

The issue is that it thinks I’m not moving when I change from holding A to W. This glitches the animations and makes it look weird.

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

I tried to fiddle with the key systems I used but it had the same result.
I am also using sprites I made in Roblox studio that I made using pixels to draw the character.

My code:

wait()

local ts = game:GetService("TweenService")
local uis = game:GetService("UserInputService")
local rs = game:GetService("RunService")
local player = game:GetService("Players").LocalPlayer
local char = player.Character
local cam = workspace.CurrentCamera

while not char do
	char = player.Character
	wait()
end

local debugui = player.PlayerGui:WaitForChild("Debug")
local pchar = char:WaitForChild("Player")
local spritesheet = pchar:WaitForChild("SpriteSheet")
local pbb = pchar:WaitForChild("PlayerBillBoard")
local ppart = pchar.PrimaryPart
local hum = char:WaitForChild("Humanoid")
local hrp = char:WaitForChild("HumanoidRootPart")
hrp.Anchored = true

local lastkey = "down"
local moving = false
local side = "Down"
local animstep = 1
local frame = 1
local cammode = 1

local frames = spritesheet:GetChildren()

ppart.Position = workspace.Spawn.Position + Vector3.new(0,1,0)

function setframe(f)
	local oldf = pbb:FindFirstChildOfClass("Frame")
	local newf = spritesheet:FindFirstChild(f):Clone()
	if newf then
		oldf:Destroy()
		newf.Parent = pbb
	end
end

function animate(key)
	while moving or uis:IsKeyDown(key) do
		if moving or uis:IsKeyDown(key) then
			if animstep == 1 then
				setframe(side.."Walk".."1")
				animstep = 3
			elseif animstep == 2 then
				setframe(side.."Walk".."2")
				animstep = 1
			elseif animstep == 3 then
				setframe(side.."Idle")
				animstep = 2
			end
		else
			coroutine.yield()
		end
		wait(0.15)
	end
end

function move(key,off)
	while uis:IsKeyDown(key) do
		if uis:IsKeyDown(key) then
			ppart.Position = ppart.Position + Vector3.new(off.x/8,off.y/8,off.z/8)
			rs.RenderStepped:Wait()
		else
			break
		end
	end
end

function controls(key)
	if key == Enum.KeyCode.W then
		moving = true
		lastkey = "up"
		side = "Up"
		move(key,Vector3.new(0,0,-1))
	elseif key == Enum.KeyCode.A then
		moving = true
		lastkey = "left"
		side = "Left"
		move(key,Vector3.new(-1,0,0))
	elseif key == Enum.KeyCode.S then
		moving = true
		lastkey = "down"
		side = "Down"
		move(key,Vector3.new(0,0,1))
	elseif key == Enum.KeyCode.D then
		moving = true
		lastkey = "right"
		side = "Right"
		move(key,Vector3.new(1,0,0))
	else
		lastkey = 0
		moving = false
	end
end


uis.InputBegan:Connect(function(i,p)
	if p then return end
	local key = i.KeyCode
	if key == Enum.KeyCode.W or key == Enum.KeyCode.A or key == Enum.KeyCode.S or key == Enum.KeyCode.D then
		local atrd = coroutine.create(controls)
		coroutine.resume(atrd,key)
		moving = true
		animate(key)
	end
	if key == Enum.KeyCode.E then
		setframe("DownIdle")
	end
end)

uis.InputEnded:Connect(function(i,p)
	if p then return end
	local key = i.KeyCode
	if key == Enum.KeyCode.W or key == Enum.KeyCode.A or key == Enum.KeyCode.S or key == Enum.KeyCode.D then
		moving = false
	end
end)

rs.RenderStepped:Connect(function()
	debugui.Side.Text = "Current Side: "..side
	debugui.Moving.Text = "Moving: "..tostring(moving)
	if cammode == 1 then
		cam.CFrame = CFrame.new(ppart.Position + Vector3.new(0,10,6.5)) * CFrame.Angles(math.rad(-60),0,0)
	end
end)

Alright so the issue is that you are setting moving to false when one of the keys is released. Which does not take the other keys still being pressed into account.

There are many ways to deal with this, but one way would be to check if each key is still pressed before setting moving to false
Same can be applied to detecting your direction.
Something like this:

function check_pressed()
	local keys = {{Enum.KeyCode.W,"Up"},{Enum.KeyCode.A,"Left"},{Enum.KeyCode.S,"Down"},{Enum.KeyCode.D,"Right"}}
	local direction = ""
	for i,keyinfo in pairs(keys) do
		if uis:IsKeyDown(keyinfo[1]) then
			direction = direction..keyinfo[2]
		end
	end
	return direction
end

Which you could then use before setting moving to false on input ended.

if check_pressed() == "" then
	moving = false
end

And you can use the same function in your debugger to detect which way the character is moving.

debugui.Moving.Text = "Moving: "..check_pressed()

It will produce a result something like this:
https://i.gyazo.com/5d73c7369a4fc617eae6da1aba56805e.mp4
Note that I did not bother editing the ‘Current Side’ part at all.

IF YOU HAVE A QUESTION, ASK.

1 Like

Thank you, it now works better.

1 Like