What do you want to achieve?
A method to check whether a part adjacent to another is occupied
(if it is then don’t place a part)
(if it isn’t then do place a part)
What is the issue?
As of current when a player spawns in (indicated by the red dot) the “baseplate” spawns 4 others, on each x and z axis.
Now the player has moved to another baseplate (indicated by the red dot), but I don’t know how to stop the script from placing another box inside another (represented by the raised box in the middle, which has 2 inside of it)
This is the simple hierarchy ^^^
What solutions have you tried so far?
I have tried using FindPartsInRegion3, but can’t exactly get it to work, encountering errors.
local touchPart = script.Parent
local map = game:GetService("ServerStorage"):WaitForChild("Map")
local movementAmount = 2048
local mapGeneration = false
local positivePositionX = false
local negativePositionX = false
local positivePositionY = false
local negativePositionY = false
touchPart.Touched:Connect(function(hit)
local debounce = false
local humanoid = hit.Parent.Humanoid
if humanoid and debounce == false then
debounce = true
if mapGeneration == false then
mapGeneration = true
local mapPositiveX = map:Clone()
local basePlate = mapPositiveX:FindFirstChild("Baseplate")
local basePlate:Parent = workspace
local currentLocationXmapPositiveX = touchPart.Position.X
local currentLocationZmapPositiveX = touchPart.Position.Z
mapPositiveX.Parent = workspace
local assetsmapPositiveX = mapPositiveX:GetChildren()
for i, v in pairs (assetsmapPositiveX) do
v.Position = Vector3.new(currentLocationXmapPositiveX + movementAmount, 0, currentLocationZmapPositiveX)
end
local mapPositiveZ = map:Clone()
local currentLocationXmapPositiveZ = touchPart.Position.X
local currentLocationZmapPositiveZ = touchPart.Position.Z
mapPositiveZ.Parent = workspace
local assetsmapPositiveZ = mapPositiveZ:GetChildren()
for i, v in pairs (assetsmapPositiveZ) do
v.Position = Vector3.new(currentLocationXmapPositiveZ, 0, currentLocationZmapPositiveZ + movementAmount)
end
local mapNegativeZ = map:Clone()
local currentLocationXmapNegativeZ = touchPart.Position.X
local currentLocationZmapNegativeZ = touchPart.Position.Z
mapNegativeZ.Parent = workspace
local assetsmapNegativeZ = mapNegativeZ:GetChildren()
for i, v in pairs (assetsmapNegativeZ) do
v.Position = Vector3.new(currentLocationXmapNegativeZ, 0, currentLocationZmapNegativeZ - movementAmount)
end
local mapNegativeX = map:Clone()
local currentLocationXmapNegativeX = touchPart.Position.X
local currentLocationZmapNegativeX = touchPart.Position.Z
mapNegativeX.Parent = workspace
local assetsmapNegativeX = mapNegativeX:GetChildren()
for i, v in pairs (assetsmapNegativeX) do
v.Position = Vector3.new(currentLocationXmapNegativeX - movementAmount, 0, currentLocationZmapNegativeX)
end
end
debounce = false
end
end)
P.S. sorry for the sloppy code I’m still new at this
This method should probably be revised from root up. Touched event is easy to implement, but is very inconsistent and unreliable. Numerous connections to Touched isn’t very easy on memory either, so here are some alternatives to determine what tile players reside in:
Raycast downwards from every player with a CollisionGroup that only collides with tiles.
Mathematically determine the tile by taking the character’s position and comparing it to boundaries.
As for determining what adjacent tiles to fill, you could simply create a 2D array:
local grid = table.create(99, {}); --creates a table with 99 subtables, each representing a column on the y-axis
grid[50][50] = tile:Clone(); --50, 50 can be your center, you can reposition it according to its size and where the origin of the tile grid should be
--when the server detects a player on the a tile, simply check grid[x + 1][y], grid[x - 1][y], grid[x][y + 1], grid[x][y - 1] assuming x and y represent the location of the relevant tile within the grid and create a tile for each tested position if its unoccupied. if the relevant tile as at the side of grid then grid[x + 1][y] or grid[x - 1][y] will throw since grid[x + 1] or grid[x - 1] will be nil, so be sure to check for those before trying to index them
Thank you for the insight, from what I understand using a ray casting and part to part collision would be much better than :touched but I don’t get what you mean by
additionally how would I actually check if the tile being spawned is actually next to the relevant tile
do you know of a source which gives an example of this?
I take it you want to accomplish this? They don’t overlap.
Here’s a template that works with less than 40 lines of code to accomplish this. I did it all client side, but this should give you an idea of what to do and accomplish with some remotes.
It works with rotated pieces as well, should that matter.
If we perceive the tiles as if they conform to a 2D grid, each tile would have four values representing the start and finish from bottom to top and left to right (or two coordinates representing opposite ends of the tile).
Say, for instance, the player was located at (1.2, 2.7) of this theoretical grid of tiles:
Assuming each tile always has a length and width of 1, we can easily assert that the player is within the tile located two tiles right and three tiles up (can be referenced with grid[2][3]) since that is the only tile in which the point (1.2, 2.7) resides. This is determined by comparing the leftmost x value of the tile (1) and the rightmost x value (2) with the player’s x value (1.2); the same applies with y values.
Verification of whether tiles are adjacent shouldn’t be necessary so long as we correctly create adjacent tiles for vacant positions and register them into our 2D array while positioning them correctly.
His method uses raycasting to determine the tile that the player stands on as well as the presence of adjacent tiles, so there is no 2D array in effect here. The method is nonetheless very reliable and resourceful. I’d mark his reply as a solution since it satisfies your needs.
It doesn’t create a grid. A grid is more data-structurally organized and would be less performance-intensive if that was an issue.
At this point, I always remark that the decision of which to implement is which is easier to code, keep organized, and doesn’t cause a performance bottleneck.
Many scripters get obsessed with over-optimizing and micro-optimizing so much so that it compromises the results of their project.
If the raycasting method works fine for your needs, then I recommend using it. It’s simpler to implement but harder to query (you can’t ask the server very easily if there is a map piece at X/Y position because there is no data grid).
If the abstract grid (stored in Lua data) and querying is what you need, then use the abstract grid method. However, if it is too complicated to code at this time (think your abilities, don’t base off of others’ abilities) then use the raycasting method. I personally would create a grid system if I had a big game in mind. If the extent was just to do what is shown in my short video and nothing more, I’d just use raycasting and be done with things.
These are my opinions, feel free to take what you want out of them.