Hello everyone, I am making a tycoon game, basically for a part of the tycoon I want players to move things around. I have made a basic placement system before. However, I do not know where to start for a grid placement system.
I don’t know what I would use to make the system. I am pretty bad with CFrames and I am just stuck and blank-minded. Does anyone have any ideas or any resources that can help me? I also am terrible with roblox math, I do have the basics down for raycasting though.
I have only a little experience with grid placing, but I believe the answer may be rounding all the cframe values, and then multiplying them by the grid’s size in studs.
CFrame stands for CoordinateFrame, keeping the instance’s rotational value and positional value. For this scenario, (assuming you don’t want [insert item here] to pivot off of walls) you only need Vector3, a positional value. The script may look like:
local x_grid = math.round(mouse_hit.p.X)*4 -- Assuming you have the mouse's hit position. 4 is the grid size.
local z_grid = math.round(mouse_hit.p.Z)*4 -- Same as x, skipping y for now.
place_item:SetPrimaryPartCFrame(CFrame.new(x_grid,mouse_hit.p.Y,z_grid)) -- Set the model's position.
This script probably won’t work, but it is an example of how I’d go about doing a grid placing system. This script assumes you have the mouse.hit value, which could be obtained through a RemoteEvent instance. As for the place_item:SetPrimaryPartCFrame(cf), all it does is position a model, assuming the model has a PrimaryPart, which can be set in the properties tab. Note: you may want to set the mouse’s TargetFilter to exclude the models you use for placing, so it doesn’t try to pivot off of what you’re placing
I have not tested this, and I’m pretty sure it’ll fail, (like most first-tries in coding) but I hope you understand the basic idea.
local gridSize = 4
local function GetGridPos(Vector)
return Vector3.new(Vector.X-Vector.X%gridSize,Vector.Y-Vector.Y%gridSize,Vector.Z-Vector.Z%gridSize)
end
Oh well this is Something i used to struggle with back then when i started. Well lets start shall we?
So first take mouses UnitRay
local Mouse = game.Players.LocalPlayer:GetMouse()
Mouse.UnitRay --This thing
Next RaycastParams. You should have a specific space where you CAN place stuff.
local WhereToPlace = {YourPartAlsoMakeSureToMakeThisInATableOrWontWork}
local RayP = RaycastParams.new()
RayP.FilterInstancesDescendants(WhereToPlace)
RayP.FilterType = Enum.RaycastFilterType.Whitelist
--Raycast
local Ray = workspace:Raycast(Mouse.UnitRay.Origin,Mouse.UnitRay.Direction times 1000,RayP)
Thanks, it’s finally not confusing, so I believe target filter is what you want the mouse to ignore correct? So I think I would set this to the placed objects?
So I actually edited @inotrandom’s suggestion and it worked VERY well. However it isn’t directly next to the mouse (the part), here it is:
local mouse = game.Players.LocalPlayer:GetMouse()
game:GetService("RunService").RenderStepped:Connect(function()
local x_grid = math.round(mouse.Hit.p.X)*4 -- Assuming you have the mouse's hit position. 4 is the grid size.
local z_grid = math.round(mouse.Hit.p.Z)*4 -- Same as x, skipping y for now.
game.Workspace.Part.CFrame = CFrame.new(x_grid,mouse.Hit.p.Y,z_grid) -- Set the model's position.
end)
But also, my biggest question is with all of this, is how I would I make it so the part doesn’t go off the canvas? Would I need an invisible wall or something?
local width = 5
local height = 5
local array = table.create(width)
for x = 1,width do
array[x] = table.create(height)
for y = 1,height do
array[x][y] = x*y
end
end
Yea, you could definitely add a third dimension to this. But this on it’s own is just a 2d plane of points, basically. You could now add something like
~~
array[x][y] = x * y
local Part = Instance.new("Part", workspace)
Part.Size = Vector3.new(width, 1, height)
Part.Position = Vector3.new(0,0,0) + Vector3.new(x*width, 0, y*height)
end
Should add parts to visualize the grid. Obviously you’ll need to work out the details yourself!