I’m trying to recreate Work at a Pizza Place’s part dragging system but I am having troubles with snapping the actual part to the stud.
I tried using multiple methods like UserInputService:GetMouseLocation()
and Player:GetMouse()
, I tried using :ViewportPointToRay()
instead of :ScreenPointToRay()
, yet I couldn’t get the part to snap onto the stud and stay there properly.
My implemention also has issues because snapping becomes exteremely inconsistent when part has a different size set.
I researched multiple DevForum posts but I couldn’t find a good solution, I’d realy appreciate it if you could help me, since I’m terrible at Vectors and CFrame.
Here’s my code:
-- services
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
-- player & character
local Player = game.Players.LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
-- camera
local Camera = workspace.CurrentCamera
-- mouse
local Mouse = Player:GetMouse()
-- how much studs to snap to
local StudsSnap = 1
-- drag distance
local DragDistance = 100
-- folder containing interactable objects
local ObjectsFolder = workspace.Objects
-- parameters
local Parameters = RaycastParams.new()
-- ignore our character and interactable objects
Parameters.FilterType = Enum.RaycastFilterType.Exclude
Parameters.FilterDescendantsInstances = {ObjectsFolder, Character}
-- update function
RunService.RenderStepped:Connect(function()
local TargetObject = ObjectsFolder.Part
local MousePosition = UserInputService:GetMouseLocation()
-- was told that ViewportPointToRay gives the most accurate mouse position minus the inset
local UnitRay = Camera:ViewportPointToRay(MousePosition.X, MousePosition.Y, 1)
-- raycast happens here
local Raycast = workspace:Raycast(UnitRay.Origin, UnitRay.Direction * DragDistance, Parameters)
if Raycast then
local PositionRound = Vector3.new(math.round (Raycast.Position.X / StudsSnap) * StudsSnap + 0.5, math.round ( Raycast.Position.Y / StudsSnap) * StudsSnap - 0.5 , math.round (Raycast.Position.Z / StudsSnap) * StudsSnap + 0.5 )
TargetObject.Position = PositionRound + Raycast.Normal * (TargetObject.Size)
end
end)
I can provide the .rbxl
as well to make this easier to solve.
Baseplate.rbxl (54.1 KB)