Here is an advanced placement system script. It rounds your placement part to the nearest point based on the mouses hit position. Here is the script:
wait()
local plr = game.Players.LocalPlayer
local posX
local posZ
local mouse = plr:GetMouse()
local gridSize = 5
local part = nil
local function Snap()
posX = math.floor(mouse.Hit.X / gridSize + 1) * gridSize
posZ = math.floor(mouse.Hit.Z / gridSize + 1) * gridSize
local mousePositions = {
mouseX = mouse.Hit.Position.X;
mouseZ = mouse.Hit.Position.Z;
}
local predictedPositions = {
xPlusGridSize = posX + 5;
xMinusGridSize = posX - 5;
zPlusGridSize = posZ + 5;
zMinusGridSize = posZ - 5;
}
local x1 = math.abs(predictedPositions.xPlusGridSize - mousePositions.mouseX)
local x2 = math.abs(predictedPositions.xMinusGridSize - mousePositions.mouseX)
local z1 = math.abs(predictedPositions.zPlusGridSize - mousePositions.mouseZ)
local z2 = math.abs(predictedPositions.zMinusGridSize - mousePositions.mouseZ)
if x1 < x2 then
posX = predictedPositions.xPlusGridSize
else
posX = predictedPositions.xMinusGridSize
end
if z1 < z2 then
posZ = predictedPositions.zPlusGridSize
else
posZ = predictedPositions.zMinusGridSize
end
end
local function createPartWithParams(size)
local ins = Instance.new("Part", workspace)
ins.Name = plr.Name.."_PlacePart"
ins.CanCollide = false
ins.Anchored = true
ins.Transparency = 0.7
ins.BrickColor = BrickColor.Green()
ins.Size = size
part = ins
end
Snap()
while mouse and wait() do
Snap()
if part then
part.Position = Vector3.new(posX,part.Size.Y/2,posZ)
else
createPartWithParams(Vector3.new(gridSize,gridSize,gridSize))
end
end
You should probably rename the title to grid movement script as the script does not do the placement part and it’s not that high quality of a script. You’re not using RunService, not using the task library etc.
But for anybody wondering, yes, the script does work, but it won’t be performant.
Wouldn’t it be better to return the part created? Also, I think the function should be called createPart. The only argument is size. And, you should set the parent of the part last.
No need to wait.
mouse is always going to be truthy, so you don’t need that in the condition. And, you don’t need that initial Snap() call since it’s the first thing in the loop.
There’s a lot of math and logic in this script can should be optimized, I wouldn’t use this.
might actually use this, ive always been struggling with grid-based placement system even though if i get it working there will be some kind of bug i couldnt fix
-- Set up some constants
local INTERACTION_DISTANCE = 10
local OPEN_ANGLE = 90
local CLOSE_ANGLE = 0
-- Find the Door part in the game
local door = game.Workspace:FindFirstChild("Door")
-- If we didn't find the Door part, print an error message and exit
if not door then
print("Error: Could not find Door in Workspace")
return
end
-- Set the door's initial state
local doorState = "closed"
door.CFrame = door.CFrame * CFrame.Angles(0, math.rad(CLOSE_ANGLE), 0)
-- Define a function to handle player input
local function onKeyPress(inputObject, gameProcessedEvent)
-- Ignore the event if it's already been processed
if gameProcessedEvent then
return
end
-- Ignore the event if the player isn't pressing the "E" key
if inputObject.KeyCode ~= Enum.KeyCode.E then
return
end
-- Check if the player is close enough to the door
local player = game.Players.LocalPlayer
local playerPos = player.Character.HumanoidRootPart.Position
local distance = (playerPos - door.Position).Magnitude
if distance > INTERACTION_DISTANCE then
return
end
-- Toggle the door's state
if doorState == "closed" then
doorState = "open"
door.CFrame = door.CFrame * CFrame.Angles(0, math.rad(OPEN_ANGLE), 0)
else
doorState = "closed"
door.CFrame = door.CFrame * CFrame.Angles(0, math.rad(-OPEN_ANGLE), 0)
end
end
-- Connect the function to the player's input events
game:GetService("UserInputService").InputBegan:Connect(onKeyPress)
Why isn’t doorState a boolean? Why does it use game.Workspace? Why doesn’t it use GetPivot? Won’t spam closing and opening the door make it slightly rotated wrong? Why is the player defined in the function? Why would you check if the Door existed to not break the script, and then stop the script anyway? Shouldn’t it use WaitForChild?
what @Sophie said and also I didn’t really specify anything so the chat robot was going off of “unknown information.” If I were to give the chat bot more instructions or I told them certain mistakes in the code, the chat bot would have corrected itself. its still in development so its not completely perfect however its pretty good for the amount of information I gave it.