Movement system not behaving properly (possibly ray cast problem)

Ok so, I have a voxel character that likes hops around, and I’m trying to make it where if an object intersects a ray that goes in the direction the voxel is about to hop towards, then it doesn’t move in that direction. It sometimes works, but the ray will detect a part right next to it instead of in front of it sometimes, and other times detect a part diagonal to it.

Here is the entire code, but I believe the problem is in the moveVoxelEnded.OnServerEvent portion, but I’m probably wrong since I’ve been starring at it for like 3 hours.

Code
--[[
Created By: PlantMaker123
Started On: 6/18/2020
Finished On: N/A

Purpose: To move the voxelCharacter Associated 
		with the player.
]]

----Services----

local Players 					= game:GetService("Players")
local TweenService 				= game:GetService("TweenService")
local RepStorage				= game:GetService("ReplicatedStorage")
local Workspace 				= game:GetService("Workspace")


----Assigned Variables----

local playerFolder 				= Workspace.PlayerFolder
local carFolder					= Workspace.CarFolder
local moveVoxel 				= RepStorage.MoveVoxel
local moveVoxelEnded 			= RepStorage.MoveVoxelEnded


----Custom Variables----

local TIME_TO_CROUCH = .3
local CROUCH_HEIGHT = 3.5 --max of 5
local JUMP_HEIGHT = 1 --stud
local JUMP_LENGTH = .3
local MOVEMENT_UPDATE_IN_SEC = 1


----Function----



local crouchHieghtCorrection = (5 - CROUCH_HEIGHT)/2

moveVoxel.OnServerEvent:Connect(function(player, direction, voxel)
	local voxelMesh = voxel.Mesh
	local moveDirection = voxel.Direction
	local isCrouching = voxel.IsCrouching
	local waitForMove = voxel.WaitForMove
	if not waitForMove.Value then
		local crouchTweenInfo = TweenInfo.new(
			TIME_TO_CROUCH, 
			Enum.EasingStyle.Quint, 
			Enum.EasingDirection.Out, 
			0, 
			false, 
			0
		)
		local crouchGoals = {
			Size = Vector3.new(5, CROUCH_HEIGHT, 5)
		}
		local crouchMeshGoals = {
			Scale = Vector3.new(5, CROUCH_HEIGHT, 5)
		}
		
		if direction == "Up" then
			if isCrouching.Value == true then
				crouchGoals.Position = voxel.Position
			else
				crouchGoals.Position = voxel.Position + Vector3.new(0, crouchHieghtCorrection*-1, 0)
			end
			crouchGoals.Orientation = Vector3.new(0,0,0)
			local tween = TweenService:Create(voxel, crouchTweenInfo, crouchGoals)
			local meshTween = TweenService:Create(voxelMesh, crouchTweenInfo, crouchMeshGoals)
			tween:Play()
			meshTween:Play()
			isCrouching.Value = true
			moveDirection.Value = "Up"
		
		elseif direction == "Down" then
			if isCrouching.Value == true then
				crouchGoals.Position = voxel.Position
			else
				crouchGoals.Position = voxel.Position + Vector3.new(0, crouchHieghtCorrection*-1, 0)
			end
			if moveDirection.Value == "Down" then
				print("hey")
				crouchGoals.Orientation = nil
			else
				crouchGoals.Orientation = Vector3.new(0, 180, 0)
			end
			local tween = TweenService:Create(voxel, crouchTweenInfo, crouchGoals)
			local meshTween = TweenService:Create(voxelMesh, crouchTweenInfo, crouchMeshGoals)
			tween:Play()
			meshTween:Play()
			isCrouching.Value = true
			moveDirection.Value = "Down"
		
		elseif direction == "Right" then
			if isCrouching.Value == true then
				crouchGoals.Position = voxel.Position
			else
				crouchGoals.Position = voxel.Position + Vector3.new(0, crouchHieghtCorrection*-1, 0)
			end
			crouchGoals.Orientation = Vector3.new(0,-90,0)
			local tween = TweenService:Create(voxel, crouchTweenInfo, crouchGoals)
			local meshTween = TweenService:Create(voxelMesh, crouchTweenInfo, crouchMeshGoals)
			tween:Play()
			meshTween:Play()
			isCrouching.Value = true
			moveDirection.Value = "Right"
		
		elseif direction == "Left" then
			if isCrouching.Value == true then
				crouchGoals.Position = voxel.Position
			else
				crouchGoals.Position = voxel.Position + Vector3.new(0, crouchHieghtCorrection*-1, 0)
			end
			crouchGoals.Orientation = Vector3.new(0,90,0)
			local tween = TweenService:Create(voxel, crouchTweenInfo, crouchGoals)
			local meshTween = TweenService:Create(voxelMesh, crouchTweenInfo, crouchMeshGoals)
			tween:Play()
			meshTween:Play()
			isCrouching.Value = true
			moveDirection.Value = "Left"
		end
	end
end)

moveVoxelEnded.OnServerEvent:Connect(function(player, direction, voxel)
	local voxelMesh = voxel.Mesh
	local moveDirection = voxel.Direction
	local hit = voxel.Hit
	local isCrouching = voxel.IsCrouching
	local waitForMove = voxel.WaitForMove
	if not waitForMove.Value then
		waitForMove.Value = true
		print(voxel.Position)
		--rays
		local confirmMoveUp = Ray.new(voxel.Position, voxel.Position + Vector3.new(0, 0, -5))
		local confirmMoveDown = Ray.new(voxel.Position, voxel.Position + Vector3.new(0, 0, 5))
		local confirmMoveRight = Ray.new(voxel.Position, voxel.Position + Vector3.new(5, 0, 0))
		local confirmMoveLeft = Ray.new(voxel.Position, voxel.Position + Vector3.new(-5, 0, 0))
		--Creates Ignore table for ray
		local ignoreRayList = carFolder:GetChildren()
		table.insert(ignoreRayList, 1, voxel)
		--TweenInfo and Goals
		local standTweenInfo = TweenInfo.new(
			.01, 
			Enum.EasingStyle.Linear, 
			Enum.EasingDirection.Out, 
			0, 
			false, 
			0
		)
		local standGoals = {
			Size = Vector3.new(5, 5, 5);
			Position = Vector3.new(voxel.Position.X, 0, voxel.Position.Z)
		}
		local standMeshGoals = {
			Scale = Vector3.new(5, 5, 5)
		}
		
		if moveDirection.Value == "Up" and direction == "Up" then
			hit.Value = game.Workspace:FindPartOnRayWithIgnoreList(confirmMoveUp, ignoreRayList)
			standGoals.Orientation = Vector3.new(0,0,0)
			local tween = TweenService:Create(voxel, standTweenInfo, standGoals)
			local meshTween = TweenService:Create(voxelMesh, standTweenInfo, standMeshGoals)
			tween:Play()
			meshTween:Play()
			print(hit.Value)
			if not hit.Value then
				tween.Completed:Connect(function()
					for i = 1/MOVEMENT_UPDATE_IN_SEC, 5, 1/MOVEMENT_UPDATE_IN_SEC  do
						local y = -.16*i^2+.8*i
						voxel.Position = Vector3.new(voxel.Position.X, y, voxel.Position.Z - 1/MOVEMENT_UPDATE_IN_SEC)
						wait(.0025)
					end
					waitForMove.Value = false
					isCrouching.Value = false
				end)
			else
				waitForMove.Value = false
				isCrouching.Value = false
			end
			
			
		elseif moveDirection.Value == "Down" and direction == "Down" then
			hit.Value = game.Workspace:FindPartOnRayWithIgnoreList(confirmMoveDown, ignoreRayList)
			if moveDirection.Value == "Down" then
				print("hey")
				standGoals.Orientation = nil
			else
				standGoals.Orientation = Vector3.new(0,180,0)
			end
			local tween = TweenService:Create(voxel, standTweenInfo, standGoals)
			local meshTween = TweenService:Create(voxelMesh, standTweenInfo, standMeshGoals)
			tween:Play()
			meshTween:Play()
			print(hit.Value)
			if not hit.Value then
				tween.Completed:Connect(function()
					for i = 1/MOVEMENT_UPDATE_IN_SEC, 5, 1/MOVEMENT_UPDATE_IN_SEC  do
						local y = -.16*i^2+.8*i
						voxel.Position = Vector3.new(voxel.Position.X, y, voxel.Position.Z + 1/MOVEMENT_UPDATE_IN_SEC)
						wait(.0025)
					end
					waitForMove.Value = false
					isCrouching.Value = false
				end)
			else
				waitForMove.Value = false
				isCrouching.Value = false
			end
			
		elseif moveDirection.Value == "Right" and direction == "Right" then
			hit.Value = game.Workspace:FindPartOnRayWithIgnoreList(confirmMoveRight, ignoreRayList)
			standGoals.Orientation = Vector3.new(0,270,0)
			local tween = TweenService:Create(voxel, standTweenInfo, standGoals)
			local meshTween = TweenService:Create(voxelMesh, standTweenInfo, standMeshGoals)
			tween:Play()
			meshTween:Play()
			print(hit.Value)
			if not hit.Value then
				tween.Completed:Connect(function()
					for i = 1/MOVEMENT_UPDATE_IN_SEC, 5, 1/MOVEMENT_UPDATE_IN_SEC  do
						local y = -.16*i^2+.8*i
						voxel.Position = Vector3.new(voxel.Position.X + 1/MOVEMENT_UPDATE_IN_SEC, y, voxel.Position.Z)
						wait(.0025)
					end
					waitForMove.Value = false
					isCrouching.Value = false
				end)
			else
				waitForMove.Value = false
				isCrouching.Value = false
			end
			
		elseif moveDirection.Value == "Left" and direction == "Left" then
			hit.Value = game.Workspace:FindPartOnRayWithIgnoreList(confirmMoveLeft, ignoreRayList)
			standGoals.Orientation = Vector3.new(0,90,0)
			local tween = TweenService:Create(voxel, standTweenInfo, standGoals)
			local meshTween = TweenService:Create(voxelMesh, standTweenInfo, standMeshGoals)
			tween:Play()
			meshTween:Play()
			print(hit.Value)
			if not hit.Value then
				tween.Completed:Connect(function()
					for i = 1/MOVEMENT_UPDATE_IN_SEC, 5, 1/MOVEMENT_UPDATE_IN_SEC  do
						local y = -.16*i^2+.8*i
						voxel.Position = Vector3.new(voxel.Position.X - 1/MOVEMENT_UPDATE_IN_SEC, y, voxel.Position.Z)
						wait(.0025)
					end
					waitForMove.Value = false
					isCrouching.Value = false
				end)
			else
				waitForMove.Value = false
				isCrouching.Value = false
			end
		else
			waitForMove.Value = false
		end
	end
end)

Some more info on the code: A local script on the player sends the player input along with the player object as the parameter.

And a visual representation for you:

FYI, it doesn’t show it in the video, but the character is able to go back to the starting position.

I thought the ray casted in the direction of a global point, not a point relative to the first parameter. The solution was just to get rid of the voxel.Position + in the 2nd parameter so just the Vector3.new() remained in all the rays.