Having problems with positioning objects on top of other objects based off normals

I’m trying to make a building system for a game I’m working on using normals returned from :FindPartOnRayWithIgnoreList. However, I ran into a problem with the object being offset from the position it should be as well as the object phasing into objects it’s supposed to be on top of. When I printed out the normal returned, it shows some insane numbers.

One of the outputs:
-2.18581846e-08, 1, -1.99148631e-09

To remedy this I tried using math.ceil and math.floor, however this would cause the normal to be for example, Vector3.new(-1, -1, 0) or Vector3.new(-1, -1, -1), causing the part to be offset from the position its supposed to be based on the mouse position.

local ThisPlayer = PlayerService.LocalPlayer
local Camera = workspace.CurrentCamera
local MoveIncrement = 1

placeMode.Event:Connect(function()
	local ObjPlaceholder = SelectedObj:Clone()
	ObjPlaceholder.Material = Enum.Material.Plastic
	ObjPlaceholder.BrickColor = BrickColor.new("Bright red")
	ObjPlaceholder.Transparency = 0.5
	ObjPlaceholder.CanCollide = false
	ObjPlaceholder.Parent = workspace
	
	local MouseMoved = UserInputService.InputChanged:Connect(function(Input, Gameprocessed)
		if Gameprocessed then return end
		
		if Input.UserInputType == Enum.UserInputType.MouseMovement then
			local MousePos = UserInputService:GetMouseLocation()
			local MouseRay = Camera:ViewportPointToRay(MousePos.X, MousePos.Y)
			MouseRay = Ray.new(MouseRay.Origin, MouseRay.Direction * 999)
			
			local Hit, Pos, Normal = workspace:FindPartOnRayWithIgnoreList(MouseRay, {ObjPlaceholder, ThisPlayer.Character})
			local ObjectNormal = Vector3.new(ObjPlaceholder.Size.X * 0.5, ObjPlaceholder.Size.Y * 0.5, ObjPlaceholder.Size.Z * 0.5) * Normal
			local X, Y, Z = Pos.X - (Pos.X % MoveIncrement), Pos.Y - (Pos.Y % MoveIncrement), Pos.Z - (Pos.Z % MoveIncrement)
			
			print(Normal)
			ObjPlaceholder.Position = Vector3.new(X, Y, Z) + ObjectNormal
		end
	end)
end)
1 Like

you can position the part by setting the position to hitPosition + normal * half the part’s size:

local player = game.Players.LocalPlayer
local camera = workspace.CurrentCamera
local UIS = game:GetService("UserInputService")
local MoveIncrement = 1

local ObjPlaceholder =  Instance.new("Part")
ObjPlaceholder.Material = Enum.Material.Plastic
ObjPlaceholder.BrickColor = BrickColor.new("Bright red")
ObjPlaceholder.Transparency = 0.5
ObjPlaceholder.CanCollide = false
ObjPlaceholder.Parent = workspace

game:GetService("RunService").RenderStepped:Connect(function()
	local MousePos = UIS:GetMouseLocation()
	local MouseRay = camera:ViewportPointToRay(MousePos.X, MousePos.Y)
	MouseRay = Ray.new(MouseRay.Origin, MouseRay.Direction * 999)
	
	local hit, pos, normal = workspace:FindPartOnRayWithIgnoreList(MouseRay, {ObjPlaceholder, player.Character})
	
	ObjPlaceholder.Position = pos + normal * (ObjPlaceholder.Size/2)
end)
3 Likes

Thanks for helping me out! :+1:t2:

1 Like