Help with orientation Lerp please

So Basically i have a script that detects walls on the side of the player using raycast and then makes the player and camera face parallel to the wall.

the problem is that when the camera changes its direction it’s too snappy it directly changes to the new direction which makes it look too bad. I want to make the camera smoothly change the angle using lerp.

cam.CFrame = CFrame.lookAt(head.Position, head.Position + ToCFrame) * CFrame.Angles(0, math.rad(-90), 0) * CFrame.Angles(math.rad(AngleX),0,0) * CFrame.Angles(0,0,math.rad(13)) * HeadOffset

the line above is what I use to change the camera direction. The Bold part mainly controls the horizontal direction (which is what I need to lerp I want the rest to continue behaving as they are) I don’t want the camera’s position to be lerped I also don’t want the camera’s up and down orientation to be lerped.

  1. How can I lerp only the camera’s angles and not its position.
  2. Can you help me change the code above so that it works how I want it?

This is all only to match the walls direction from your character right?

cam.CFrame = CFrame.lookAt(head.Position, head.Position + ToCFrame) * CFrame.Angles(0, math.rad(-90), 0) * CFrame.Angles(math.rad(AngleX),0,0) * CFrame.Angles(0,0,math.rad(13)) * HeadOffset

Too lazy to finish reading this, but try using the CFrame:Lerp() method of CFrame. Depending on how fast you want the camera to move, you can change the lerp value as you change the camera’s cframe again.


This is how it looks when i was messing around with lerp. the position is also being lerped its not fixed. i don’t want the up and down orientation to be lerped i only want this part to get lerped CFrame.lookAt(head.Position, head.Position + ToCFrame) * CFrame.Angles(0, math.rad(-90), 0)

this makes the player face parallel to the wall. and as u see since there is different parts at different angles its snaps to the new angle i want it to be smooth

Check this out

Camera.CFrame = Camera.CFrame:Lerp(CFrame.new(RootPart.Position) * CFrame.Angles(0,math.atan2(CastRay.Normal.Unit.Z, -RootPart.CFrame.LookVector.Z),0) * CFrame.Angles(math.rad(-20),0,0) * CFrame.new(0,0,10), 0.1)
1 Like

i was able to reach a similar outcome before but its not exactly what i need. i made a small change so that i can look up and down. as you can see the camera is not in first person anymore since the position is being affected by the lerp i think.

This is 100% what you want

local LerpIncrements	= 0.1
local PlacementPos		= CFrame.new(RootPart.Position)
local Rx, Ry, Rz		= 0, math.atan2(CastRay.Normal.Z, -RootPart.CFrame.LookVector.Z), math.rad(20)

Camera.CameraType		= Enum.CameraType.Scriptable
Camera.CFrame			= (PlacementPos * CFrame.Angles(Camera.CFrame:ToEulerAngles())):Lerp(PlacementPos * CFrame.Angles(0,Ry,0) * CFrame.Angles(Rx,0,0) * CFrame.Angles(0,0,Rz), LerpIncrements)

Untitled video - Made with Clipchamp

No wait I’m dumb give me a second

Edit: Yeah no its good

You can construct the angle in one instead of creating three.

Example:

This:

PlacementPos * CFrame.Angles(0,Ry,0) * CFrame.Angles(Rx,0,0) * CFrame.Angles(0,0,Rz)

Is the same as this:

PlacementPos * CFrame.Angles(Rx,Ry,Rz)

Its not.


It is though. The slight differences you may see between them are because when you multiply CFrames together, they can cause unintended floating point values.

Code:

print(CFrame.Angles(15, 0, 0) * CFrame.Angles(0, 60, 0) * CFrame.Angles(0, 0, 25))
print(CFrame.Angles(15, 60, 25))

Output:

0, 0, 0, -0.944034398, -0.126053527, -0.304810613, -0.0959248915, -0.77923882, 0.619342566, -0.31559059, 0.613919675, 0.723536611
0, 0, 0, -0.944034398, -0.126053527, -0.304810613, -0.0959248915, -0.77923882, 0.619342566, -0.31559059, 0.613919675, 0.723536611
1 Like

I thought it worked in sequence. So, if you rotate from Rz, then the Ry rotation is based on the previous one, etc.

1 Like

It does, it’s just that the Ry rotation does not depend on the Rx or Rz rotation of it’s CFrame.

1 Like

Oh yeah ik that lol, you could even put Rx and Rz together I believe.

1 Like

ik im being too annoying but its almost perfect. Noramlly when i multiply

  • CFrame.Angles(math.rad(AngleX),0,0)

it allows me to look up and down while wallrunning.

The video above is an example of how it looks like to look up and down. (its smooth and allows and has a limit when looking up or down you cant do a full 360)

now however if i try to multiply by

  • CFrame.Angles(math.rad(AngleX),0,0)

it looks like this:

.

it weird and you can do a full 360.

Try limiting it with math.clamp(XAngle, -math.pi/2, math.pi/2)

local LerpIncrements	= 0.1
local PlacementPos		= CFrame.new(RootPart.Position)
local Rx, Ry, Rz		= 0, math.atan2(CastRay.Normal.Z, -RootPart.CFrame.LookVector.Z), math.rad(20)

Camera.CameraType		= Enum.CameraType.Scriptable
Camera.CFrame			= (PlacementPos * CFrame.Angles(Camera.CFrame:ToEulerAngles())):Lerp(PlacementPos * CFrame.Angles(0,Ry,0) * CFrame.Angles(Rx,0,0) * CFrame.Angles(0,0,Rz), LerpIncrements)

this seems to only work and face the correct direction when the wall is on the right side doesn’t work if the wall is on the left it faces the opposite direction the player is moving

local Rx, Ry, Rz		= 0, math.atan2(CastRay.Normal.Z, -RootPart.CFrame.LookVector.Z), math.rad(20)

try changing the -RootPart.CFrame.LookVector.Z to a positive