Part not going on good rotation with normal

Im trying to make a drawing system to draw on every surface like the game spraypaint. but the part is on the wrong orientation but correct on one orientation only here is a example of that happening:


local script:
(unnecessary pieces of code not included)

	local pos = mouse.Hit
		local result = workspace:Raycast(mouse.UnitRay.Origin, mouse.UnitRay.Direction * 1000)
		local normal = result.Normal
		script.DrawEvent:FireServer(pos,normal.X*90,normal.Y*90,normal.Z*90)

server script:
(unnecessary pieces of code not included)

script.Parent.DrawEvent.OnServerEvent:Connect(function(player,pos,x,y,z)
	local part = Instance.new("Part")
    part.Position = Vector3.new(pos.p.X,pos.p.Y,pos.p.Z)
	part.Parent = folder
	part.Anchored = true
	part.Shape = Enum.PartType.Cylinder
	part.Size = Vector3.new(layer,width,width)
	part.Orientation = Vector3.new(x,y,z) 
	part.Material = Enum.Material.SmoothPlastic
	part.Color = Color3.fromHSV(h,s,v)
	part.CanCollide = false
	part.CanQuery = false
	part.CanTouch = false
	part.Name = "DrawPart"
	local lval = Instance.new("NumberValue")
	lval.Name = "Layer"
	lval.Parent = part
	lval.Value = layer*100
end)

Hey @123wolfyking !

The thing is, normal is not the actually the same as Euler angles rotation (which is used in your case).
Normal is the vector, that goes perpendicular to the plane that your raycast hits.

The easiest way you can implement what you’re trying to is:

Local part:

local pos = mouse.Hit.p
local result = workspace:Raycast(mouse.UnitRay.Origin, mouse.UnitRay.Direction * 1000)
local normal = result.Normal
script.DrawEvent:FireServer(pos, normal) -- Just send pos and normal

Server part:

script.Parent.DrawEvent.OnServerEvent:Connect(function(player, pos, normal)
	local part = Instance.new("Part")
    -- (CFrame that starts in pos, and looks to the point pos + normal)
    part.CFrame = CFrame.new(pos, pos + normal)  * CFrame.Angles(0, math.pi/2, 0)
	part.Parent = folder
	part.Anchored = true
	part.Shape = Enum.PartType.Cylinder
	part.Size = Vector3.new(layer,width,width)
	part.Material = Enum.Material.SmoothPlastic
	part.Color = Color3.fromHSV(h,s,v)
	part.CanCollide = false
	part.CanQuery = false
	part.CanTouch = false
	part.Name = "DrawPart"
	local lval = Instance.new("NumberValue")
	lval.Name = "Layer"
	lval.Parent = part
	lval.Value = layer*100
end)

The best part is, this approach will work on any kind of rotated instance, not just the basic block rotated strictly 90 degrees!

Hope that helps.

i get error

Players.123wolfyking.PlayerGui.DrawScript.Server:58: invalid argument #1 to 'new' (Vector3 expected, got CFrame)

Oh, that’s because you pass pos that is not actually a position but a CFrame

local pos = mouse.Hit -- Hit is CFrame value

To get the actual position, do this:

local pos = mouse.Hit.p

Let me know if that works!

does it replicate?
{char limit}

now i get error Players.123wolfyking.PlayerGui.DrawScript.Server:57: invalid argument #2 (Vector3 expected, got nil)

also when i click on it it brings me here

	part.CFrame = CFrame.new(pos, pos + normal)

Then try instead

local pos = mouse.Hit.Position

mouse.Hit.p Is the old style

still the same error nothing is wrong with the position

wait how is it setting the position right but not the orientation im confused

Print out both arguments:

print(pos, normal)
script.DrawEvent:FireServer(pos, normal)
script.Parent.DrawEvent.OnServerEvent:Connect(function(player, pos, normal)
print(pos, normal)

Tell me what is says.

-16.24700927734375, 2.3165130615234375, -2.0841803550720215 1, 0, 0  -  Server - Server:56
-16.24700927734375, 2.3165130615234375, -2.0841803550720215 1, 0, 0  -  Client - DrawScript:35

From what I see, everything should be fine. Both pos and normal are passed to the server, so in no way pos + normal should be equal to nil. Check out if the code was properly copied from what I have send.

i checked it should be
{char limit}

it is the same as you posted i even recopied the code

Okay, do on the server side:

print(pos, normal)
print(pos+normal)
print(CFrame.new(pos, pos+normal))
-16.24700927734375, 11.92670726776123, 0.028084278106689453 1, 0, 0  -  Server -Server:58
    -15.24700927734375, 11.92670726776123, 0.028084278106689453  -  Server - Server:59
  -16.2470093, 11.9267073, 0.0280842781, -0, -0, -1, -0, 1, -0, 1, 0, -0  -  Server - Server:60

the second one is wrong sorry here is the right one

-16.2470093, 12.0348291, 0.0794138908, 0.116985202, 0.0983133167, 0.988255501, -8.73580575e-06, 0.99508822, -0.0989920199, -0.993133664, 0.0115719661,

That basically means, all of the values are calculated properly. Means, there is no problem in the code logic itself. Otherwise, you would have got the same error during the printing. Try to do it step by step:

local newCFrame = CFrame.new(pos, pos + normal) 
print(newCFrame)
part.CFrame = newCFrame
print("CFrame is correct")

i still get the error but the rotation is just wrong