placement: fix selection box

This commit is contained in:
2026-01-08 19:42:54 +02:00
committed by Tangled
parent b34830a493
commit d4992b3095

View File

@@ -26,6 +26,15 @@ raycastParams.FilterDescendantsInstances = {PlacementManager.ChunkFolder}
raycastParams.FilterType = Enum.RaycastFilterType.Include raycastParams.FilterType = Enum.RaycastFilterType.Include
raycastParams.IgnoreWater = true raycastParams.IgnoreWater = true
local Mouse: Mouse = nil
local lastNormalId: Enum.NormalId? = nil
local lastRaycastFailure: string? = nil
local lastSelectedChunkKey: string? = nil
local lastSelectedBlockKey: string? = nil
local BREAK_ROLLBACK_TIMEOUT = 0.6
local pendingBreaks = {}
local clearSelection
if _G.__BLOCKSCRAFT_PLACEMENT_MANAGER then if _G.__BLOCKSCRAFT_PLACEMENT_MANAGER then
return _G.__BLOCKSCRAFT_PLACEMENT_MANAGER return _G.__BLOCKSCRAFT_PLACEMENT_MANAGER
end end
@@ -35,6 +44,17 @@ PlacementManager.SelectionBox = script.SelectionBox:Clone()
PlacementManager.SelectionBox.Name = "$SelectionBox"..(game:GetService("RunService"):IsServer() and "_SERVER" or "") PlacementManager.SelectionBox.Name = "$SelectionBox"..(game:GetService("RunService"):IsServer() and "_SERVER" or "")
PlacementManager.SelectionBox.Parent = game:GetService("Workspace"):FindFirstChildOfClass("Terrain") PlacementManager.SelectionBox.Parent = game:GetService("Workspace"):FindFirstChildOfClass("Terrain")
PlacementManager.SelectionBox.Adornee = nil PlacementManager.SelectionBox.Adornee = nil
PlacementManager.SelectionBox:GetPropertyChangedSignal("Adornee"):Connect(function()
local adornee = PlacementManager.SelectionBox.Adornee
if not adornee then
return
end
adornee.AncestryChanged:Connect(function(_, parent)
if not parent then
clearSelection("adornee destroyed")
end
end)
end)
-- Trash method TODO: Fix this -- Trash method TODO: Fix this
local function findChunkFolderFromDescendant(inst: Instance): Instance? local function findChunkFolderFromDescendant(inst: Instance): Instance?
@@ -71,10 +91,12 @@ local function resolveBlockInstance(chunkFolder: Instance, chunkName: string, bl
return chunkInst:FindFirstChild(blockName) return chunkInst:FindFirstChild(blockName)
end end
local function clearSelection(reason: string?) clearSelection = function(reason: string?)
PlacementManager.SelectionBox.Adornee = nil PlacementManager.SelectionBox.Adornee = nil
PlacementManager.SelectionBox.Parent = nil PlacementManager.SelectionBox.Parent = nil
lastNormalId = nil lastNormalId = nil
lastSelectedChunkKey = nil
lastSelectedBlockKey = nil
if reason then if reason then
lastRaycastFailure = reason lastRaycastFailure = reason
end end
@@ -105,11 +127,6 @@ local function findChunkAndBlock(inst: Instance): (string?, string?)
return nil, nil return nil, nil
end end
local Mouse: Mouse = nil
local lastNormalId: Enum.NormalId? = nil
local BREAK_ROLLBACK_TIMEOUT = 0.6
local pendingBreaks = {}
local lastRaycastFailure: string? = nil
local function vectorToNormalId(normal: Vector3): Enum.NormalId local function vectorToNormalId(normal: Vector3): Enum.NormalId
local ax, ay, az = math.abs(normal.X), math.abs(normal.Y), math.abs(normal.Z) local ax, ay, az = math.abs(normal.X), math.abs(normal.Y), math.abs(normal.Z)
if ax >= ay and ax >= az then if ax >= ay and ax >= az then
@@ -324,6 +341,15 @@ function PlacementManager:Raycast()
script.RaycastResult.Value = nil script.RaycastResult.Value = nil
return return
end end
local chunkKey = makeChunkKey(chunkCoords.X, chunkCoords.Y, chunkCoords.Z)
local blockKey = makeBlockKey(blockCoords.X, blockCoords.Y, blockCoords.Z)
-- block is being optimistically broken, do not highlight it
if getPendingBreak(chunkKey, blockKey) then
clearSelection("block pending break")
script.RaycastResult.Value = nil
return
end
-- hide selection if block no longer exists (air/removed) -- hide selection if block no longer exists (air/removed)
local chunk = ChunkManager:GetChunk(chunkCoords.X, chunkCoords.Y, chunkCoords.Z) local chunk = ChunkManager:GetChunk(chunkCoords.X, chunkCoords.Y, chunkCoords.Z)
@@ -341,7 +367,11 @@ function PlacementManager:Raycast()
end end
lastRaycastFailure = nil lastRaycastFailure = nil
setSelection(blockInstance, PlacementManager.ChunkFolder) if lastSelectedChunkKey ~= chunkKey or lastSelectedBlockKey ~= blockKey then
setSelection(blockInstance, PlacementManager.ChunkFolder)
lastSelectedChunkKey = chunkKey
lastSelectedBlockKey = blockKey
end
script.RaycastResult.Value = objLookingAt script.RaycastResult.Value = objLookingAt
lastNormalId = vectorToNormalId(result.Normal) lastNormalId = vectorToNormalId(result.Normal)
debugPlacementLog( debugPlacementLog(
@@ -520,9 +550,8 @@ function PlacementManager:GetBlockAtMouse(): nil | {chunk:Vector3, block: Vector
local selectedPart = PlacementManager:RaycastGetResult() local selectedPart = PlacementManager:RaycastGetResult()
--print(selectedPart and selectedPart:GetFullName() or nil) --print(selectedPart and selectedPart:GetFullName() or nil)
if selectedPart == nil then if selectedPart == nil then
PlacementManager.SelectionBox.Adornee = nil clearSelection()
script.RaycastResult.Value = nil script.RaycastResult.Value = nil
lastNormalId = nil
debugPlacementLog("[PLACE][CLIENT][TARGET]", "no selectedPart after raycast", lastRaycastFailure) debugPlacementLog("[PLACE][CLIENT][TARGET]", "no selectedPart after raycast", lastRaycastFailure)
return nil return nil
end end
@@ -624,7 +653,7 @@ function PlacementManager:Init()
PlacementManager:Raycast() PlacementManager:Raycast()
end) end)
if not a then if not a then
PlacementManager.SelectionBox.Adornee = nil clearSelection("raycast error")
script.RaycastResult.Value = nil script.RaycastResult.Value = nil
end end
end) end)