Trying to place a part with a building tool

Hi, I’m trying to implement a placement system and I’m having a difficult time. What I’m trying to achieve in the long term is having a highlight part showing the way a part will be placed at the player’s cursor position, then clicking will place the part at the position. Honestly the behavior I want is in like with how old BuildTools used to work, if there’s a way to just get a BuildTool and put my custom part in it that would be the best thing.

Right now I’m just trying to cast a ray to where the player’s mouse is to place a part at the position of the surface the ray hits. My results aren’t desirable because while I have the part placing, usually it places far away from where the player’s mouse clicks, usually inside something.

Previous approaches I’ve made included using a vector3 position to place instead of a cframe, but I couldn’t figure it out.

This local script handles the tool I use to build. The idea is each block is a tool.

local ServerScriptStorage = game:GetService("ServerScriptService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = ReplicatedStorage:WaitForChild("PartPlaceEvent")
local UIS = game:GetService("UserService")
local runservice = game:GetService("RunService")
local tool = script.Parent.Parent
local handle = tool:WaitForChild("Handle")
local rKeyPressed = false  -- To rotate in the future
local qKeyPressed = false -- To rotate in the future

local function onEquip()
	handle.CanCollide = false
end

local function onUnequip()
	handle.CanCollide = true
end

local function onDeactivate()
end

local function onActivate()
	print("Block placed")
	local x, y, z = 0, 0, 0
	local player = game:GetService("Players").LocalPlayer
	local mouse = player:GetMouse()
	local humanoidrootpart = player.Character:FindFirstChild("HumanoidRootPart")
	local humanoid = player.Character:FindFirstChildOfClass("Humanoid")
	local camera = workspace.CurrentCamera
	local length = 30
	local unitRay = camera:ScreenPointToRay(mouse.X, mouse.Y, length)
	local ray = Ray.new(unitRay.Origin, unitRay.Direction * length)
	local placedCFrame = CFrame.new(ray.Origin, ray.Origin + ray.Direction)
	remoteEvent:FireServer(handle, placedCFrame)
	humanoid:UnequipTools()
	tool:Destroy()
end

tool.Equipped:Connect(onEquip)
tool.Unequipped:Connect(onUnequip)
tool.Activated:Connect(onActivate)
tool.Deactivated:Connect(onDeactivate)

This is my server script.

local ServerScriptStorage = game:GetService("ServerScriptService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remoteEventDrop = ReplicatedStorage:WaitForChild("WoodDropEvent")
local remoteEventPlace = ReplicatedStorage:WaitForChild("PartPlaceEvent")
local remoteEventEat = ReplicatedStorage:WaitForChild("ResourceEatEvent")
local remoteEventUpdate = ReplicatedStorage:WaitForChild("StatUpdateEvent")
local CraftTool = ReplicatedStorage:WaitForChild("CraftTool")
local craftingInfo = require(ReplicatedStorage:WaitForChild("craftingInfo"))
local CraftBlock = ReplicatedStorage:WaitForChild("BuildBlockCraft")

local function placeBlock(player, block, cframe)
    print("Place block called")
    local buildingblock = block:Clone()
    buildingblock.Anchored = true
    buildingblock.CanCollide = true
    buildingblock.BuildScript:Destroy()
    buildingblock.CFrame = cframe
    buildingblock.Parent = workspace.interactive.player_placed
end

remoteEventPlace.OnServerEvent:Connect(placeBlock)

Can anyone help me figure this out? I tried following some tutorials on YouTube but it’s hard to find free placement videos or what I need in general and I’m struggling.