Bug With Placement System

I haven’t really scripted in a while, so this might be a dumb question. I tried to make a grid-based placement system. Whenever I click on a side of a block (or part), it goes on the side but the Y axis is either 1-2 studs higher. It also sometimes has a very specific decimal on the Y axis. Here’s an image of what i mean. I have a suspicion that I know why it doesn’t work.

Screenshot 2023-07-04 204923

Also, if you click on one (or more) of the sides (pretty sure its left and back) it instead adds on top of the part (and it doesn’t match with the grid.)

Screenshot 2023-07-04 211356

Here’s the code:

--// SERVICE
local S_USER_INPUT = game:GetService("UserInputService")
local S_PLAYERS = game:GetService("Players")

--// VARIABLES

local PLAYER = S_PLAYERS.LocalPlayer

repeat wait() until PLAYER.Character

local CHARACTER = PLAYER.Character

local MOUSE = PLAYER:GetMouse()

local CAMERA = workspace.CurrentCamera

local GRID_SPACING = 4

local function mouse_racyast()
	local mouse_position = S_USER_INPUT:GetMouseLocation()
	local mouse_ray = CAMERA:ViewportPointToRay(mouse_position.X, mouse_position.Y)
	local raycast_parameters = RaycastParams.new()

	raycast_parameters.FilterType = Enum.RaycastFilterType.Exclude
	raycast_parameters.FilterDescendantsInstances = {CAMERA, CHARACTER:GetDescendants()}

	local raycast_result = workspace:Raycast(mouse_ray.Origin, mouse_ray.Direction * 1000, raycast_parameters)
	
	return raycast_result
end

function get_rounded_position(position : Vector3)
	local position_x = position.X
	local position_y = position.Y
	local position_z = position.Z

	local rounded_x = math.floor((position_x / GRID_SPACING) + 0.5) * GRID_SPACING
	local rounded_z = math.floor((position_z / GRID_SPACING) + 0.5) * GRID_SPACING
	return Vector3.new(rounded_x, position_y, rounded_z)
end

S_USER_INPUT.InputBegan:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		local raycast_result = mouse_racyast()
		if raycast_result.Instance then
			local grid_position = get_rounded_position(raycast_result.Position)
			local position = grid_position + Vector3.new(0, GRID_SPACING / 2, 0)
			for _, block in ipairs(workspace.BLOCKS:GetChildren()) do
				if block.Position == position then return end
			end
			local block = Instance.new("Part")
			MOUSE.TargetFilter = block
			block.Size = Vector3.new(4, 4, 4)
			block.Anchored = true
			block.Material = Enum.Material.SmoothPlastic
			block.Position = position
			block.Parent = workspace.BLOCKS
		end
	end
end)
1 Like

Round the y axis too:

local rounded_y = math.floor((position_y  / GRID_SPACING) + 0.5) * GRID_SPACING

I’m not saying you’re wrong, as this could be a component to fix my code. Though, this is the effect now.

Screenshot 2023-07-05 001757

As you can see, now the block is off by 1 stud. I’d like to mention that when you click on top of the block, it goes perfectly on the block. Also, when I press the left side and the back, it is now in the correct grid; it just goes on the top of the block though. This is probably due to the rounding of the axes.

Here’s my updated code following your suggestion:

--// SERVICE
local S_USER_INPUT = game:GetService("UserInputService")
local S_PLAYERS = game:GetService("Players")

--// VARIABLES

local PLAYER = S_PLAYERS.LocalPlayer

repeat wait() until PLAYER.Character

local CHARACTER = PLAYER.Character

local MOUSE = PLAYER:GetMouse()

local CAMERA = workspace.CurrentCamera

local GRID_SPACING = 4

local function mouse_racyast()
	local mouse_position = S_USER_INPUT:GetMouseLocation()
	local mouse_ray = CAMERA:ViewportPointToRay(mouse_position.X, mouse_position.Y)
	local raycast_parameters = RaycastParams.new()

	raycast_parameters.FilterType = Enum.RaycastFilterType.Exclude
	raycast_parameters.FilterDescendantsInstances = {CAMERA, CHARACTER:GetDescendants()}

	local raycast_result = workspace:Raycast(mouse_ray.Origin, mouse_ray.Direction * 1000, raycast_parameters)
	
	return raycast_result
end

function get_rounded_position(position : Vector3)
	local position_x = position.X
	local position_y = position.Y
	local position_z = position.Z

	local rounded_x = math.floor((position_x / GRID_SPACING) + 0.5) * GRID_SPACING
	local rounded_z = math.floor((position_z / GRID_SPACING) + 0.5) * GRID_SPACING
	local rounded_y = math.floor((position_y  / GRID_SPACING) + 0.5) * GRID_SPACING
	return Vector3.new(rounded_x, rounded_y, rounded_z)
end

S_USER_INPUT.InputBegan:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		local raycast_result = mouse_racyast()
		if raycast_result.Instance then
			local grid_position = get_rounded_position(raycast_result.Position)
			local position = grid_position + Vector3.new(0, GRID_SPACING / 2, 0)
			for _, block in ipairs(workspace.BLOCKS:GetChildren()) do
				if block.Position == position then return end
			end
			local block = Instance.new("Part")
			MOUSE.TargetFilter = block
			block.Size = Vector3.new(4, 4, 4)
			block.Anchored = true
			block.Material = Enum.Material.SmoothPlastic
			block.Position = position
			block.Parent = workspace.BLOCKS
		end
	end
end)

Remove the addition of the Vector3.

Also, when I click too close to the edge it adds it on top of the block, one again probably due to rounding.

Still didn’t work, it’s now off by 3 studs on the Y axis.

Could you show a video of this happening? also you could try adding half of the object.Size.Y to your part Y position you would do it like this (i think)

block.Position = position + Vector3.new(0,raycast_result.Instance.Size.Y/2,0)

Btw i meant Y sorry lol

If i add it to the Z, it’ll be off by 2 studs. Plus, the Z axis isn’t really the problem at the moment.

I really just have to fix the Y of the initial part added.

Actually, the block being off by one stud is likely due to the position of your baseplate. I had this issue, while I was working on a Minecraft like game.

After I add a part on top of the initial one, it is elevated by 2 studs.

Yeah, it was because of the baseplate’s position. Though, I still have to fix the fact that nothing happens whenever you click on the left and back side of the block.

Edit: I should be able to fix it but i’ll let you know if I need help.

Try this:

local grid_position = get_rounded_position(raycast_result.Position + result.Normal * 2)

I used a similar solution, thanks for helping!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.