I’m making a module script for a game that requires some sort of building system. Roblox Studio’s method of placing parts is perfect for what I’m doing. How can I make something similar?
-
What happened to DraggerService? I searched through the docs and api and found DraggerService, but cannot access it in game. Being able to use DraggerService (for increments and other things) with Draggers will solve my issue.
-
How do I do the same thing Roblox is doing? I’ve been through the forum and found some posts about it, but none of them (except this one, but I can’t load the .rbxm file as apparently its corrupted.) presents a solid solution I can use.
Here’s a snippet of my current code/module, made with some help from existing forum posts:
local function ConvertWithIncrement(v3: Vector3, increment: number, size, unitNormal)
local x, y, z = v3.X, v3.Y, v3.Z
if increment > 0 then
x = math.sign(x)*((math.abs(x) - math.abs(x) % increment) + (size.X % increment))
y = math.sign(y)*((math.abs(y) - math.abs(y) % increment) + (size.Y % increment))
z = math.sign(z)*((math.abs(z) - math.abs(z) % increment) + (size.Z % increment))
end
return Vector3.new(x, y, z)
end
function Dragger:MouseMove(unitRay: Ray, params: RaycastParams)
local rayStart = unitRay.Origin
local rayDirection = unitRay.Direction
if self.Target then
if not params then
params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Exclude
params.IgnoreWater = true
params.FilterDescendantsInstances = {self.Target}
end
local hit = game.Workspace:Raycast(rayStart, rayDirection * self.RaycastRange, params)
if hit and hit.Instance then
local pos = hit.Position
-- offset by the face of the target
local size
if self.Target.ClassName == "Model" then
local normClone = self.Target:Clone()
normClone.Parent = game.ReplicatedStorage
normClone:PivotTo(CFrame.new(0,0,0))
_, size = normClone:GetBoundingBox()
else
size = self.Target.Size
end
pos += hit.Normal * (size/2)
-- grid locking
pos = ConvertWithIncrement(pos, self.Increment, size, hit.Normal)
local c = CFrame.new(pos, pos + hit.Normal)
--c *= CFrame.Angles(math.rad(hit.Instance.Orientation.X), math.rad(hit.Instance.Orientation.Y), math.rad(hit.Instance.Orientation.Z))
if self.Target.ClassName == "Model" then
self.Target:PivotTo(c)
else
self.Target.CFrame = c
end
end
else
warn("No target was found.")
end
end
The script works the best when the snap increment is 0. Otherwise, the position is snapped “globally”, and so the part can clip into the part it is being placed on.
Another issue is that unlike in Roblox’s dragger system, the part’s orientation doesn’t match up with the part its being placed on.
Current:
Snap and orientation are off
Expected:
Snap and orientation matches that of the canvas part
EDIT:
I looked through again and found this. How do you use/find the “new framework”?