Custom handles aren't working as supposed

Hello, As everyone knows you can’t use Handles in viewportframes, so I created an script which will copy an part from ReplicatedStorage and gives it the right Size. All good, but as I had no idea to see what is the Magnitude from the last position of the mouse and the new one, and I just used the Position’s (Ray’s end position). It works pretty well, but if the .Adornee Is an big part, it will just be beetwen 2-4 studs. I think the problem is in this part:

        local IsFound,Data,Pos = data.IsMouseInRay()
		if IsFound and UIS:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) then
           if LastPosition > (Data.Object.Position-Pos).Magnitude and LastType == Data.Id or LastPosition < (Data.Object.Position-Pos).Magnitude and LastType == Data.Id then
               LastPosition = (Data.Object.Position-Pos).Magnitude
               MouseDrag:Fire(Data.Id,LastPosition)
            elseif LastType ~= Data.Id then
               LastType = Data.Id
               LastPosition = (Data.Object.Position-Pos).Magnitude 
            elseif (Data.Object.Position-Pos).Magnitude == LastPosition then
               LastPosition = (Data.Object.Position-Pos).Magnitude 
           end
		end

The entire script if you want to see it:

local HandlesModule = {}
local Handles = {}
Handles.__index = Handles
local UIS = game:GetService("UserInputService")
local Model = Instance.new("Model")

local EnumFaces = {
  ["Top"] = Vector3.new(0, 1, 0);
  ["Bottom"]= Vector3.new(0, -1, 0);
  ["Back"] = Vector3.new(0, 0, 1);
  ["Front"] = Vector3.new(0, 0, -1);
  ["Right"] = Vector3.new(1, 0, 0);
  ["Left"]  = Vector3.new(-1, 0, 0)
}

local Types = {[1] = "Z",[2] = "Y",[3] = "X"}

local Modes = {
 ["Resize"] = "StudsResize";
 ["Movement"] = "StudsMove";
}

local function ToModel(Inst)
	local ToModel = Instance.new("Model")
	Inst:Clone().Parent = ToModel
	return ToModel
end

local function GetSize(Ins)
	local position,Size = ToModel(Ins):GetBoundingBox()
	position = Vector3.new(position.X,position.Y,position.Z)
	return Size,position
end

local function DoSize(Object,Position,Size,EnumId)
	local Vector
	local  Num
	for i = 1,3 do
		if Vector3.FromNormalId(EnumId)[Types[i]] == 1 or Vector3.FromNormalId(EnumId)[Types[i]] == -1 then
			local Type = Types[i]
			local Size = Size / 2
			Vector = Vector3.new(Size,Size,Size)
			break
		end
	end
	return Vector
end

local function CreateBuild(Type: string,Origin: Instance,parent: Instance)
	local Ret = {}
	if parent then
	
	if Type == "Movement" then
		for EnumId,Vector in pairs(EnumFaces) do
			local Object = game.ReplicatedStorage.HandlesBuild[Modes[Type]]:Clone()
			local Size,position = GetSize(parent)
			Object.Position = position + (Vector * (Size/1.25))
            Object.Parent = Origin
            Object.Name = EnumId
			table.insert(Ret,{Object = Object,Id = EnumId})
		end
	elseif Type == "Resize" then
		for EnumId,Vector in pairs(EnumFaces) do
			local Object = game.ReplicatedStorage.HandlesBuild[Modes[Type]]:Clone()
			local Size,position = GetSize(parent)
			Object.Position = position + (Vector * (Size/1.25))
            Object.Parent = Origin
            Object.Name = EnumId
			table.insert(Ret,{Object = Object,Id = EnumId})
		end
	else
		
	end
	end
	return Ret
end


function HandlesModule.new(Type: string,Style: any,Origin: Instance,parent: Instance,Mouse)
	local data = setmetatable({},Handles)
	data.Type = Type
	data.Color3 = Color3.fromRGB(0,0,0)
	data.Visible = false
	data.Adornee = nil
	data.Build = CreateBuild(Style,Origin,parent)
	data.Style = Style
	local MouseDrag = Instance.new("BindableEvent")
	local MouseButton1Down = Instance.new("BindableEvent")
	data.MouseDrag = MouseDrag.Event
	data.IsMouseInRay = function()
		local Part,Pos = Mouse.MouseTarget(Model)
		local IsFound = false
        local DataObject 
		if Part then
			for Object,Id in pairs(data.Build) do
                if Part.Name == Id.Id then
                    if Part.Color == Color3.fromRGB(4, 171, 208) or Part.Color == Color3.fromRGB(185, 99, 53) then
                        DataObject = Id
                        IsFound = true;
                        break
                    end
                end
            end
		end
		return IsFound,DataObject,Pos
	end
    local LastPosition,LastType = 0,nil
	game.Players.LocalPlayer:GetMouse().Move:Connect(function()
        local IsFound,Data,Pos = data.IsMouseInRay()
		if IsFound and UIS:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) then
           if LastPosition > (Data.Object.Position-Pos).Magnitude and LastType == Data.Id or LastPosition < (Data.Object.Position-Pos).Magnitude and LastType == Data.Id then
               LastPosition = (Data.Object.Position-Pos).Magnitude
               MouseDrag:Fire(Data.Id,LastPosition)
            elseif LastType ~= Data.Id then
               LastType = Data.Id
               LastPosition = (Data.Object.Position-Pos).Magnitude 
            elseif (Data.Object.Position-Pos).Magnitude == LastPosition then
               LastPosition = (Data.Object.Position-Pos).Magnitude 
           end
		end
	end)
    data.ChangeAdornee = function(Value)
        if data.Build then
            for i,v in pairs(data.Build) do
                for k,Part in pairs(v) do
                    if typeof(Part) == "Instance" and Part:IsA("BasePart") then
                        Part:Destroy()
                    end
                end
            end
        end
        data.Adornee = Value
        if Value then
        data.Build = CreateBuild(data.Type,Origin,Value)
        end
    end
    data.ChangeStyle = function(Value)
        data.Type = Value
        if data.Build then
            for i,v in pairs(data.Build) do
                for k,Part in pairs(v) do
                    if typeof(Part) == "Instance" and Part:IsA("BasePart") then
                        Part:Destroy()
                    end
                end
            end
        end
        if Value then
        data.Build = CreateBuild(data.Type,Origin,data.Adornee)
        end
    end
	return data
end

return HandlesModule

It is an Module script. Sorry for bad scripting but I’m pretty new to scripting :confused:

The code is a little confusing - not your fault necessarily, just a lot of things happening for my brain to take in after school right now haha.

But here’s a way to check the magnitude of the last position of the mouse to the new position that I believe should work:

local player = -- Whichever player you specify
local mouse = Player:GetMouse()

local lastPos = nil
local currentPos = nil

local switch = false

while true do
    if switch == false then
        lastPos = Vector2.new(mouse.X, mouse.Y)
        switch = true
    else
        currentPos = Vector2.new(mouse.X, mouse.Y)
        switch = false
    end

    if lastPos and currentPos then
        local magnitude = (lastPos - currentPos).Magnitude
        -- Do whatever you want with it
    end
end

And if you want to find out how .Magnitude works mathematically, I made a post with a formula I made for it that works pretty much the same way, just not for Roblox Lua, but vanilla Lua. Here: How does magnitude and range work? - #6 by MJTFreeTime

Hope I helped ya out!

1 Like

Sorry, but I arleady done this using an different Math. I will give you the Solution anyways