8 Way Directional Movement

I’m trying to make a 8 way directional system, I made a 4 way one but the 8 way one just wont work,
any help is appreciated, here is the 4 way directional walking system that works:

local animationFolder = game:GetService("ReplicatedStorage"):FindFirstChild("Animations")

if not animationFolder then
	error("Animations folder not found")
end

local walkForwardAnim = animationFolder:FindFirstChild("WalkForwardR6")
local walkBackwardAnim = animationFolder:FindFirstChild("WalkBackwardR6")
local walkLeftAnim = animationFolder:FindFirstChild("WalkLeftR6")
local walkRightAnim = animationFolder:FindFirstChild("WalkRightR6")

if not walkForwardAnim or not walkBackwardAnim or not walkLeftAnim or not walkRightAnim then
	error("One or more walk animations not found")
end

local humanoid = game.Players.LocalPlayer.Character:WaitForChild("Humanoid")
local animator = humanoid.Animator

local animationControllers = {}

local function playAnimation(animation)
	local animationController = animationControllers[animation.Name]

	if not animationController then
		animationController = animator:LoadAnimation(animation)
		animationControllers[animation.Name] = animationController
	end

	if animationController.IsPlaying then
		return animationController
	end

	animationController:Play()
	animationController:GetMarkerReachedSignal("End"):Connect(function()
		animationController:Stop()
	end)

	return animationController
end

local function stopAnimation(animationController)
	if animationController then
		animationController:Stop()
	end
end

local function getMoveDirection()
	local rootPart = humanoid.RootPart
	local forwardDirection = rootPart.CFrame.LookVector
	local rightDirection = rootPart.CFrame.RightVector

	local moveDirection = forwardDirection * humanoid.MoveDirection.Z + rightDirection * humanoid.MoveDirection.X

	return moveDirection.Unit
end


local function applyMotionR6(rootPart, moveDirection)
	local x = moveDirection.X
	local y = moveDirection.Y
	local z = moveDirection.Z

	if y > 0 then
		rootPart.Velocity = Vector3.new(x * 16, y * 40, z * 16)
	else
		rootPart.Velocity = Vector3.new(x * 16, 0, z * 16)
	end

	rootPart.CFrame = rootPart.CFrame + Vector3.new(x * 16, 0, z * 16)
end

game:GetService("RunService").Heartbeat:Connect(function()
	local moveDirection = getMoveDirection()

	if moveDirection.Magnitude > 0 then
		humanoid.WalkSpeed = 16

		local dotForward = moveDirection:Dot(Vector3.new(0, 0, -1))
		local dotBackward = moveDirection:Dot(Vector3.new(0, 0, 1))
		local dotLeft = moveDirection:Dot(Vector3.new(-1, 0, 0))
		local dotRight = moveDirection:Dot(Vector3.new(1, 0, 0))

		local currentAnimationController = nil

		if dotForward > 0.5 then
			stopAnimation(animationControllers["WalkBackwardR6"])
			stopAnimation(animationControllers["WalkLeftR6"])
			stopAnimation(animationControllers["WalkRightR6"])
			currentAnimationController = playAnimation(walkForwardAnim)
		elseif dotBackward > 0.5 then
			stopAnimation(animationControllers["WalkForwardR6"])
			stopAnimation(animationControllers["WalkLeftR6"])
			stopAnimation(animationControllers["WalkRightR6"])
			currentAnimationController = playAnimation(walkBackwardAnim)
		elseif dotLeft > 0.5 then
			stopAnimation(animationControllers["WalkForwardR6"])
			stopAnimation(animationControllers["WalkBackwardR6"])
			stopAnimation(animationControllers["WalkRightR6"])
			currentAnimationController = playAnimation(walkLeftAnim)
		elseif dotRight > 0.5 then
			stopAnimation(animationControllers["WalkForwardR6"])
			stopAnimation(animationControllers["WalkBackwardR6"])
			stopAnimation(animationControllers["WalkLeftR6"])
			currentAnimationController = playAnimation(walkRightAnim)
		end
		if currentAnimationController then
			currentAnimationController.Priority = Enum.AnimationPriority.Movement
		end
	else
		humanoid.WalkSpeed = 0
		stopAnimation(animationControllers["WalkForward"])
		stopAnimation(animationControllers["WalkBackward"])
		stopAnimation(animationControllers["WalkLeft"])
		stopAnimation(animationControllers["WalkRight"])
	end
end)

Here is the 8 way directional walking system that encountered some weird issues:

local animationFolder = game:GetService("ReplicatedStorage"):FindFirstChild("Animations")

if not animationFolder then
	error("Animations folder not found")
end

local walkForwardAnim = animationFolder:FindFirstChild("WalkForwardR6")
local walkBackwardAnim = animationFolder:FindFirstChild("WalkBackwardR6")
local walkLeftAnim = animationFolder:FindFirstChild("WalkLeftR6")
local walkRightAnim = animationFolder:FindFirstChild("WalkRightR6")
local walkForwardLeftAnim = animationFolder:FindFirstChild("WalkForwardLeftR6")
local walkForwardRightAnim = animationFolder:FindFirstChild("WalkForwardRightR6")
local walkBackwardLeftAnim = animationFolder:FindFirstChild("WalkBackwardLeftR6")
local walkBackwardRightAnim = animationFolder:FindFirstChild("WalkBackwardRightR6")

if not walkForwardAnim or not walkBackwardAnim or not walkLeftAnim or not walkRightAnim then
	error("One or more walk animations not found")
end

local humanoid = game:GetService("Players").LocalPlayer.Character:WaitForChild("Humanoid")
local animator = humanoid.Animator

local animationControllers = {}

local function playAnimation(animation)
	local animationController = animationControllers[animation.Name]

	if not animationController then
		animationController = animator:LoadAnimation(animation)
		animationControllers[animation.Name] = animationController
	end

	if animationController.IsPlaying then
		return animationController
	end

	animationController:Play()
	animationController:GetMarkerReachedSignal("End"):Connect(function()
		animationController:Stop()
	end)

	return animationController
end

local function stopAnimation(animationController)
	if animationController then
		animationController:Stop()
	end
end

local function getMoveDirection()
	local rootPart = humanoid.RootPart
	local forwardDirection = rootPart.CFrame.LookVector
	local rightDirection = rootPart.CFrame.RightVector

	local moveDirection = forwardDirection * humanoid.MoveDirection.Z + rightDirection * humanoid.MoveDirection.X

	return moveDirection.Unit
end

local function applyMotionR6(rootPart, moveDirection)
	if not rootPart then
		return
	end

	local humanoid = rootPart.Parent:FindFirstChildOfClass("Humanoid")
	if not humanoid then
		return
	end

	humanoid.MoveDirection = moveDirection
	rootPart.CFrame = rootPart.CFrame + moveDirection * humanoid.WalkSpeed / 60
end

game:GetService("RunService").Heartbeat:Connect(function()
	local rootPart = humanoid.Parent:FindFirstChild("Torso")
	if not rootPart then
		return
	end

	local moveDirection = getMoveDirection()

	if moveDirection and moveDirection.Magnitude > 0 then
		humanoid.WalkSpeed = 16

		local dotForward = moveDirection:Dot(Vector3.new(0, 0, -1))
		local dotBackward = moveDirection:Dot(Vector3.new(0, 0, 1))
		local dotLeft = moveDirection:Dot(Vector3.new(-1, 0, 0))
		local dotRight = moveDirection:Dot(Vector3.new(1, 0, 0))

		local currentAnimationController = nil

		if dotForward > 0 then
			if dotRight > 0.5 then
				-- Forward-Right
				print("ForwardRight")
				playAnimation(walkForwardRightAnim)
			elseif dotLeft > 0.5 then
				-- Forward-Left
				print("ForwardLeft")
				playAnimation(walkForwardLeftAnim)
			else
				-- Forward
				print("Forward")
				playAnimation(walkForwardAnim)
			end
		elseif dotForward < 0 then
			if dotRight > 0.5 then
				-- Backward-Right
				print("BackwardRight")
				playAnimation(walkBackwardRightAnim)
			elseif dotLeft > 0.5 then
				-- Backward-Left
				print("BackwardLeft")
				playAnimation(walkBackwardLeftAnim)
			else
				-- Backward
				print("Backward")
				playAnimation(walkBackwardAnim)
			end
		else
			if dotRight > 0.5 then
				-- Right
				print("Right")
				playAnimation(walkRightAnim)
			elseif dotLeft > 0.5 then
				-- Left
				print("Left")
				playAnimation(walkLeftAnim)
			else
				-- Idle
				stopAnimation(playAnimation(walkForwardAnim))
			end
		end

		applyMotionR6(humanoid.RootPart, moveDirection)
	else
		humanoid.WalkSpeed = 0
		stopAnimation(playAnimation(walkForwardAnim))
	end
end)
  1. Instead of detecting that the player is moving to the right or left it prints “BackwardLeft” or “BackwardRight” or “ForwardRight” or “ForwardLeft” in other words it thinks i’m going diagonally when im going right or left.
  2. I don’t want it to detect in which direction the player is headed to using the camera which it currently uses I think, I also don’t want it to use key inputs.
  3. I encountered a error that says: “Unable to assign property MoveDirection. Property is read only” I have no idea what “Property is read only” is.

It got solved in this post: 8 Way Directional Walking System

1 Like