Orientation help

what i am trying to do is spawn a part at the mouse position and set its orientation correctly
image

image

Part.CFrame = CFrame.new(Mouse.Hit.Position)

I didnโ€™t test it, but a similar approach should work.

local players = game:GetService("Players")

local localPlayer = players.LocalPlayer;
local mouse = localPlayer:GetMouse();
local camera = workspace.CurrentCamera;

function SpawnPart()
    local spawnDistance = 10^4 -->> If an object is a greater distance in studs than that, it will not spawn the part.
    local rayCastParams = RaycastParams.new(); -->> You can modify it
    local rayCast = workspace:Raycast(camera.CFrame.Position, (mouse.Hit.Position - camera.CFrame.Position).Unit*(spawnDistance), rayCastParams);
    if rayCast then
        local part = Instance.new("Part")
        -->> Apply whatever changes
        part.Position = mouse.Hit.Position
        part.CFrame = CFrame.lookAt(part.Position, part.Position + rayCast.Normal)
        part.Parent = workspace
    else
        -->> There is no surface where the mouse is at.
    end;
end;

-->> Calling SpawnPart() would search for a surface the mouse is on, and create a part rotated with respect to the surface.

how can i fix this problem?
image

This has fixed the problem when I just tested:

local players = game:GetService("Players")

local localPlayer = players.LocalPlayer;
local mouse = localPlayer:GetMouse();
local camera = workspace.CurrentCamera;

function SpawnPart()
	local spawnDistance = 10^4 -->> If an object is a greater distance in studs than that, it will not spawn the part.
	local rayCastParams = RaycastParams.new(); -->> You can modify it
	local rayCast = workspace:Raycast(camera.CFrame.Position, (mouse.Hit.Position - camera.CFrame.Position).Unit*(spawnDistance), rayCastParams);
	if rayCast then
		local part = Instance.new("Part")
		part.Shape = Enum.PartType.Cylinder
		-->> Apply whatever changes
		part.Anchored = true
		part.Size = Vector3.one
		
		part.Position = mouse.Hit.Position
		part.CFrame = CFrame.lookAt(part.Position + rayCast.Normal*(part.Size/2), part.Position + rayCast.Normal)*CFrame.Angles(math.pi, math.pi/2, 0)
		part.Parent = workspace
	else
		-->> There is no surface where the mouse is at.
	end;
end;

while task.wait(3) do
	SpawnPart()
end;

I just offset the position by the normal vector times half the size vector.
Edit: I again changed something in the code because it was not facing correctly when I was using a cylinder instead (like in the example you showed), so by rotating it it was fixed.

thank you
everything is working perfectly

1 Like

apologies for disturbing again but would there be a way to only spawn the part as shown in this picture?
image

You donโ€™t have to apologize for asking a question, and secondly, yes, you can check if the X and Z components of the normal vector are 0 (that means that the direction is not facing sideways at all, so it must be either upwards or downards), I will provide a code momentarily.

local players = game:GetService("Players")

local localPlayer = players.LocalPlayer;
local mouse = localPlayer:GetMouse();
local camera = workspace.CurrentCamera;

function SpawnPart()
	local spawnDistance = 10^4 -->> If an object is a greater distance in studs than that, it will not spawn the part.
	local rayCastParams = RaycastParams.new(); -->> You can modify it
	local rayCast = workspace:Raycast(camera.CFrame.Position, (mouse.Hit.Position - camera.CFrame.Position).Unit*(spawnDistance), rayCastParams);
	if rayCast then
		print(rayCast.Normal)
		if rayCast.Normal.X == 0 and rayCast.Normal.Z == 0 then
			local part = Instance.new("Part")
			part.Shape = Enum.PartType.Cylinder
			-->> Apply whatever changes
			part.Anchored = true
			part.Size = Vector3.one

			part.Position = mouse.Hit.Position
			part.CFrame = CFrame.lookAt(part.Position + rayCast.Normal*(part.Size/2), part.Position + rayCast.Normal)*CFrame.Angles(math.pi, math.pi/2, 0)
			part.Parent = workspace
		else
			-->> The surface is sideways
		end
	else
		-->> There is no surface where the mouse is at.
	end;
end;
1 Like