Help With ArcHandles

Hello,
Ive recently been trying to make a Roller Coaster building system similar to Theme Park Tycoon 2. The only issue is that the Archandles don’t seem to show up.


All the properties are correct, I believe.

If anyone knows why it wouldn’t work, please tell me!

Thanks

local function createOrUpdateAllHandles(adornee)
	local playerGui = PLAYER:FindFirstChild("PlayerGui")
	if not playerGui then warn("Cannot create/update handles: PlayerGui not found!"); return end
	dragStartCFrame = nil -- Reset drag state

	if not adornee or not adornee.Parent then
		warn("Cannot create/update handles: Invalid Adornee")
		if movementHandles then movementHandles:Destroy(); movementHandles = nil end
		if rotationHandles then rotationHandles:Destroy(); rotationHandles = nil end
		return
	end

	if not movementHandles then
		movementHandles = Instance.new("Handles"); movementHandles.Name = "CoasterMovementHandles"
		movementHandles.Style = Enum.HandlesStyle.Movement; movementHandles.Color3 = Color3.fromRGB(0, 170, 255); movementHandles.Transparency = 0.2
		movementHandles.MouseButton1Down:Connect(function(face) if adornee and adornee.Parent then dragStartCFrame = adornee.CFrame; isDraggingHandle = true else dragStartCFrame = nil end end)
		movementHandles.MouseDrag:Connect(function(face, distance) if adornee and adornee.Parent and dragStartCFrame then local offset = Vector3.fromNormalId(face) * distance; adornee.CFrame = dragStartCFrame * CFrame.new(offset); updateGhostTrack() else isDraggingHandle = false; dragStartCFrame = nil end end)
		movementHandles.MouseButton1Up:Connect(function(face) if isDraggingHandle then isDraggingHandle = false; if adornee and adornee.Parent then updateGhostTrack() end end; dragStartCFrame = nil end)
		print("Created Movement Handles instance.")
	end
	movementHandles.Adornee = adornee
	movementHandles.Parent = (currentHandleMode == "Movement") and playerGui or nil

	if not rotationHandles then
		rotationHandles = Instance.new("ArcHandles"); rotationHandles.Name = "CoasterRotationHandles"
		rotationHandles.Axes = Axes.new(true, true, true); rotationHandles.Color3 = Color3.fromRGB(255, 255, 0); rotationHandles.Transparency = 0.2
		rotationHandles.MouseButton1Down:Connect(function(axis) if adornee and adornee.Parent then dragStartCFrame = adornee.CFrame; isDraggingHandle = true else dragStartCFrame = nil end end)

		rotationHandles.MouseDrag:Connect(function(axis, relativeAngle, deltaRadius)
			if adornee and adornee.Parent and dragStartCFrame then
				local rx, ry, rz = 0, 0, 0 -- Initialize angles to 0
				-- Set the angle for the axis being dragged
				if axis == Enum.Axis.X then
					rx = relativeAngle
				elseif axis == Enum.Axis.Y then
					ry = relativeAngle
				elseif axis == Enum.Axis.Z then
					rz = relativeAngle
				end

				-- Apply rotation relative to the CFrame captured at the start of the drag
				adornee.CFrame = dragStartCFrame * CFrame.Angles(rx, ry, rz)
				updateGhostTrack() -- Update preview
			else
				-- Reset state if something is wrong
				isDraggingHandle = false
				dragStartCFrame = nil
			end
		end)
		-- Connect MouseButton1Up (same as before)
		rotationHandles.MouseButton1Up:Connect(function(axis) if isDraggingHandle then isDraggingHandle = false; if adornee and adornee.Parent then updateGhostTrack() end end; dragStartCFrame = nil end)
		print("Created Rotation Handles instance.")
	end
	rotationHandles.Adornee = adornee
	rotationHandles.Parent = (currentHandleMode == "Rotation") and playerGui or nil -- Set parent based on mode

	print(string.format("Handles updated. Mode: %s. Move Parent: %s, Rot Parent: %s", currentHandleMode, tostring(movementHandles.Parent), tostring(rotationHandles.Parent)))
end
2 Likes

The class of the instance you clicked on in the video is Handles not ArcHandles.

If you mean that the instance isn’t appearing (I don’t think this is what u mean) , then you’d probably have to share the code snippet that deals with that.

1 Like

The handles work properly, but the archandles do not show. In the video, the handles do not pop up when the mode is switched to rotation in the output log (Which is supposed to happen), but the archandles don’t appear.

The Code in question:

local function createOrUpdateAllHandles(adornee)
	local playerGui = PLAYER:FindFirstChild("PlayerGui")
	if not playerGui then warn("Cannot create/update handles: PlayerGui not found!"); return end
	dragStartCFrame = nil -- Reset drag state

	if not adornee or not adornee.Parent then
		warn("Cannot create/update handles: Invalid Adornee")
		if movementHandles then movementHandles:Destroy(); movementHandles = nil end
		if rotationHandles then rotationHandles:Destroy(); rotationHandles = nil end
		return
	end

	if not movementHandles then
		movementHandles = Instance.new("Handles"); movementHandles.Name = "CoasterMovementHandles"
		movementHandles.Style = Enum.HandlesStyle.Movement; movementHandles.Color3 = Color3.fromRGB(0, 170, 255); movementHandles.Transparency = 0.2
		movementHandles.MouseButton1Down:Connect(function(face) if adornee and adornee.Parent then dragStartCFrame = adornee.CFrame; isDraggingHandle = true else dragStartCFrame = nil end end)
		movementHandles.MouseDrag:Connect(function(face, distance) if adornee and adornee.Parent and dragStartCFrame then local offset = Vector3.fromNormalId(face) * distance; adornee.CFrame = dragStartCFrame * CFrame.new(offset); updateGhostTrack() else isDraggingHandle = false; dragStartCFrame = nil end end)
		movementHandles.MouseButton1Up:Connect(function(face) if isDraggingHandle then isDraggingHandle = false; if adornee and adornee.Parent then updateGhostTrack() end end; dragStartCFrame = nil end)
		print("Created Movement Handles instance.")
	end
	movementHandles.Adornee = adornee
	movementHandles.Parent = (currentHandleMode == "Movement") and playerGui or nil

	if not rotationHandles then
		rotationHandles = Instance.new("ArcHandles"); rotationHandles.Name = "CoasterRotationHandles"
		rotationHandles.Axes = Axes.new(true, true, true); rotationHandles.Color3 = Color3.fromRGB(255, 255, 0); rotationHandles.Transparency = 0.2
		rotationHandles.MouseButton1Down:Connect(function(axis) if adornee and adornee.Parent then dragStartCFrame = adornee.CFrame; isDraggingHandle = true else dragStartCFrame = nil end end)

		rotationHandles.MouseDrag:Connect(function(axis, relativeAngle, deltaRadius)
			if adornee and adornee.Parent and dragStartCFrame then
				local rx, ry, rz = 0, 0, 0 -- Initialize angles to 0
				-- Set the angle for the axis being dragged
				if axis == Enum.Axis.X then
					rx = relativeAngle
				elseif axis == Enum.Axis.Y then
					ry = relativeAngle
				elseif axis == Enum.Axis.Z then
					rz = relativeAngle
				end

				-- Apply rotation relative to the CFrame captured at the start of the drag
				adornee.CFrame = dragStartCFrame * CFrame.Angles(rx, ry, rz)
				updateGhostTrack() -- Update preview
			else
				-- Reset state if something is wrong
				isDraggingHandle = false
				dragStartCFrame = nil
			end
		end)
		-- Connect MouseButton1Up (same as before)
		rotationHandles.MouseButton1Up:Connect(function(axis) if isDraggingHandle then isDraggingHandle = false; if adornee and adornee.Parent then updateGhostTrack() end end; dragStartCFrame = nil end)
		print("Created Rotation Handles instance.")
	end
	rotationHandles.Adornee = adornee
	rotationHandles.Parent = (currentHandleMode == "Rotation") and playerGui or nil -- Set parent based on mode

	print(string.format("Handles updated. Mode: %s. Move Parent: %s, Rot Parent: %s", currentHandleMode, tostring(movementHandles.Parent), tostring(rotationHandles.Parent)))
end
2 Likes

https://create.roblox.com/store/asset/75159371555667/CFrametool-fix-2025 if u want i make module on

1 Like