Hi guys! I’m still currently making a grid placement system and it has been going well. I followed a template made by another user and customized parts of it. I also have a plot placement system inside my game and I’m not quite sure how to connect that to my grid placement system. Basically what I want to do is make it so that the player is unable to place items outside of their assigned plot. I’ve tried for the past 2 hours and nothing worked
I guess it depends on how your current grid placement system is. Can you please provide a sample of the code? Depending on how it is implemented, the solution will vary slightly
Are the plots rotated at all? Are they squares? Are the dimensions constant?
theyre not rotated, size is 26, 1, 26 yes square
In that case, you should be able to modify the SnapToGrid function like this:
local plot = ...
local function SnapToGrid(position, hitPart)
position = Vector3.new(
math.clamp(position.X, plot.Position.X - Plot.Size.X, plot.Position + plot.Size.X),
position.Y,
math.clamp(position.Z, plot.Position.Z - Plot.Size.Z, plot.Position + plot.Size.Z),
)
return Vector3.new(
math.floor(position.X / gridSize + 0.5) * gridSize,
hitPart.Position.Y + (ObjectClone.Size.Y / 2) + (hitPart.Size.Y / 2), -- Prevents underground placement
math.floor(position.Z / gridSize + 0.5) * gridSize
)
end
do i add my code inside the 3 dots? and would this setup affect my code in any way?
You should set the plot
variable at some point, probably just using a loop to go through all the plots and checking if the local player is the one who owns the plot
Replace the 3 dots with the player’s plot .
on the server, create a tag for the plot with the player’s name (or user ID if you want to be truly safe), in your RenderStepped just check if the Hit includes the tag of the player’s name.
I’m also making a plot system rn, and the code I use for keeping a part inside the plot is like this:
It might not be good though, but it works for me
function module.bounds(c: CFrame, primaryRotation: Vector3, Size: Vector3, plot:BasePart): CFrame
-- Calculate plot bounds in local space
local plotCFrame:CFrame = plot.CFrame
local plotSize = plot.Size
-- Transform the input point to the plot's local space
local relativePos = plotCFrame:PointToObjectSpace(c.Position)
-- Account for primary part rotation
local primaryRotCFrame = CFrame.Angles(
math.rad(primaryRotation.X),
math.rad(primaryRotation.Y),
math.rad(primaryRotation.Z)
)
-- Calculate the rotated size
local primarySize = Size
local rotatedSize = Vector3.new(
math.abs(primarySize.X * primaryRotCFrame.RightVector.X) +
math.abs(primarySize.Y * primaryRotCFrame.UpVector.X) +
math.abs(primarySize.Z * primaryRotCFrame.LookVector.X),
math.abs(primarySize.X * primaryRotCFrame.RightVector.Y) +
math.abs(primarySize.Y * primaryRotCFrame.UpVector.Y) +
math.abs(primarySize.Z * primaryRotCFrame.LookVector.Y),
math.abs(primarySize.X * primaryRotCFrame.RightVector.Z) +
math.abs(primarySize.Y * primaryRotCFrame.UpVector.Z) +
math.abs(primarySize.Z * primaryRotCFrame.LookVector.Z)
)
-- Update bounds based on rotated size
local lowerX = -plotSize.X / 2 + rotatedSize.X / 2
local upperX = plotSize.X / 2 - rotatedSize.X / 2
local lowerY = plotSize.Y/2 + rotatedSize.Y/2
local upperY = Placement:GetAttribute("MaxHeight" ) - rotatedSize.Y / 2
local lowerZ = -plotSize.Z / 2 + rotatedSize.Z / 2
local upperZ = plotSize.Z / 2 - rotatedSize.Z / 2
-- Clamp the position in local space
local clampedX = math.clamp(relativePos.X, math.min(lowerX, upperX), math.max(lowerX, upperX))
local clampedY = math.clamp(relativePos.Y, math.min(lowerY, upperY), math.max(lowerY, upperY))
local clampedZ = math.clamp(relativePos.Z, math.min(lowerZ, upperZ), math.max(lowerZ, upperZ))
-- Transform the clamped position back to world space
local clampedWorldPos = plotCFrame:PointToWorldSpace(Vector3.new(clampedX, clampedY, clampedZ))
local clampedVector = CFrame.new(clampedWorldPos.X, clampedWorldPos.Y, clampedWorldPos.Z)
--if rotatedSize.X >= MaxScale.X then
-- primarySize = Vector3.new(MaxScale.X, primarySize.Y, primarySize.Z)
--end
--if rotatedSize.Y >= MaxScale.Y then
-- primarySize = Vector3.new(primarySize.X, MaxScale.Y, primarySize.Z)
--end
--if rotatedSize.Z >= MaxScale.X then
-- primarySize = Vector3.new(primarySize.X, primarySize.Y, MaxScale.Z)
--end
if primarySize.X >= plot.Size.X then
primarySize = Vector3.new(plot.Size.X, primarySize.Y, primarySize.Z)
clampedVector = CFrame.new(plot.Position.X, clampedVector.Y, clampedVector.Z)
end
if primarySize.Y >= Placement:GetAttribute("MaxHeight" ) then
primarySize = Vector3.new(primarySize.X, Placement:GetAttribute("MaxHeight"), primarySize.Z)
end
if primarySize.Z >= plot.Size.Z then
primarySize = Vector3.new(primarySize.X, primarySize.Y, plot.Size.Z)
clampedVector = CFrame.new(clampedVector.X, clampedVector.Y, plot.Position.Z)
end
-- Combine the clamped position with the rotation from the original CFrame
print(clampedVector * c - c.Position)
return clampedVector * c - c.Position, primarySize
end
what is a tag? sorry I’m new to this and also what do you mean with the player’s name?
is this the whole script? what is maxheight?
oh max height is just a vector, you can set it to what ever you want, and also this the whole script
ok so i’ve edited this script a bit but it works!!!
local plot = findPlot(player) -- Now using the player's plot
local function SnapToGrid(position, hitPart)
-- Get the half-width and half-length of the object
local halfWidth = ObjectClone.Size.X / 2
local halfLength = ObjectClone.Size.Z / 2
-- Calculate plot boundaries
local plotHalfX = plot.Size.X / 2
local plotHalfZ = plot.Size.Z / 2
-- Clamp the object's position so it doesn't exceed the plot's boundaries
local clampedX = math.clamp(position.X, plot.Position.X - plotHalfX + halfWidth, plot.Position.X + plotHalfX - halfWidth)
local clampedZ = math.clamp(position.Z, plot.Position.Z - plotHalfZ + halfLength, plot.Position.Z + plotHalfZ - halfLength)
-- Set the new position with the clamped values
position = Vector3.new(clampedX, position.Y, clampedZ)
-- Return the snapped position, also adjusting the Y to prevent underground placement
return Vector3.new(
math.floor(position.X / gridSize + 0.5) * gridSize,
hitPart.Position.Y + (ObjectClone.Size.Y / 2) + (hitPart.Size.Y / 2), -- Prevents underground placement
math.floor(position.Z / gridSize + 0.5) * gridSize
)
end
so the only problem is that the length and width of the object has to be divisible by 2 or otherwise it won’t perfectly snap to the grid lol
the original script you gave didn’t work and i could only rotate/move the object once according to where my character face but i fixed it!
also some other problem: the object tends to snap to the baseplate if i try to move it out any further. will fix that later
thank you sir
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.