How can you check which side a player is touching?

I want to make a wall jump system which the player has touch the wall and face the sides or the back of the character.
I can get how to check if the guy is touching the wall, but I don’t get how to check which side the character of the player is touching.
For now I used raycast before to achieve this, but I think this is this is not a good way.

while true do
	local humanoidState = humanoid:GetState()
	humanoid.Touched:Connect(function(Ispart)
		if (Ispart:IsA("Part") and fallCheck()) then
			print("is falling")
			-- Creating a Ray for ground detection
			local origin = character.HumanoidRootPart.Position
			local direction = Vector3.new(0, -4, 0) -- Ray goes down
			local params = RaycastParams.new()
			params.FilterType = Enum.RaycastFilterType.Exclude
			params.FilterDescendantsInstances = {character}
			local raycastResult = workspace:Raycast(origin, direction, params)
			task.wait(0.4)
			if raycastResult and raycastResult.Instance then
				print("cant climb", Ispart.Name)
			else
				print("can climb", Ispart.Name)
			end
		end
	end)
	task.wait()
end

I believe raycasting also returns the normal of the surface it hit, and you can use that to either calculate the angle of the face or the face of the part

Rereading your post do you mean to calculate the angle between what the player is looking at and the wall it is touching? Like if the player was perfectly facing the wall compared to if they are 45 degrees to it?

I guess that was what I was initially trying to do when I first made this, but the code I post there was for another project with a similar idea. I am for now using the same code but for the front, but it has too many grey areas which does not give a clear result, like if it can climb or not. This is the reason why Im saying raycasting is not a good way to do this, and Im asking for a better way to do this than raycasting.

I would really thank you for some guidance because this is the best I can come up with using the existing posts and youtube.

For a hacky but working way, you can always just make parts in the character and check which one it touches, but if u insist on using raycasting, you can use the player’s character lookvector and rightvector to cast rays in all four directions:

local function detectWall()
	if humanoid:GetState() ~= Enum.HumanoidStateType.Freefall then
		return "none"
	end

	local origin = rootPart.Position
	local cf = rootPart.CFrame

	local rayParams = RaycastParams.new()
	rayParams.FilterType = Enum.RaycastFilterType.Exclude
	rayParams.FilterDescendantsInstances = {character}

	local rayDistance = 3
	local rays = {
		front = {direction = cf.LookVector * rayDistance, side = "front"},
		back = {direction = -cf.LookVector * rayDistance, side = "back"},
		right = {direction = cf.RightVector * rayDistance, side = "right"},
		left = {direction = -cf.RightVector * rayDistance, side = "left"}
	}

	for _, rayData in pairs(rays) do
		local rayResult = workspace:Raycast(origin, rayData.direction, rayParams)

		if rayResult then
			local normal = rayResult.Normal

			local wallAngle = math.deg(math.acos(math.abs(normal:Dot(Vector3.new(0, 1, 0)))))

			if wallAngle >= 45 then
				if rayResult.Distance <= 2.5 then
					return rayData.side, rayResult.Instance, rayResult.Normal
				end
			end
		end
	end

	return "none"
end

This way you get proper directional detection and can filter out floors/ceilings by checking the surface angle. The normal vector also lets you calculate proper wall jump direction.

Roblox doesn’t give you this directly, but here’s a practical way to do it:


The Basic Idea

Every part has six faces: front, back, left, right, top, bottom.

When the player touches the part, you get their position (or the position of the part that touched).

You compare this position to the center points of each face.

The face with the smallest distance to the player is probably the one being touched.


How To Do It (Example)

Here’s a simple function you can use. Plug in the position you want to check (like the player’s HumanoidRootPart.Position) and the part they’re touching:

function getClosestFace(pos, part)
    local faces = {
        Top = part.CFrame * CFrame.new(0, part.Size.Y/2, 0),
        Bottom = part.CFrame * CFrame.new(0, -part.Size.Y/2, 0),
        Front = part.CFrame * CFrame.new(0, 0, -part.Size.Z/2),
        Back = part.CFrame * CFrame.new(0, 0, part.Size.Z/2),
        Right = part.CFrame * CFrame.new(part.Size.X/2, 0, 0),
        Left = part.CFrame * CFrame.new(-part.Size.X/2, 0, 0),
    }
    local closest = nil
    local minDist = math.huge
    for face, cframe in pairs(faces) do
        local dist = (pos - cframe.Position).Magnitude
        if dist < minDist then
            minDist = dist
            closest = face
        end
    end
    return closest
end

Usage Example:

local playerPos = player.Character.HumanoidRootPart.Position
local touchedPart = -- the part the player touched
local side = getClosestFace(playerPos, touchedPart)
print("Player is touching the", side, "side")


Real Talk

This works best if the player is actually near the part’s surface—not floating in the middle of nowhere.

It’s not perfect at corners or edges, but for most uses (like buttons, doors, etc.), it does the job.

If you want pixel-perfect accuracy, you’ll need more complex math, but honestly, this is good enough for 99% of games.


Let me know if you need further help or have informations!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.