Part's CFrame angle resetting when I teleport it

I’m making a point-and-click game and I picked it up after months of neglect because of this problem where the CameraPart(which is just a part that I’m using to position the player camera, as the name implies) always points back to its original rotation when it gets moved. I’ve looked up so many things to try to fix it that every result is a purple link anymore and nothing works. Below are 3 different scripts that act on the camera and/or CameraPart.

This script is the teleport to node script(placed inside the node itself), which is the problem area here, but the other scripts might be interacting with it in ways I’m not catching(I’m rather new to lua and don’t understand much of it):

local node = script.Parent
local clickDetector = node.ClickDetector
local cameraPart = workspace.CameraPart

clickDetector.MouseClick:Connect(function()
	cameraPart.CFrame = CFrame.new(node.CFrame.Position) * cameraPart.CFrame.Rotation

	wait(0.1)

end)

The next two scripts are in StarterGui

This script rotates the camera left or right 90 degrees when A or D are pressed, respectivly:

UserInputService.InputBegan:Connect(function(input, gameProcessedEvent)
	if not gameProcessedEvent then
		if input.KeyCode == Enum.KeyCode.A then
			camera.CFrame = camera.CFrame * CFrame.Angles(0, math.rad(90), 0)
		elseif input.KeyCode == Enum.KeyCode.D then
			camera.CFrame = camera.CFrame * CFrame.Angles(0, math.rad(-90), 0)
		end
	end
end)

This script rotates the camera angle slightly depending on the mouse position:

--// Variables
local cam = workspace.CurrentCamera
local camPart = workspace["CameraPart"]
local mouse = game:GetService("Players").LocalPlayer:GetMouse()

--// Set cam
repeat
	wait()
	cam.CameraType = Enum.CameraType.Scriptable
until
cam.CameraType == Enum.CameraType.Scriptable

--// Move cam
local maxTilt = 45
game:GetService("RunService").RenderStepped:Connect(function()
	cam.CFrame = camPart.CFrame * CFrame.Angles(
		math.rad((((mouse.Y - mouse.ViewSizeY / 2) / mouse.ViewSizeY)) * -maxTilt),
		math.rad((((mouse.X - mouse.ViewSizeX / 2) / mouse.ViewSizeX)) * -maxTilt),
		0
	)
end)

Here’s a video demonstrating the mechanics and the issue:

If any of you know what my issue is and how I could fix it, that would be greatly appreciated.

1 Like

A simpler way to change the position of a CFrame is:

cameraPart.CFrame = cameraPart.CFrame + node.CFrame.Position - cameraPart.Position

This centers the CFrame at 0,0,0 by removing it’s original position then it adds in the new position.

If that still doesn’t work, perhaps there is other code messing with the CFrame or the camera mode isn’t set to scriptable.

3 Likes

What is the goal here … to teleport facing a given direction then having the camera be in back of the player as normal?

ServerScript
-- ServerScript-ServerScriptService
-- with a block part "PortPad" on the workspace
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local SetCameraEvent = ReplicatedStorage:FindFirstChild("SetCamera") or
	Instance.new("RemoteEvent", ReplicatedStorage)
SetCameraEvent.Name = "SetCamera"

local function TeleportCharacter(player, padName, rot, ypos)
	local character = player.Character
	--if not character or not character.PrimaryPart then return end

	local pad = workspace:WaitForChild(padName)
	--if not pad then return end

local newCFrame = pad.CFrame * CFrame.new(0, ypos, 0) *
		CFrame.Angles(0, math.rad(rot), 0)

	character:SetPrimaryPartCFrame(newCFrame)
	SetCameraEvent:FireClient(player, rot)
end

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function()

		task.wait(4) print("port test")
		TeleportCharacter(player, "PortPad", 90, 3) -- 0 90 180 -90
	end)
end)
LocalScript
-- LocalScript-StarterPlayerScripts

--task.wait(1)
local player = game.Players.LocalPlayer
local camera = workspace.CurrentCamera
local SetCameraEvent = game.ReplicatedStorage:WaitForChild("SetCamera")

local function SetCameraBehindCharacter(rot)
	local character = player.Character
	--if not character or not character.PrimaryPart then return end

	local root = character:WaitForChild("HumanoidRootPart")
	local backOffset = root.CFrame:PointToWorldSpace(Vector3.new(0, 2, 10)) --set behind
	local lookAtPos = root.Position + Vector3.new(0, 2, 0) --aim at player

	camera.CameraType = Enum.CameraType.Scriptable
	camera.CFrame = CFrame.lookAt(backOffset, lookAtPos) 
	camera.CameraType = Enum.CameraType.Custom
end

SetCameraEvent.OnClientEvent:Connect(function(rot)
	SetCameraBehindCharacter(rot)
end)
1 Like

Can’t you just change cameraPart.Position instead of CFrame?

local node = script.Parent
local clickDetector = node.ClickDetector
local cameraPart = workspace.CameraPart

clickDetector.MouseClick:Connect(function()
	cameraPart.Position = node.CFrame.Position

	task.wait(0.1)
end)

Also wait() is deprecated you should use task.wait() instead
Not sure whats the point of this wait tho.

1 Like

Firstly, thank you for showing me a simpler way of moving the camera. Also, I discovered that the issue is with the turn camera 90 degrees script but I should be able to figure out why it’s resetting the rotation on my own. I don’t know how it completely passed over my head that that could be the issue.

2 Likes

I’ve solved the issue with the rotation script. I needed to make it hold the rotation using runService

local key = game:GetService("UserInputService")
local runService = game:GetService("RunService")
local camera = workspace.CameraPart

local desiredOrientation = camera.Orientation

key.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.A then
		desiredOrientation += Vector3.new(0, 90, 0)
	end
	if input.KeyCode == Enum.KeyCode.D then
		desiredOrientation += Vector3.new(0, -90, 0)
	end
end)


runService.Heartbeat:Connect(function()
	camera.Orientation = desiredOrientation
end)

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