Tilt Object Relative To Other Object

Hello! I am trying to make a scooter tilt whenever it turns via the CFrame. My model consists of a “physics box” which is a rectangular prism interacting with the world and an “appearance” which is the thing that makes the scooter look like a scooter and is something of an aesthetic thing since it can’t collide with anything. My goal to make this appearance tilt relative to the physics box and according to the physics box turn direction.

I already have a system in place where I can just access the current turn direction and so this is essentially the code so far:

local physicsBox: Part = -- physics box
local appearance: UnionOperation = -- scooter appearance

local function updateTilt()
    local maxTiltAngle = 20 -- degrees

	if currentTurnDirection == turnDirections.none then
		appearance.CFrame = appearance.CFrame:Lerp(physicsBox.CFrame, 0.05)
	elseif currentTurnDirection == turnDirections.right then
		-- TODO: Tilt appearance right
	elseif currentTurnDirection == turnDirections.left then
		-- TODO: Tilt appearance left
	end
end

RunService.Heartbeat:Connect(updateTilt)

bumping since I haven’t found a solution yet; I tried this but it didn’t quite do the trick… it doesn’t always tilt the correct direction and it results in the back of the scooter being lifted up

local appearanceOffsetFromPhysicsBox: number = -- appearance offset from physics box

local function updateTilt()
	local neutralState: CFrame = scooterPhysicsBox.CFrame + scooterPhysicsBox.CFrame.UpVector * appearanceOffsetFromPhysicsBox
	
	if currentTurnDirection == turnDirections.none then
		scooterAppearance.CFrame = scooterAppearance.CFrame:Lerp(neutralState, 0.05)
	elseif currentTurnDirection == turnDirections.right then
		scooterAppearance.CFrame = scooterAppearance.CFrame:Lerp(neutralState * CFrame.fromAxisAngle(neutralState.LookVector, maxTiltAngle), 0.05)
	elseif currentTurnDirection == turnDirections.left then
		scooterAppearance.CFrame = scooterAppearance.CFrame:Lerp(neutralState * CFrame.fromAxisAngle(neutralState.LookVector, -maxTiltAngle), 0.05)
	end
end

I think you might be overcomplicating this a bit, have you tried using CFrame.Angle? You can use that to obtain a tilt motion. If I were to guess, the tilting angle would be on the Z axis.

local physicsBox: Part = -- physics box
local appearance: UnionOperation = -- scooter appearance

local maxTiltAngle = 20 -- degrees

local function updateTilt()
        local tiltAngle = maxTiltAngle

	if currentTurnDirection == turnDirections.none then
		appearance.CFrame = appearance.CFrame:Lerp(physicsBox.CFrame, 0.05)
	elseif currentTurnDirection == turnDirections.right then
		appearance.CFrame = appearance.CFrame:Lerp(physicsBox.CFrame * CFrame.Angles(0, 0, math.rad(tiltAngle)), 0.05)
	elseif currentTurnDirection == turnDirections.left then
		appearance.CFrame = appearance.CFrame:Lerp(physicsBox.CFrame * CFrame.Angles(0, 0, math.rad(-tiltAngle)), 0.05)
	end
end

RunService.Heartbeat:Connect(updateTilt)

This may not be exactly what you want, but hopefully it helps put you in the right direction. (Let me know if it doesn’t, though)

1 Like

Thank you for your response! It works exactly as expected! I wasn’t understanding CFrame.Angles; I thought that multiplying with that was like multiplying using the static Z axis in the world coordinate system, so I tried multiplying by an angle about the look vector of the physics box (which is the Z coordinate like you suspected) thinking that would transform the local space value I was looking for to world space. But it looks like I had the wrong impression. Thank you again!

1 Like

Well, for your reference, (and for others reference) multiplying/dividing any CFrame with another CFrame would be treated as local space instead of world space. If you wanted to move something into world space, you would add/subtract the CFrame with a Vector3.

The use of CFrame.fromAxisAngle is for “rotating a CFrame from a unit Vector3 and a rotation in radians”.

So, when you were using it within your other attempt, you were actually rotating it in the direction of where your LookAt, which would be angle X, hence why your scooter was resulting in the “back of the scooter being lifted up”.

Aside from that, I’m glad my assistance did help you with your scooter physics, and I wish you good luck on the project. (When you’re done, maybe you could showcase it to us for feedback?)

1 Like

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