Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

How can I 'round' a Vector3 to the nearest stud?

Asked by 10 years ago

I'm trying to create an equivalent to the default ROBLOX 'Drag' HopperBin, but I want it to only work within a 20 stud radius. I've got that bit working, but actually moving the part I'm dragging is not how I'd like it. I want it 'rounded' to the nearest stud. The problem with that is that some studs are .5 and not just a solid 1. Here's my current code:

local player = script.Parent.Parent.Parent.Parent local mouse = player:GetMouse() local draggable = false local trg = nil

mouse.Move:connect(function()
    if trg ~= nil then
        if mouse.Target ~= trg then
            if (mouse.Hit.p - trg.Position).magnitude <= 50 then
                trg.Position = Vector3.new(math.ceil(mouse.Hit.p.X),math.ceil(mouse.Hit.p.Y),math.ceil(mouse.Hit.p.Z))
            end
        end
    end
end)

mouse.Button1Down:connect(function()
    if mouse.Target ~= nil then
        if mouse.Target:findFirstChild("ForageItem") ~= nil then
            if mouse.Target:findFirstChild("ForageItem").RemoveOnForage.Value == true then
                if mouse.Target:findFirstChild("NoDrag") == nil then
                    if player.Character ~= nil then
                        if (mouse.Target.Position - player.Character:GetModelCFrame().p).magnitude <= 50 then
                            trg = mouse.Target
                        end
                    end
                end
            end
        end
        if draggable == true and trg ~= nil then
            trg.Rotation = Vector3.new(0,0,0)
            local sel = Instance.new("SelectionBox",player.PlayerGui)
            sel.Adornee = trg
            sel.Name = "DragBox"
            sel.Color = BrickColor.new("Bright blue")
            trg.Anchored = true
        else
            if player.PlayerGui:findFirstChild("DragBox") ~= nil then
                player.PlayerGui:findFirstChild("DragBox"):Destroy()
            end
        end
    end
end)

mouse.KeyDown:connect(function(key)
    if key == "r" then
        trg.CFrame = trg.CFrame * CFrame.Angles(0,math.pi/2,0)
    elseif key == "t" then
        trg.CFrame = trg.CFrame * CFrame.Angles(0,0,math.pi/2)
        if trg.Rotation.Z == 90 then
            trg.Position = trg.Position + Vector3.new(0,2,0)
        end
    end
end)

mouse.Button1Up:connect(function()
    if player.PlayerGui:findFirstChild("DragBox") ~= nil then
        player.PlayerGui:findFirstChild("DragBox"):Destroy()
    end
    if trg ~= nil then
        trg.Anchored = false
        for i=1,10 do
            trg = nil
        end
    end
end)

coroutine.resume(coroutine.create(function()
    while true do
        wait(0.01)
        if player.PlayerGui.TopBar.Selected.Value == "Drag" then
            script.Parent.Visible = true
            script.Parent.Position = UDim2.new(0,mouse.X + 10,0,mouse.Y + 40)
            local passed = false
            if mouse.Target ~= nil then
                if mouse.Target:findFirstChild("ForageItem") ~= nil then
                    if mouse.Target:findFirstChild("ForageItem").RemoveOnForage.Value == true then
                        if mouse.Target:findFirstChild("NoDrag") == nil then
                            if player.Character ~= nil then
                                if (mouse.Target.Position - player.Character:GetModelCFrame().p).magnitude <= 50 then
                                    passed = true
                                end
                            end
                        end
                    end
                end
            end
            if passed == false then
                script.Parent.Text = "Not Draggable"
                script.Parent.TextColor3 = Color3.new(255/255,0,0)
            else
                script.Parent.Text = "Draggable"
                script.Parent.TextColor3 = Color3.new(0,255/255,0)
            end
            draggable = passed
        else
            script.Parent.Visible = false
        end
    end
end))

1 answer

Log in to vote
4
Answered by 10 years ago

I think this should work. Just tested with single number, so it should work with vectors just fine.

function roundVector(vector, unit)
    return vector - Vector3.new(vector.X%unit, vector.Y%unit, vector.Z%unit)
end
0
What is the second argument to the function? Vector3.unit? YaYaBinks3 110 — 10y
0
No, it's not an argument of Vector3 API. The unit is argument of my custom function, and I use it to round to closest value using modulus operator. What I am doing, is: vector.X - (vector.X % 20) In that example it would snap X to 20 stud grid. ZarsBranchkin 885 — 10y
0
Thank you! I worked it out! :) YaYaBinks3 110 — 10y
Ad

Answer this question