I’m not sure at all how to do the snapping and no tutorials have helped so i would appreciate an example or explanation
this is my current code and i’ve only gotten it to place and move i attempted rotation but got lost
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")
local CollectionService = game:GetService("CollectionService")
local Preview = nil
local CurrentBuild = ReplicatedStorage["Build Items"]["Wooden Wall"]
local function preparePreview(preview: Model)
for _, part in preview:GetChildren() do
if part:IsA("BasePart") then
part.CanCollide = false
part.Transparency = 0.5
end
end
end
Preview = CurrentBuild:Clone()
Preview.Parent = workspace
preparePreview(Preview)
--[[Player Variables]]
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local cc = workspace.CurrentCamera
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {player.Character, Preview}
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
local function GetMouseLocation()
local MouseLocation = UserInputService:GetMouseLocation()
local UnitRay = cc:ViewportPointToRay(MouseLocation.X, MouseLocation.Y)
local cast = workspace:Raycast(UnitRay.Origin, UnitRay.Direction * 1000, raycastParams)
if cast and CurrentBuild ~= nil then
local hitPosition = cast.Position
local hitNormal = cast.Normal
local lookAtPosition = hitPosition + hitNormal
local orientation = CFrame.lookAt(hitPosition, lookAtPosition, hitNormal)
Preview:PivotTo(orientation)
CurrentBuild:PivotTo(Preview:GetPivot())
else
return
end
end
local RotationAmount = 0
UserInputService.InputBegan:Connect(function(input, gpe)
if gpe then return end
if input.UserInputType == Enum.UserInputType.MouseButton1 then
Preview = nil
ReplicatedStorage.Communication.Placement:FireServer(CurrentBuild)
end
end)
local Running
Running = RunService.RenderStepped:Connect(function()
if Preview == nil then
Running:Disconnect()
else
GetMouseLocation()
end
end)
to alter the size of the snapping grid, simply change the % 1 to % yourDesiredGridSize
The percent sign is called the modulo operator. It takes a number like in your case cast.Position.X divides it by your grid size (1) and returns the remainder.
thanks still looks complicated to me but i’ll try to understand it
also i assumed this was using raycastparams i only want to include parts with a tag “Grid” but dont know if that possible or not to use tags or if i would have to give a path for every grid instead
If I understand correctly, you only want parts with a “Grid” tag to be snapped to the grid.
You can achieve this simply by adding a check for the tag:
local hitPosition = cast.Position
if Preview:HasTag("Grid") then
hitPosition -= Vector3.new(cast.Position.X % 1, cast.Position.Y % 1, cast.Position.Z % 1)
end
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")
local CollectionService = game:GetService("CollectionService")
local Preview = nil
local CurrentBuild = ReplicatedStorage["Build Items"]["Wooden Wall"]
local ReplicatedModel = CurrentBuild:Clone()
local function preparePreview(preview: Model)
for _, part in preview:GetChildren() do
if part:IsA("BasePart") then
part.CanCollide = false
part.Transparency = 0.5
end
end
end
Preview = CurrentBuild:Clone()
Preview.Parent = workspace
preparePreview(Preview)
--[[Player Variables]]
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local cc = workspace.CurrentCamera
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {player.Character, Preview}
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
local function GetMouseLocation()
local MouseLocation = UserInputService:GetMouseLocation()
local UnitRay = cc:ViewportPointToRay(MouseLocation.X, MouseLocation.Y)
local cast = workspace:Raycast(UnitRay.Origin, UnitRay.Direction * 1000, raycastParams)
if cast and CurrentBuild ~= nil then
local hitPosition = cast.Position - Vector3.new(cast.Position.X % 2, cast.Position.Y % 2, cast.Position.Z % 2)
local hitNormal = cast.Normal
local lookAtPosition = hitPosition + hitNormal
local orientation = CFrame.lookAt(hitPosition, lookAtPosition, hitNormal)
Preview:PivotTo(orientation)
else
return
end
end
local RotationAmount = 0
UserInputService.InputBegan:Connect(function(input, gpe)
if gpe then return end
if input.UserInputType == Enum.UserInputType.MouseButton1 then
ReplicatedModel:PivotTo(Preview:GetPivot())
print(ReplicatedModel)
ReplicatedModel.Parent = workspace
ReplicatedStorage.Communication.Placement:FireServer(ReplicatedModel)
Preview = nil
end
end)
local Running
Running = RunService.RenderStepped:Connect(function()
if Preview == nil then
Running:Disconnect()
else
GetMouseLocation()
end
end)