How to get the change in the orientation of a CFrame? (Camera-Related, Need Help)

I have a wall running system in my game where it moves the players character along the direction of a normal of a wall.

If I wall run and the wall bends to the left, it does so accordingly and will move my character to the left along the wall. This is intended! However, I needed to change the camera behaviour to reflect the change that the character had (because rn it just stayed the same).

I thought of doing this by getting the change of the CFrame over time, which I did. However, this didn’t actually seem to do anything at all? Or at least, it wasn’t strong enough (I multiplied it by 100 and it jittered out but that meant it did affect it after all).

Here’s the function handling the camera wallrun behaviour:

local function updateWallrunCamera(character, deltaTime, rootPart, rotCFrame)
	-- Update transition time for smooth blend
	wallrunTransitionTime = math.min(wallrunTransitionTime + deltaTime, wallrunMaxTransitionTime)
	local transitionAlpha = wallrunTransitionTime / wallrunMaxTransitionTime

	-- Store wallrun direction from attribute and update character orientation
	local wallrunDirection = character:GetAttribute("WallrunDirection")
	currentWallrunDirection = wallrunDirection or currentWallrunDirection
	rootPart.CFrame = CFrame.new(rootPart.Position, rootPart.Position + currentWallrunDirection)

	-- Determine ideal wallrun camera rotation without affecting targetRotY
	local wallrunRotY = getWallrunCameraOrientation(character, currentWallrunDirection)

	local _, deltaRootCF, _ = (rootPart.CFrame * oldRootPartCF:Inverse()):ToOrientation()

	print(deltaRootCF)

	local wallrunRotCFrame = CFrame.fromEulerAnglesYXZ(rotationX, rotationY + deltaRootCF, 0)

	-- Blend between user-controlled rotation and wallrun rotation
	local blendedRotCFrame = rotCFrame:Lerp(wallrunRotCFrame, transitionAlpha)

	-- Calculate and set the target camera CFrame
	local targetCFrame = CFrame.new(rootPart.Position) * blendedRotCFrame * cameraOffset

	local wrOffset = wallrunOffsets[character:GetAttribute("WallrunSide")] or Vector3.zero

	CAMERA.CFrame = CAMERA.CFrame:Lerp(targetCFrame, wallrunSmoothness) * CFrame.new(wrOffset)

	oldRootPartCF = rootPart.CFrame
end

I’m really confused. If you can suggest a different solution, go for it lol! All I really need is for blendedRotCFrame to have the wallrun dir y and rotation y to combine so that the player can look around while wallrunning, but as soon as the wall bends the camera reflects it. Please help!

2 Likes

The problem is specifically with these ones:

local _, deltaRootCF, _ = (rootPart.CFrame * oldRootPartCF:Inverse()):ToOrientation()

print(deltaRootCF)

local wallrunRotCFrame = CFrame.fromEulerAnglesYXZ(rotationX, rotationY + deltaRootCF, 0)

deltaRootCF is the change of the cframe of the rootPart every frame. Rotation X and Rotation Y are values that are changed by the input of the user (moving the mouse).

1 Like

I’m not really sure what you’re trying to do.

Can you maybe show us some video of what you currently have? Is there some other game with the effect that you’re trying to achieve?

There are various methods of getting a change in a CFrame but the best method is to first record the old CFrame and then do this:

  • For Position: oldCFrame.Position - newCFrame.Position
  • For Orientation: math.acos(oldCFrame.LookVector:Dot(newCFrame.LookVector))

Orr just use :ToOrientation.

Parkour reborn is a good example of what I was trying to do. I’ve found the solution though, and I’ll share it in another reply.

Pretty much, I had a variable called Rotation Y that was the Y axis rotation of the camera as based off user input (so pretty much horizontal mouse movement = horizontal camera movement). The issue was, I had another variable, wallrunRotCFrame which was the CFrame that actually changed where the camera went. I had this variable because I wanted to make it so that while I was wallrunning, the camera would follow behind. However, I still wanted to implement user input into the camera movement.

I think the error I had was the math, and I think I plugged in the wrong variables together. I implemented the thing @iicloudsforeveriii said, thanks for that! I actually just got the change in Rotation Y each frame and I added that to wallrunRotCFrame.

Here’s a video of my wallrun in action if you’re curious:

robloxapp-20250309-2041194.wmv (2.4 MB)

EDIT: Roblox’s video capture lowkey sucks. Here’s one with windows capture

Thanks for your help!

If I was the one who had helped you then I believe I should be the one having my post marked. Don’t you think?

1 Like