My sprites system freezes when making certain movements, how do I improve/fix this script?

PLEASE HELP! I’ve been trying to wrap my head around this for so long but I can’t seem to get to the bottom of it! `:(

What do I want to do?

I’ve been working on a true 2.5D game that will have sprite-based characters mixed with 3D environments using BillBoardGuis. I’m trying to get the character sprites to function properly, just like they would on another engine.

Issue?

  1. Sometimes, when changing directions abruptly, it will only change frame to the standing position, despite the prints and the script saying everything else. There are no sort of weird wait()s or anything that could possibly make this happen.

  2. I would also love to know if there is any way to fix the weird behaviour that occurs when the Player tries to press two keys at once.

Video demonstarting issue 1:

Video demonstrating issue 2:

Here is the script and the Place file (the MovementScript is under StarterPlayerScripts)!

game.rbxl (80.1 KB)

--[[
All are negative.
Steps are in X axis and changed every .9
0, 0.9, 1.8

Directions are in Y axis and changed every 1
0,1,2,3

]]
-- (PLEASE IGNORE COMMENTED CODE BELOW HERE, I'M THE TYPE TO "SAVE EVERYTHING IN CASE", BUT RIGHT NOW THE COMMENTS SERVE 0 PURPOSE)

local TweenService = game:GetService("TweenService")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local ContextActionService = game:GetService("ContextActionService")

local plr = game.Players.LocalPlayer

while not plr.Character do
	wait()
	Character = plr.Character
end

-- // Sp means spritesheet
local spBillboard:BillboardGui = plr.Character:WaitForChild("HumanoidRootPart").SpriteBillboard
local spImage:ImageLabel = spBillboard.Sprite
--local spCurrentDirection = nil

-- // Directions
local Direction_Backward = 0
local Direction_Left = -1
local Direction_Right = -2
local Direction_Forward = -3

-- // Steps
local StepSize = .9 -- The Step size: This is also the middle of the image, where the character is stationary.
local MaxStep = -2 -- Starts at 0
local STEP_CENTER = -.9

-- // Speed
local FRAME_SPEED = .2 -- Time to wait between frames: Less time = faster

--local LoopSprites = false
--local AmountOfAnimationsPlaying = 0

function LoopingFrameStop()
	--LoopSprites = false
	spImage.Position = UDim2.fromScale(STEP_CENTER, spImage.Position.Y.Scale)
	--AmountOfAnimationsPlaying -= 1
end

function LoopFrame(CurrentDirection)
	--AmountOfAnimationsPlaying +=1
	--spCurrentDirection = CurrentDirection
	--CurrentDirection = spCurrentDirection
	--LoopSprites = true
	
	--if AmountOfAnimationsPlaying > 1 then
	--	return
	--end
	
	local Step = 0
	local Count = 0 -- The count variable is for the character on the spritesheet to do the standing position in bewteen walking cycles. Otherwise it looks odd!
	while true do
		if Step < MaxStep and Count > 3 then 
			Step = 0 
			Count = 0 
		end
		print(`Step: {Step}`)
		print(`Count: {Count}`)
		
		if Count == 3 then
			--print("SPECIAL MIDDLE")
			spImage.Position = UDim2.fromScale(STEP_CENTER, CurrentDirection)
		else
			spImage.Position = UDim2.fromScale(Step, CurrentDirection)
		end
		print(`{spImage.Position}`)
		task.wait(FRAME_SPEED)
		Step -= StepSize
		Count += 1
	end
end


--function UpdateSprite(actionName, inputState)
--	if actionName == "Forward" then
--		if inputState == Enum.UserInputState.Begin then
--			--print("MovementHandler :: Started pressing Forward key")
--			LoopFrame(Direction_Forward)
--		else
--			--print("MovementHandler :: Stopped pressing Forward key")

--			LoopSprites = false
--			spImage.Position = UDim2.fromScale(STEP_CENTER, Direction_Forward)
--		end
--	end
--end

--ContextActionService:BindAction("Forward",UpdateSprite,false,Enum.KeyCode.W)

UserInputService.InputBegan:Connect(function(input)
	--if LoopSprites == true then return end
	
	if input.KeyCode == Enum.KeyCode.W then
		--spCurrentDirection = Direction_Forward
		
		W_task = task.spawn(function()
			LoopFrame(Direction_Forward)
		end)
		
	elseif input.KeyCode == Enum.KeyCode.S then
		--spCurrentDirection = Direction_Backward
		
		S_task = task.spawn(function()
			LoopFrame(Direction_Backward)
		end)
		
	elseif input.KeyCode == Enum.KeyCode.A then
		--spCurrentDirection = Direction_Left
		
		A_task = task.spawn(function()
			LoopFrame(Direction_Left)
		end)
		
	elseif input.KeyCode == Enum.KeyCode.D then
		--spCurrentDirection = Direction_Right
		
		D_task = task.spawn(function()
			LoopFrame(Direction_Right)
		end)
		
	end
end)

UserInputService.InputEnded:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.W then
		task.cancel(W_task)
		LoopingFrameStop()
	elseif input.KeyCode == Enum.KeyCode.S then
		task.cancel(S_task)
		LoopingFrameStop()
	elseif input.KeyCode == Enum.KeyCode.A then
		task.cancel(A_task)
		LoopingFrameStop()
	elseif input.KeyCode == Enum.KeyCode.D then
		task.cancel(D_task)
		LoopingFrameStop()
	end
	
end)
2 Likes