Best Way To Go About Directional Movement System (R6)

Hello. I have recently started working on a soccer game, and I am trying to implement a directional movement system. (where your animation changes according to what w/a/s/d keys you have down in shift lock) I have previously made a system like this, but I’ve now ran into the following issues:
Firstly, due to the several amount of animations, if I implement this into the default animate script, spamming different keys causes the animations to look weird, as they glitch together.
Lerping doesn’t work because after lerping when you stop moving the character looks weird for a bit before returning to the idle animation. Also as I am making a soccer game, I need more customization as the ball must roll differently.
Even if I combine them, the lerping issue persists. I was wondering what the best way to go about this would be.

2 Likes

I was looking for a way to avoid these bugs and I asked chatgpt and it gave me this:

local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")

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

local AnimationIds = {
	W  = "rbxassetid://92017029269100",
	S  = "rbxassetid://89561096413698",
	A  = "rbxassetid://92017029269100",
	D  = "rbxassetid://92017029269100",
	WA = "rbxassetid://92017029269100",
	WD = "rbxassetid://92017029269100",
	SA = "rbxassetid://92017029269100",
	SD = "rbxassetid://92017029269100",
}

local tracks = {}
for key, id in pairs(AnimationIds) do
	local anim = Instance.new("Animation")
	anim.AnimationId = id
	tracks[key] = humanoid:LoadAnimation(anim)
end

local keysDown = {
	W = false,
	A = false,
	S = false,
	D = false,
}

local currentTrack

local function isShiftLocked()
	return UserInputService.MouseBehavior == Enum.MouseBehavior.LockCenter
end

local function updateAnimation()
	if not isShiftLocked() then
		if currentTrack then
			currentTrack:Stop(0.15)
			currentTrack = nil
		end
		return
	end

	local dir = ""

	if keysDown.W then dir ..= "W" end
	if keysDown.S then dir ..= "S" end
	if keysDown.A then dir ..= "A" end
	if keysDown.D then dir ..= "D" end

	if dir == "AW" then dir = "WA" end
	if dir == "DW" then dir = "WD" end
	if dir == "AS" then dir = "SA" end
	if dir == "DS" then dir = "SD" end

	local track = tracks[dir]

	if track ~= currentTrack then
		if currentTrack then
			currentTrack:Stop(0.1)
		end
		currentTrack = track
		if currentTrack then
			currentTrack:Play(0.1, 1, 1)
		end
	end
end

UserInputService.InputBegan:Connect(function(input, gpe)
	if gpe then return end
	if input.KeyCode == Enum.KeyCode.W then keysDown.W = true end
	if input.KeyCode == Enum.KeyCode.A then keysDown.A = true end
	if input.KeyCode == Enum.KeyCode.S then keysDown.S = true end
	if input.KeyCode == Enum.KeyCode.D then keysDown.D = true end
	updateAnimation()
end)

UserInputService.InputEnded:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.W then keysDown.W = false end
	if input.KeyCode == Enum.KeyCode.A then keysDown.A = false end
	if input.KeyCode == Enum.KeyCode.S then keysDown.S = false end
	if input.KeyCode == Enum.KeyCode.D then keysDown.D = false end
	updateAnimation()
end)

RunService.RenderStepped:Connect(updateAnimation)

I was wondering if there was any big problems with this or issues. I can’t test it out right now but I can’t think of an issue on paper.