How to improve my interaction system

hey guys this is a bit messy how to improve it? without having to use many constant loops or coroutines?
Here is a module example;

return {
	{
		Key = Enum.KeyCode.E;
		Text = 'test';
	};
	{
		Key = Enum.KeyCode.F;
		Text = 'test2';
	}
};

image

local Interactions = workspace.Interactions:GetChildren();
local Player = game:GetService('Players').LocalPlayer;

local UI = Player.PlayerGui:WaitForChild("Client")

local Settings = {
	DefaultDistance = 6;
} ;

local module = {}
module.__index = module;

function module.new()
	local self = setmetatable({},module)
	self.AllInteractions = {};
	self.CloseInteractions = {};

	self.LastUpdate = os.clock() - 30;
	self.Connections = {};

	self.Enabled = true;

	self.CurrentInteraction = nil;

	self:Start()

	return self;
end;

function module:FindAllInteractions()
	print('Finding all interactions.')
	self.AllInteractions = {};

	--
	for i,v in pairs(Interactions) do
		if (v:FindFirstChildWhichIsA("ModuleScript")) then
			local Distance = Settings.DefaultDistance;
			local Module = require(v:FindFirstChildWhichIsA("ModuleScript"))

			local ndist = v.Name:split("|");
			if (ndist[2]) then
				Distance = tonumber(ndist)
			end;

			table.insert(self.AllInteractions,{
				Part = v;
				Distance = Distance;
				Module = Module;
			})
		end;
	end;
end;

function module:FindCloseInteractions()
	print('Finding close interactions.')
	self.CloseInteractions = {};
	if (os.clock() - self.LastUpdate) > 30 then
		for i,v in pairs(self.AllInteractions) do
			if (Player:DistanceFromCharacter(v.Part.Position) < 80) then
				table.insert(self.CloseInteractions,v)
			end;
		end;
	end;
end;

function module:Enable()
	self.Enabled = true;
end

function module:Disable()
	self.Enabled = false;
end;

function module:AddInteraction(interaction)
	local Visible = interaction.Module.Visible and interaction.Module.Visible() or true;
	if (interaction) then
		if (Visible) then
			if (not interaction.AddedTemplates) then
				interaction.AddedTemplates = true;
				for i,v in pairs(interaction.Module) do
					if (v.Template == nil) then
						local tmp = script.Frame:Clone();
						tmp.Parent = UI.Interactions;
						tmp.Frame.key.TextLabel.Text = tostring(v.Key):sub(14,14);
						tmp.Frame.text.TextLabel.Text = v.Text;
						game:GetService('TweenService'):Create(tmp.Frame,TweenInfo.new(.25),{Position = UDim2.new(0,0,0,0)}):Play()
						v.Template = tmp;
						self.CurrentInteraction = interaction.Part;
						coroutine.wrap(function()
							while (tmp) do
								wait(1);
								Visible = v.Visible and v.Visible() or true;
								if (not Visible or Player:DistanceFromCharacter(interaction.Part.Position) > interaction.Distance) then
									if (v.Template) then
										local tween = game:GetService('TweenService'):Create(v.Template.Frame,TweenInfo.new(.25),{Position = UDim2.new(0,0,1,0)})
										tween:Play()
										tween.Completed:Wait()
										v.Template:Destroy();
										v.Template = nil;
										if (interaction.AddedTemplates) then
											interaction.AddedTemplates = false;
										end;
									end;
									break
								end;
							end;
						end)()
					end;
				end;
			end
		end
	end;
end;

function module:Start()
	self:FindAllInteractions();
	self:FindCloseInteractions()

	self.Connections[#self.Connections + 1] = game:GetService('RunService').RenderStepped:Connect(function()
		if not (self.Enabled) then
			for i,v in pairs(self.Connections) do
				v:Disconnect();
			end;
			for i,v in pairs(self.CloseInteractions) do
				if (v.Module.Template) then
					v.Module.Template:Destroy()
					v.Module.Template = nil;
				end;
			end;
		end;
		if (os.clock() - self.LastUpdate) > 30 then
			self:FindCloseInteractions();
			self.LastUpdate = os.clock();
		end;

		if (self.CurrentInteraction) then
			local WSP,cansee = workspace.CurrentCamera:WorldToScreenPoint(self.CurrentInteraction.Position)
			if (cansee) then
				UI.Interactions.Position = UDim2.new(0,WSP.X,0,WSP.Y)
				UI.Interactions.Visible = true;
			else
				UI.Interactions.Visible = false;
			end;
		else
			UI.Interactions.Visible = false;
		end;

		for i,v in pairs(self.CloseInteractions) do
			if (Player:DistanceFromCharacter(v.Part.Position) < v.Distance and v.Module.Template == nil) then
				self:AddInteraction(v);
			end;
		end;
	end)
end;

return module