Rotating Character Around Golf Ball

I am working on a golf game right now, and I am currently trying to roate the character holding a golf club around the ball. However, everything I have tried is inconsistent or does not work.

The current way I am doing it is the client requests a rotation part to be made with a remote event. The server creates this rotation part, makes it the primary part of the character, positions it, welds it to the humanoid root part, gives ownership to the client, and returns the part. The client then anchors this part, and makes it so when the camera moves, this rotation part will only move on the y-axis.

The problem is that it is consistently rotating on the y-axis with weird offsets. Additionally, the rotation part’s rotation doesn’t automatically change when the client changes it, so I am also using a remote event to update the position of this part, which is inefficient.

Code
-- Local Script
	-- creates the rotation part under the player
	remoteEvent:FireServer("RotationPart")
	local rotationPart = character:WaitForChild("RotationPart")
	rotationPart.Anchored = true
	local weld = rotationPart:WaitForChild("Weld")
	
	-- set position of rotation part
	local camRotation = camera.CFrame.Rotation
	local rotationX, rotationY, rotationZ = camRotation:ToOrientation()
	cameraConnection = camera:GetPropertyChangedSignal("CFrame"):Connect(function()
		local camRotation = camera.CFrame.Rotation
		local rotationX, rotationY, rotationZ = camRotation:ToOrientation()
		
		-- only rotate on y axis
		local orientation = CFrame.fromOrientation(0, rotationY - 1.75, 0) -- inconsistant
		local newCFrame = CFrame.new(golfBall.Position) * orientation
		
		
		rotationPart.CFrame = newCFrame
		remoteEvent:FireServer("UpdateCFrame", newCFrame) -- inefficient
	end)
-- Server Script
				local offsetFromBall = CFrame.new( -- calculated from ToObjectSpace
					-3.74243164, 2.61268568, 0.0940246582,
					0, 0, -1.00000381,
					0, 1, 0,
					1.00000381, 0, 0
				)
				
				character:SetPrimaryPartCFrame(golfBall.CFrame * offsetFromBall)
				character.PrimaryPart = rotationPart
				
				rotationPart.Position = golfBall.Position
				weld.Enabled = true
Screenshots

Offset from ball taken from DummyHumanoidRootPart.CFrame:ToObjectSpace(Ball.CFrame)


Inconsistent rotation angles (seems to depend on the rotation of your character when you start)
image
image
image

Found a solution, here was the final code with a lot of explanation. (Inside the local script). Big thanks to @5uphi for helping me out with this.

--[[
		This offset was calculated using a dummy's humanoid root part, and getting the offset from 
		it to the ball. Example of how to get it:
		
		print(workspace.Dummy.HumanoidRootPart.CFrame:ToObjectSpace(workspace.GolfBall.CFrame))
	]]
	local offsetFromBall = CFrame.new( 
		-3.74243164, 2.61268568, 0.0940246582, -- Only this part is needed, this is the Vector3 offset
		0, 0, -1.00000381,
		0, 1, 0,
		1.00000381, 0, 0
	)
	
	-- anchor to avoid moving around 
	character.HumanoidRootPart.Anchored = true 
	cameraConnection = camera:GetPropertyChangedSignal("CFrame"):Connect(function()
		-- get the direction the camera is facing
		local cameraDirection = game.Workspace.CurrentCamera.CFrame.LookVector

		-- remove the y axis from the look vector since we don't want to move up and down with the camera
		cameraDirection = Vector3.new(cameraDirection.X, 0, cameraDirection.Z).Unit

		-- get the right direction from the camera forward direction
		local cameraRight = cameraDirection:Cross(Vector3.yAxis)
		
		-- position of the golfBall
		local position = golfBall.Position
		-- move the position back 0.0940246582 studs the Z offset from the ball
		position -= cameraDirection * 0.0940246582
		-- move the position to the left 3.74243164 studs, the X offset from the ball
		position -= cameraRight * 3.74243164
		
		--[[
			Move the position up so the player's legs are on the floor.
			This was gotten from subtracting the animation dummy's hipheight
			to the Y offset from the ball. Beaware if the hipheight is 0,
			you may need to calculate it using a script.
			
			print(workspace.Dummy.HipHeight - - 2.61268568)
		]]
		position += Vector3.new(0,character.Humanoid.HipHeight + 0.5126856799999997,0)

		-- make the player face in the direction of the camera
		local cframe = CFrame.lookAt(position, position + cameraDirection)
		-- rotate the cframe to counter the animation rotation
		cframe *= CFrame.Angles(0, math.rad(-90), 0)

		-- set the character cframe
		character.PrimaryPart.CFrame = cframe
	end)

Additional resources: Vector3 Cross Explanation, How To Calculate Hip Height (The animated dummy may have a hip height of 0 since they don’t come with a humanoid)