Issue with custom character controller

I am currently writing my own character controller, and first I am implementing the collider with raycasting. I have this cylinder that can collide with walls and floors and can move around with a velocity vector. What I am trying to do now is make the collider slide a long a wall it’s currently colliding with. So if you were running into a wall that was a bit rotated, or you were a bit rotated, you’d begin horizontally sliding along the wall.

I cannot get the correct projected vector for achieving this. The Unity engine has a built in Vector function to deal with this sort of projection. Vector3.ProjectOnPlane, of course Roblox lacks this sort of method, so I’m attempting to write my own implementation of it. It works perfectly fine when the walls is axis aligned, but as soon as I rotate it, it gives me the wrong vector.

I’ve looked up many solutions to this issue, I found the math behind Unity’s implementation of this method, so I implemented it as such:

local function SurfaceProjection(v,n) 
-- v is direction of movement, n is the surface normal of the wall
	local num = n:Dot(n)
	local project = n * v:Dot(n)/num
	return v - project
end

This results in this behavior shown in the video. I also looked up the math behind projecting a vector, and I implemented it as such, and it still does the same thing.

local function SurfaceProjection(v,n)
-- v is direction of movement, n is the surface normal of the wall
	local right = n:Cross(vert) -- vert == Vector3.new(0,1,0)
	local up = n:Cross(right)

	return right*(right:Dot(v)) + up*(up:Dot(v))
end

I’ve seen one single dev forum post that mentions this but doesn’t go into how it was done.

2 Likes

Oh my lord, I am blind. The reason it wasn’t working was because for some reason I was getting the absolute value of the normal instead of the actual normal.

Hey sorry if this comment is off topic and for replying to an old post. I’m also developing my own custom character controller and need to implement ProjectOnPlane for slope movement. That’s how I found this post.

However I was curious about what games you might have made and I checked your roblox page. I found 7 Seas Of Sorrow and was in complete awe in how you made the waves move. I was wondering if you would be willing to share how you were able to do this in roblox because every other game on Roblox features really boring water.

Thanks!

There was some dev forum post I found a while back showing off the waves he had made, and he made it free to use in your own games. I don’t remember how I found it though or what it was called.

1 Like

No problem. Thanks for your reply.

For anyone looking for that projectonplane function…

local function ProjectOnPlane(v,n)	
	return v - (((v:Dot(n))/(n.Magnitude)^2)*n)
end

This is what inevitably worked for me. Not sure if it effectively the same as the code Frezezen shared above. Anyway, I can confirm that it outputs the same as unity as I’ve tested it. For anyone who just wants to copy/paste.

8 Likes
local function ProjectUnitVectorOnPlane(unitVector : Vector3, normalVector : Vector3)
	return unitVector - unitVector:Dot(normalVector)*normalVector	
end

cleaned up the code

4 Likes