I’m currently working on a game inspired by islands and bedwars, and in the bedwars placement system you can place your mouse on the edge of a block without touching a face of the block and it’ll place a preview there. Example:
my code:
local function renderPreview(blockTemplate)
local mouseLocation = UserInputService:GetMouseLocation()
local unitRay = camera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)
local cast = workspace:Raycast(unitRay.Origin, unitRay.Direction * 1000, castParams)
if cast and preview and placementValidator.IsWithinMaxDistance(player, cast.Position) then
for _, v in pairs(preview:GetChildren()) do
if v:IsA("Texture") then
v.Transparency = 0.7
end
end
local snappedPosition = placementValidator.SnapToGrid(cast.Position, preview.PrimaryPart.Size)
local normalCF = CFrame.lookAlong(cast.Position, cast.Normal)
local relativeSnapped = normalCF:PointToObjectSpace(snappedPosition)
local xVector = normalCF:VectorToWorldSpace(Vector3.xAxis * -math.sign(relativeSnapped.X))
local yVector = normalCF:VectorToWorldSpace(Vector3.yAxis * -math.sign(relativeSnapped.Y))
local cf = CFrame.fromMatrix(snappedPosition, xVector, yVector, cast.Normal)
preview.PrimaryPart.Position = cf:PointToWorldSpace(blockTemplate.PrimaryPart.Size / 2)
else
if preview then
for _, v in pairs(preview:GetChildren()) do
if v:IsA("Texture") then
v.Transparency = 1
end
end
end
end
end