Help with CFrame Orientation and Angles

I’m practicing with CFrame by creating a car pedal system, but whenever I tween the CFrame.Angles it always looked bad until I used ToWorldSpace() which worked until it didn’t. You see, what ToWorldSpace() does, is it adds to the current angle instead of a fixed orientation. I have searched for a while and can’t find a simple solution.

Code:

--Services
local UIS = game:GetService("UserInputService")
local CAS = game:GetService("ContextActionService")
local TS = game:GetService("TweenService")
local RS = game:GetService("RunService")

--Player
local players = game:GetService("Players")
local player = players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()
local hum = char.Humanoid
local humRoot = char.HumanoidRootPart

--Camera
local cam = game.Workspace.CurrentCamera
local camBone = game.Workspace:WaitForChild("CamBone")
cam.CameraType = Enum.CameraType.Scriptable

--Parts
local gasPedal = game.Workspace.Accelerator
local brakePedal = game.Workspace.Brake
local clutchPedal = game.Workspace.Clutch

--Main
cam.CFrame = camBone.CFrame
cam.FieldOfView = 90
local x, y, z = gasPedal.PrimaryPart.CFrame:ToEulerAngles() -- this is just here because of testing, it is not currently being used

print(gasPedal.PrimaryPart.Orientation)
local function gasDown(actionName, inputState)
	if actionName == "GasPressed" and inputState == Enum.UserInputState.Begin then
		print("Input Began")
		local camTween = TS:Create(cam, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0, false, 0), {FieldOfView = 100})
		local gasTween = TS:Create(gasPedal.PrimaryPart, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0, false, 0), {CFrame = gasPedal.PrimaryPart.CFrame:ToWorldSpace(CFrame.Angles(math.rad(-20), 0, 0))})
		--camTween:Play()
		gasTween:Play()
	elseif actionName == "GasPressed" and inputState == Enum.UserInputState.End then
		print("Input Ended")
		local camTween = TS:Create(cam, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0, false, 0), {FieldOfView = 90})
		local gasTween = TS:Create(gasPedal.PrimaryPart, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0, false, 0), {CFrame = gasPedal.PrimaryPart.CFrame:ToWorldSpace(CFrame.Angles(math.rad(20), 0, 0))})
		--camTween:Play()
		gasTween:Play()
	end
end

CAS:BindAction("GasPressed", gasDown, false, Enum.KeyCode.W)

RS.RenderStepped:Connect(function()
	print(gasPedal.PrimaryPart.Orientation)
end)

You want to know what ToWorldSpace() does? It translates the current CFrame to the world perspective instead of the object perspective, in short. For example, if I have a CFrame (0, 1, 0), and I use ToWorldSpace(), it will convert the CFrame (0, 1, 0) to the WorldSpace relative CFrame (0, 0, 0 by default), returning 0, 1, 0, as it is 0, 1, 0 studs away from the WorldSpace relative CFrame.

This post may help clarifying stuff about both ToWorldSpace() and ToObjectSpace(): What does ToObjectSpace() and ToWorldSpace() do?

1 Like

I see, but how can I prevent it from adding to the current angle instead of going TO that angle

Additionally, you could encapsulate all those if statements by doing this:

if actionName == "GasPressed" then
    if inputState == Enum.UserInputState.Begin then
        print("Input Began")

		local camTween = TS:Create(cam, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0, false, 0), {FieldOfView = 100})
		local gasTween = TS:Create(gasPedal.PrimaryPart, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0, false, 0), {CFrame = gasPedal.PrimaryPart.CFrame:ToWorldSpace(CFrame.Angles(math.rad(-20), 0, 0))})
		--camTween:Play()
		gasTween:Play()
    end

    if inputState == Enum.UserInputState.End then
        print("Input Ended")

		local camTween = TS:Create(cam, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0, false, 0), {FieldOfView = 90})
		local gasTween = TS:Create(gasPedal.PrimaryPart, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0, false, 0), {CFrame = gasPedal.PrimaryPart.CFrame:ToWorldSpace(CFrame.Angles(math.rad(20), 0, 0))})
		--camTween:Play()
		gasTween:Play()
    end
end

I think I know what you are trying to achieve. You can store the CFrame of the primarypart and then use ToWorldSpace into it.

EDIT:

local CFrame = gasPedal.PrimaryPart.CFrame

local goal = CFrame:ToWorldSpace(CFrame.Angles(math.rad(-20), 0, 0))

Try doing this. If it doesn’t work let me know.

1 Like

This is the new code:

local function gasDown(actionName, inputState)
	if actionName == "GasPressed" then
		local CF = gasPedal.PrimaryPart.CFrame
		if inputState == Enum.UserInputState.Begin then
			print("Input Began")

			local camTween = TS:Create(cam, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0, false, 0), {FieldOfView = 100})
			local gasTween = TS:Create(gasPedal.PrimaryPart, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0, false, 0), {CFrame = CF:ToWorldSpace(CFrame.Angles(math.rad(-20), 0, 0))})
			--camTween:Play()
			gasTween:Play()
		end

		if inputState == Enum.UserInputState.End then
			print("Input Ended")

			local camTween = TS:Create(cam, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0, false, 0), {FieldOfView = 90})
			local gasTween = TS:Create(gasPedal.PrimaryPart, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0, false, 0), {CFrame = CF:ToWorldSpace(CFrame.Angles(math.rad(-20), 0, 0))})
			--camTween:Play()
			gasTween:Play()
		end
	end
end

And this is what it is doing:

What do you want to do actually?

1 Like

I want the Pivot (PrimaryPart) to rotate down to a fixed orientation when W is pressed and rotate back up to fixed orientation when W is released. (Poorly made I know)

why don’t you do that then?

local gasTween = TS:Create(gasPedal.PrimaryPart, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out), {CFrame = CF * CFrame.Angles(math.rad(-20), 0, 0)})

You don’t need to use ToWorldSpace

1 Like

It does the same thing as ToWorldSpace. If the player were to let off the gas before reaching the endpoint of the tween it would subtract instead of going to the original orientation.

1 Like

Why don’t you store the original CFrame before changing it, and then you tween according to the original cframe?

1 Like

Do you mean make the tween back to original, just the stored value like this:

CFrame = CF

If this is the case you need to ensure the tweens work differently from eachother.

The two tweens are literally equal to eachother. On the Begin you make the CFrame rotate -20, and on the End you make the CFrame rotate to the original rotation.

1 Like

No, apparently you want to make it so when player presses “W” the tween goes oriented by negative 20. However, when player stops holding “W,” the tween goes back to its original orientation; am I right?

1 Like

That is what I want, yes. I did change those values, but it still did the weird thing. The stored original CFrame of the PrimaryPart is apparently the updated version and not the original. Also, it appears I have confused you, but what you just explained is what I want.

Ok, so do something like it:

local originalCF = gasPedal.PrimaryPart.CFrame

local function gasDown(actionName, inputState)
	if actionName == "GasPressed" then
		if inputState == Enum.UserInputState.Begin then
			print("Input Began")

			local camTween = TS:Create(cam, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0, false, 0), {FieldOfView = 100})
			local gasTween = TS:Create(gasPedal.PrimaryPart, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0, false, 0), {CFrame = originalCF * CFrame.Angles(math.rad(-20), 0, 0)})
			--camTween:Play()
			gasTween:Play()
		end

		if inputState == Enum.UserInputState.End then
			print("Input Ended")

			local camTween = TS:Create(cam, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0, false, 0), {FieldOfView = 90})
			local gasTween = TS:Create(gasPedal.PrimaryPart, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0, false, 0), {CFrame = originalCF})
			--camTween:Play()
			gasTween:Play()
		end
	end
end
1 Like

Thank you, it appears the stored original CFrame was updating due to it being under the function.

1 Like

I’m glad I could solve it ^^. Good luck with your game :slight_smile:

1 Like

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