How would I rotate the player based on a raycast normal?

Hey there! I am working on a wallrun system, and I want to be able to orient a player based on a raycast normal. The problem is, is that I just can’t figure this out. I keep getting the error "Argument 3 missing or nil" at the line that is supposed to orient the player.

Here is that line:

humanoid.RootPart.CFrame = humanoid.RootPart.CFrame * CFrame.Angles(normal)

the normal variable is just the raycast.Normal

How would I fix this? Any help is appreciated!

With the given context, it seems it would be easier to go about this by using CFrame.lookAt and using ray.Position.

local _, y, z= CFrame.lookAt(humanoid.RootPart.CFrame,ray.Position):ToOrientation()
local newCFrameLookAt = CFrame.fromOrientation(0,y,z)

When I apply it to the HumanoidRootPart like this:

while runService.RenderStepped:Wait() do
	local _, y, z= CFrame.lookAt(humanoid.RootPart.Position, rayL.Position):ToOrientation()
	local newCFrameLookAt = CFrame.fromOrientation(0,y,z)
					
	humanoid.RootPart.CFrame = newCFrameLookAt
end

It just teleports me to the middle of the world. I also changed humanoid.RootPart.CFrame to humanoid.RootPart.Position.

Edit: Looks like I just forgot to do humanoid.RootPart.CFrame * newCFrameLookAt. But now there’s another problem, it spins me really fast.

It teleports you because you only used Orientation I guess.

Yes, I fixed that by just doing humanoid.RootPart.CFrame * newCFrameLookAt. Now the problem is, is that it spins me really fast.

Use CFrame:Lerp(), it will smooth it out

Using Lerp like this:

humanoid.RootPart.CFrame:Lerp(humanoid.RootPart.CFrame * newCFrameLookAt, .3)

Just stops the player from rotation whatsoever. I don’t know if I used it wrong, but it doesn’t seem to work.

Can you please describe what you want to achieve once again? When do you want to rotate player? When they are close to the wall?

So, I want to rotate the player when they are holding space against the wall. The player should rotate so they are looking 90 degrees away from the wall, for a wall run mechanic. I am checking if they are actually up against a wall by sending a raycast to the left and to the right of the player. I hope this is enough information.

Use alignOrientation. Probably you are familliar with BodyGyro but it’s deprecated. So I would suggest you to use alignOrientation.

1 Like

CFrame.Angles() requires three parameters according to each axis of rotation.

raycast.Normal returns the direction facing away from the intersected surface.
You can find the vector parallel to the wall by taking the cross product between the up vector and the normal vector:

local direction = normal:Cross(Vector3.new(0, 1, 0))

You may need to negate this vector based on whether the character is running along a left or right handed wall.
Now you can create a rotation using CFrame.lookat()

local rotation = CFrame.lookat(Vector3.new(), direction * Vector3.new(1, 0, 1))
--we multiply the direction by (1, 0, 1) to ensure the rotation is exclusively along the xz plane and does not rotate the character facing up or down.

and now finally, apply the rotation to the RootPart.

humanoid.RootPart.CFrame = CFrame.new(humanoid.RootPart.Position) * rotation
1 Like

Very good idea, but fireys found the exact solution I was looking for. Thanks for the help anyway!

For clarifying, were you just trying to face character so they look at the wall or what? Can’t understand why would you need RightVector for that

I don’t know how to say it in English, so I drew it instead:

So the player is basically just facing the wall like you would in most wallruns.

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