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.
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.)
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)
I’m not saying you’re wrong, as this could be a component to fix my code. Though, this is the effect now.
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)
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)
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.
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.