Hello, I have been trying to code a placement system. It works, however I do not like how it works if that makes sense. My Preview placement part keeps going inside other blocks, and I just want to to be a nice smooth placement, similar to games like Minecraft or The Chosen One - Roblox
My Script:
local Tool = script.Parent
local TweenService = game:GetService("TweenService")
local Players = game:GetService("Players")
local Workspace = game:GetService("Workspace")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local SoundService = game:GetService("SoundService")
local mouse = Players.LocalPlayer:GetMouse()
local gridSize = 4
local partSize = Vector3.new(gridSize, gridSize, gridSize)
local previewUnion
local folder = Workspace:FindFirstChild("CurrentBlocks")
local toolEquipped = false
local remoteEvent = ReplicatedStorage:FindFirstChild("BlockPlacerRemote")
local soundId = 8265653733 -- ID of the sound to play
if not folder then
folder = Instance.new("Folder")
folder.Name = "CurrentBlocks"
folder.Parent = Workspace
end
-- Function to snap positions to the grid
local function snapToGrid(position)
return Vector3.new(
math.round(position.X / gridSize) * gridSize,
math.round(position.Y / gridSize) * gridSize,
math.round(position.Z / gridSize) * gridSize
)
end
-- Function to create and position the preview union
local function createPreviewUnion()
if previewUnion then
previewUnion:Destroy()
end
-- Clone the union from ReplicatedStorage
local previewTemplate = ReplicatedStorage:FindFirstChild("Preview")
if not previewTemplate then
warn("Preview union not found in ReplicatedStorage")
return
end
previewUnion = previewTemplate:Clone()
previewUnion.Size = partSize
previewUnion.CanCollide = false
previewUnion.Anchored = true
previewUnion.Parent = Workspace
-- Position the previewUnion so its center aligns with the grid
previewUnion.Position = snapToGrid(mouse.Hit.Position) + Vector3.new(0, partSize.Y / 2, 0) -- Centered above ground
end
-- Function to update the position of the preview union
local function updateUnionPosition()
local targetPosition = snapToGrid(mouse.Hit.Position) + Vector3.new(0, partSize.Y / 2, 0) -- Center of the previewUnion
local tweenInfo = TweenInfo.new(0, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut) -- 0 seconds duration
local goal = { Position = targetPosition }
local tween = TweenService:Create(previewUnion, tweenInfo, goal)
tween:Play()
-- Check if a block can be placed
local canPlace = true
for _, part in ipairs(Workspace:FindFirstChild("CurrentBlocks"):GetChildren()) do
if part:IsA("Part") then
if (part.Position - previewUnion.Position).magnitude < (partSize.X / 2 + partSize.X / 2) then
canPlace = false
break
end
end
end
-- Change color based on whether placement is possible
if canPlace then
previewUnion.BrickColor = BrickColor.new("Bright green")
else
previewUnion.BrickColor = BrickColor.new("Bright red")
end
end
-- Function to play the sound effect
local function playSound()
local sound = Instance.new("Sound")
sound.SoundId = "rbxassetid://" .. soundId
sound.Parent = SoundService
sound:Play()
-- Clean up the sound after it finishes playing
sound.Ended:Connect(function()
sound:Destroy()
end)
end
Tool.Equipped:Connect(function()
toolEquipped = true
createPreviewUnion()
while Tool.Parent do
updateUnionPosition()
wait(0.1) -- Adjust the wait time to control the update frequency
end
end)
Tool.Unequipped:Connect(function()
toolEquipped = false
if previewUnion then
previewUnion:Destroy()
end
end)
mouse.Button1Down:Connect(function()
if toolEquipped and previewUnion and remoteEvent then
-- Determine if placement is valid
local canPlace = previewUnion.BrickColor == BrickColor.new("Bright green")
local previewOrigin = previewUnion.Position - previewUnion.Size / 2 -- Origin of the previewUnion
local position = previewOrigin + Vector3.new(partSize.X / 2, partSize.Y / 2, partSize.Z / 2) -- Center the block
-- Apply a random easing style for tweening
local easingStyles = Enum.EasingStyle:GetEnumItems()
local randomEasingStyle = easingStyles[math.random(1, #easingStyles)]
local tweenInfo = TweenInfo.new(0, randomEasingStyle, Enum.EasingDirection.InOut)
local goal = { Position = position }
local tween = TweenService:Create(previewUnion, tweenInfo, goal)
tween:Play()
-- Send a request to the server to place the block
remoteEvent:FireServer(position, canPlace)
-- Play the sound effect
playSound()
end
end)