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:

I forgot to mention, there is the part where I use the Event:

local function new(Type: string,Style,FramParams)
	return require(game.ReplicatedStorage.HandlesController).new(Type,Style,Origin,FramParams,Mouse)
end

local Handles = {
Studs = new("Studs","Move",script.Parent.Buildings.Buildings.FramParams);
Angle = new("Angles",nil,script.Parent.Buildings.Buildings.FramParams);
}

Handles.Studs.MouseDrag:Connect(function(Face,Magnitude)
    if Handles.Studs.Type == "Studs" then
       Handles.Studs.Adornee.CFrame =  Handles.Studs.Adornee.CFrame*CFrame.new(Vector3.FromNormalId(Face)*((Magnitude < 0 and -((-Magnitude)^(1/3))) or (Magnitude^(1/3)))/math.pi)
    end
end)

And most of the problem is the Magnitude (On the topic, not on this post) because it is only beetwen 2-4 studs (Not below 0) Will make it work in just one direction

… why can’t you use handles in viewport frames?

Are you talking about tools?

Because roblox isn’t allowing it…? It is putting the Instances in workspace.

Look at this: Handles | Documentation - Roblox Creator Hub

OHHHH, thats what you mean! Sorry, can’t help you :v

1 Like