Grid placement system only functions on 3 angles

https://gyazo.com/f92f4afe7e5eea1d1d23bc8ec2cc7e2d
^^^
In this video, you can see i can only place a block on the right, top and forward of it, here is my grid placement code.

part.Position = Grid
part.Parent = workspace

Anyone know why this happens / a soloution to it? It’s just a test project i had fun with, but i ran into an issue.

can u post a piece of your code where u detect what surface the mouse is pointing at

script.Parent.RemoteEvent.OnServerEvent:Connect(function(player,HIT,orig)
	local char = script.Parent
	local params = RaycastParams.new()
	params.FilterType = Enum.RaycastFilterType.Blacklist
	params.FilterDescendantsInstances = {char}
	local dir = (HIT.Position - orig).Unit
	local ray = workspace:Raycast(orig,dir*100,params)
	if ray then
		if mode then
			local part = Instance.new("Part")
			part.Name = "Placeable"
			part.Material = Material
			part.Color = Color
			part.Transparency = Transparency
			local GridSize = 3 --> Amount of studs it will move on a grid.
			part.Size = Vector3.new(GridSize,GridSize,GridSize)
			part.Anchored = true

			local Grid = Vector3.new(math.floor(ray.Position.X/GridSize+.5)*GridSize, math.floor(ray.Position.Y/GridSize+.5)*GridSize, math.floor(ray.Position.Z/GridSize+.5)*GridSize)
			part.Position = Grid
			part.Parent = workspace
		else
			if ray.Instance.Name == "Placeable" then
				ray.Instance:Destroy()
			end
		end
	end
end)

You mean this? (raycasting)

well u can make a brand new mechanic for placing when the mouse.Target is an already placed Part
u can use mouse.TargetSurface to get the surface and then use it to get the Surface Vector after that u just set the position of the new part to the position of the part plus the Surface Vector multiplied by the GridSize.

it will look something like this


local function GetVectorFromSurface(Surface,part)
	local Vectors = {
		[Enum.NormalId.Front] = part.CFrame.LookVector,
		[Enum.NormalId.Back] = -part.CFrame.LookVector,
		[Enum.NormalId.Left] = -part.CFrame.RightVector,
		[Enum.NormalId.Right] = part.CFrame.RightVector,
		[Enum.NormalId.Top] = part.CFrame.UpVector,
		[Enum.NormalId.Bottom] = -part.CFrame.UpVector
	}
	
	return Vectors[Surface]
end

local GridSize = 3
Remote.OnServerEvent:Connect(function(plr,MouseTarget,MouseTargetSurface,)
    if MouseTarget:IsDescendantOf(workspace.PartsFolders) then
       local newPart = Instance.new("Part",workspace.PartsFolders)
       newPart.Size = Vector3.new(GridSize,GridSize,GridSize)
       newPart.Position += GetVectorFromSurface(MouseTargetSurface,MouseTarget) * GridSize 
    end
end)

Can’t you just use ray.Normal?

u can also do that too lol
(limit limit)

They work the same right? Because that would be best with my current system.

Yeah, that’s exactly what I would do.

I would also multiply the normal by GridSize / 2 so the estimated point is as close to the center as possible, but that’s just nitpicking.

Also, similar thread:

It’s erroring even tho i did the same exact thing as you, just a bit different.
image
image

can u pass the Mouse.TargetSurface trought the remote
and replace the ray.Normal with it i just realised ray.Normal returns vector and not NormalId

oh alright lemme do that
(LIMITSSSSSSS)

Update, it has some very weird behaviour now.
https://gyazo.com/c4fb8a250ed93c72fd76c2ac755adab1
Basically, it works for the angles that didn’t work, but now it extends it by one gridsize when it’s on the angles that did work.

script.Parent.RemoteEvent.OnServerEvent:Connect(function(player,HIT,orig,surface)
	local char = script.Parent
	local params = RaycastParams.new()
	params.FilterType = Enum.RaycastFilterType.Blacklist
	params.FilterDescendantsInstances = {char}
	local dir = (HIT.Position - orig).Unit
	local ray = workspace:Raycast(orig,dir*100,params)
	if ray then
		if mode then
			local part = Instance.new("Part")
			part.Name = "Placeable"
			part.Material = Material
			part.Color = Color
			part.Transparency = Transparency
			local GridSize = 3 --> Amount of studs it will move on a grid.
			part.Size = Vector3.new(GridSize,GridSize,GridSize)
			part.Anchored = true
			local Grid = Vector3.new(math.floor(ray.Position.X/GridSize+.5)*GridSize, math.floor(ray.Position.Y/GridSize+.5)*GridSize, math.floor(ray.Position.Z/GridSize+.5)*GridSize)
			part.Position = Grid
			part.Parent = workspace.PartsFolders
			if ray.Instance.Name == "Placeable" then
				part.Position += GetVectorFromSurface(surface,ray.Instance) * GridSize
			else
				part.Position = Grid
			end
		else
			if ray.Instance.Name == "Placeable" then
				ray.Instance:Destroy()
			end
		end
	end
end)

^^^this code

Okay, so i ended up just checking if the surface normal was either of those 3 angles, and then made the part.Position += ray.Normal * GridSize, and that worked