Editing CFrame of part to fit raycast normal producing undesirable results

I am trying to create a placement system, and to get parts to be placeable correctly on walls and roofs, I am trying to edit the CFrame of the part being placed using the normal of the raycast, however, it is currently placing the block in the wrong position.

Relevant code:


local mouseRay = mouse.UnitRay;
local castRay = Ray.new(mouseRay.Origin, mouseRay.Direction * 1000);
local ignoreList = {clientStructure, char};
local tau = math.pi*2;
local hit, position, normal = workspace:FindPartOnRayWithIgnoreList(castRay, ignoreList);
local newCFrame = CFrame.new(position.X, position.Y + yBuildingOffset, position.Z) * CFrame.fromEulerAnglesXYZ(normal.X*tau, normal.Y*tau, normal.Z*tau);
clientStructure.CFrame = newCFrame;

Entire script (although most of this is unrelated to the problem):

local ReplicatedStorage = game:GetService("ReplicatedStorage");
local PlaceStructure = ReplicatedStorage:WaitForChild("PlaceEvent");
local Structures = ReplicatedStorage:WaitForChild("Structures");



local UIS = game:GetService("UserInputService");
local RunService = game:GetService("RunService");



local Player = game.Players.LocalPlayer;
local StructureFrame = script.Parent.StructureFrame;
local char = Player.Character or Player.Character:Wait();
local HumanoidRootPart = char:WaitForChild("HumanoidRootPart");
local mouse = Player:GetMouse();



local yBuildingOffset = 2;
local MaxPlacingDistance = 50;
local rKeyIsPressed = false;
local placingStructure = false;

local tau = math.pi*2;
local pi = math.pi;
for _, structureButton in pairs(StructureFrame:GetChildren()) do
	if structureButton:IsA("TextButton") then
		structureButton.MouseButton1Up:Connect(function()
			StructureFrame.Visible = false;
			local yorientation = 0;
			local GoodToPlace = false;
			local PlacedStructure;
			if placingStructure == false then
				placingStructure = true;
				local clientStructure = Structures:FindFirstChild(structureButton.Name):Clone();
				clientStructure.BrickColor = BrickColor.new("Forest green");
				clientStructure.Transparency = 0.5;
				clientStructure.Material = "Neon";
				clientStructure.CanCollide = false;
				clientStructure.Parent = game.Workspace;
				local startingCFrame = CFrame.new(0, -2, -15);
				clientStructure.CFrame = HumanoidRootPart.CFrame:ToWorldSpace(startingCFrame);
				RunService.RenderStepped:Connect(function()
					local mouseRay = mouse.UnitRay;
					local castRay = Ray.new(mouseRay.Origin, mouseRay.Direction * 1000);
					local ignoreList = {clientStructure, char};
					local hit, position, normal = workspace:FindPartOnRayWithIgnoreList(castRay, ignoreList);
					print(workspace:FindPartOnRayWithIgnoreList(castRay, ignoreList));
					print(hit, position, normal);
					if hit then
						if (HumanoidRootPart.Position - clientStructure.Position).Magnitude < MaxPlacingDistance then
							GoodToPlace = true;
							clientStructure.BrickColor = BrickColor.new("Forest green");
						else
							GoodToPlace = false;
							clientStructure.BrickColor = BrickColor.new("Crimson");
						end;
					end;
					local newAnglesCFrame = CFrame.Angles(0, math.rad(yorientation), 0);
					local newCFrame = CFrame.new(position.X, position.Y + yBuildingOffset, position.Z) * CFrame.fromEulerAnglesXYZ(normal.X*tau, normal.Y*tau, normal.Z*tau);
					clientStructure.CFrame = newCFrame;
				end)
				UIS.InputBegan:Connect(function(input)
					if input.KeyCode == Enum.KeyCode.R then 
						rKeyIsPressed = true;
						local rotationSpeed = 5;
						while rKeyIsPressed do
							task.wait();
							if placingStructure == true then 
								yorientation = yorientation + rotationSpeed;
							end;
						end;
					end;
				end);
				UIS.InputEnded:Connect(function(Input)
					if Input.KeyCode == Enum.KeyCode.R then
						rKeyIsPressed = false;
					end;
				end);
				UIS.InputBegan:Connect(function(input)
					if input.UserInputType == Enum.UserInputType.MouseButton1 then
						if placingStructure == true then
							if GoodToPlace == true then
								local StructureCFrame = clientStructure.CFrame;
								PlaceStructure = PlaceStructure:FireServer(clientStructure.Name, StructureFrame);
								if PlaceStructure == true then
									PlaceStructure = false;
									clientStructure:Destroy();
									StructureFrame.Visible = true;
								end;
							end;
						end;
					end;
				end);
			end;
		end);
	end;	
end;

Footage of error:
https://gyazo.com/1148ca47f98ff27c9b8e3ce1e8fffb32

Anyone got a solution? Can’t seem to solve the problem but it doesn’t seem to be too difficult for someone with the prerequisite knowledge

Depending on the axis you would prefer to be set on the ray’s normal it would go somewhere along the lines of this:

CFrame.lookAt(SelectedPosition, SelectedPosition+Normal, SelectedPosition+(Normal:Cross(Vector3.yAxis) ).Unit ) -- Last Axis is up vector
-- Preferably CFrame.fromMatrix if you would like to choose a different side to look at.

Works exactly as intended. Thanks a lot for the help!