The NPCs in my game have a surrounding circle, called ‘Proximity Aura’. When you enter it, the designed PopUp (UI) of that NPC should appear in your screen. My code works, but it’s too slow. Ideas as to why? Help is appreciated ;D
Proximity local script:
local Fetch: { [string]: () -> () } = _G.Fetch;
local S, GUI, Notify, Run = Fetch.Script({ 'Services', 'GUIManager', 'Notifier', 'Runner' });
local WS: Workspace, P: Players = S.WS, S.P;
local Player = P.LocalPlayer;
local Character = Player.Character or Player.CharacterAdded:Wait();
local Interface = Player.PlayerGui:WaitForChild('Interface', 10.0);
local Information = { };
local function CheckDistance(ID: number): ()
local Distance = (Character.HumanoidRootPart.Position - Information[ID][1]).Magnitude;
local P = Information[ID][2];
local PopUp = Interface.PopUps:FindFirstChild(P);
if PopUp then
if Distance <= 11.0 then
print(Distance)
GUI.Open(P, false);
else
if PopUp.ManuallyOpened.Value == false then
GUI.Close(P);
end
end
else
if Distance <= 11.0 then
Notify(Player, 'Coming Soon', 'Come back again later in order to uncover the secrets behind this feature!');
end
end
end
for i, Object in ipairs(WS:GetDescendants()) do
if Object.Name == 'Proximity Aura' then
Information[i] = { Object.Details.Position, Object.Details.Parent.Parent.Name };
Run(CheckDistance, 'CheckDistance', 1.0, 'Heartbeat', { i });
end
end
GUIManager module:
local GUI: { [string]: () -> () } = { };
local ed = Enum.EasingDirection;
local es = Enum.EasingStyle;
local Fetch: { [string]: () -> () } = _G.Fetch;
local MouseInteraction = Fetch.Event({ 'MouseInteraction' });
local S, Debounce, Database, Check = Fetch.Script({ 'Services', 'Debouncer', 'DatabaseManager', 'Checker' });
local RSS: ReplicatedStorage, TS: TweenService, P: Players = S.RSS, S.TS, S.P;
local TI1 = TweenInfo.new(0.5, es.Circular, ed.Out);
local TI2 = TweenInfo.new(0.5, es.Circular, ed.Out);
local TI3 = TweenInfo.new(0.50, es.Circular, ed.Out);
-- local TI4 = TweenInfo.new(5.0, es.Quad, ed.Out);
-- local TI5 = TweenInfo.new(4.0, es.Quad, ed.Out);
local TI4 = TweenInfo.new(0.8, es.Quad, ed.Out);
local TI5 = TweenInfo.new(1.0, es.Quint, ed.InOut);
local TI6 = TweenInfo.new(0.3, es.Quint, ed.InOut);
local TweenSettings1 = { Position = UDim2.new(-0.150, 0, -0.3640, 0) };
local TweenSettings2 = { Position = UDim2.new(0.5920, 0, -0.3640, 0) };
local TweenSettings3 = { Size = UDim2.new(0.30, 0, 0.05, 0) }
local TweenSettings4 = { Position = UDim2.new(0.50, 0, 0.05, 0) }
local TweenSettings5 = { Size = UDim2.new(0.6, 0, 0.6, 0) }
local TweenSettings6 = { Position = UDim2.new(0.5, 0, 0.5, 0) };
local TweenSettings7 = { Position = UDim2.new(1.31, 0, 0.50, 0) };
local TweenSettings8 = { Position = UDim2.new(1.16, 0, 0.05, 0) };
local OriginalSizeY;
local TransparencyTable = { };
local FadeTweens = { };
local PropertyMap = {
[' O'] = 'Transparency',
[' I'] = 'ImageTransparency',
[' T'] = 'TextTransparency',
[' TS'] = 'TextStrokeTransparency',
[' BG'] = 'BackgroundTransparency',
[' SB'] = 'ScrollBarImageTransparency',
};
local Sounds = RSS:WaitForChild('Library', 10.0).Sounds;
local Player = P.LocalPlayer;
local function Play(Player: Player, Sound: string): ()
local SoundObject = Sounds:WaitForChild(Sound, 10.0);
local SFX = Fetch.Setting(Player, { 'SFX' });
if SFX then
SoundObject:Play();
end
end
local function AddTween(Object: Instance, Key: string, IsMinimized: boolean, Type: string): ()
local Settings = { };
local DefaultValue = 1.0;
if IsMinimized then
DefaultValue = TransparencyTable[Key] or 1.0;
end
local Property = PropertyMap[Type];
if Property then
Settings[Property] = DefaultValue;
pcall(function(): boolean
table.insert(FadeTweens, TS:Create(Object, TI4, Settings));
end);
end
end
local function TweenSlider(Button: Instance): ()
if Debounce('SettingsState Change', 0.5) then return end
local GFX = GUI.GetInfo();
local Circle = Button.Parent.Circle;
local SettingName = Circle.Parent.Parent.Name;
local Setting = Fetch.Setting(Player, { SettingName });
local PlayerSettings = RSS:WaitForChild("Players", 10.0):WaitForChild(Player.UserId, 10.0);
local SettingObject = PlayerSettings.Settings.Audiovisual:WaitForChild(SettingName, 10.0);
local Enabled = SettingObject.Value;
if GFX then
local Tween1 = TS:Create(Circle, TI1, TweenSettings1);
local Tween2 = TS:Create(Circle, TI2, TweenSettings2);
local function AnimateColor(ColorN: Color3): ()
local TweenSettings3 = {
BackgroundColor3 = ColorN
};
local Tween3 = TS:Create(Circle, TI3, TweenSettings3);
Tween3:Play();
end
if Enabled then
AnimateColor(Color3.fromRGB(188.0, 137.0, 225.0));
Tween1:Play()
else
AnimateColor(Color3.fromRGB(119.0, 225.0, 207.0));
Tween2:Play()
end
else
if Enabled then
Circle.Position = UDim2.new(-0.150, 0.0, -0.3640, 0.0);
Circle.BackgroundColor3 = Color3.fromRGB(188.0, 137.0, 225.0);
else
Circle.Position = UDim2.new(0.5920, 0.0, -0.3640, 0.0);
Circle.BackgroundColor3 = Color3.fromRGB(119.0, 225.0, 207.0);
end
end
SettingObject.Value = not SettingObject.Value;
end
local function Shadering(Shader: Frame, GFX: boolean, Transparency: number, Visibility: boolean): ()
task.spawn(function(): ()
Shader.Visible = true;
if GFX then
Shader.BackgroundTransparency = 1.0;
local Tween = TS:Create(Shader, TI6, { Transparency = Transparency });
Tween:Play();
task.wait(TI6.Time);
else
Shader.BackgroundTransparency = Transparency;
end
Shader.Visible = Visibility;
end);
end
function GUI.EnableShader(Shader: Frame, GFX: boolean): ()
Shadering(Shader, GFX, 0.30, true);
end
function GUI.DisableShader(Shader: Frame, GFX: boolean): ()
Shadering(Shader, GFX, 1.0, false);
end
function GUI.GetInfo(PopUpName: string?): any
local GFX = Fetch.Setting(Player, { 'GFX' });
if not PopUpName then return GFX end
local PopUp, Shader = Fetch.UI(Player, { PopUpName, 'Shader' }, 'Unpacked');
return GFX, PopUp, Shader;
end
function GUI.Resize(Object: Instance, Amplification: number, Time: number?): ()
Time = Time or 0.2;
local SizeX = Object.Parent.Size.X.Scale;
local SizeY = OriginalSizeY or Object.Parent.Size.Y.Scale;
OriginalSizeY = SizeY;
Object.Parent:TweenSize(UDim2.new(SizeX * Amplification, 0, SizeY * Amplification, 0), ed.InOut, es.Quint, Time);
end
local function ChangeState(PopUpName: string, SizeSettings: { }, PositionSettings: { }, SizeX: number, SizeY: number, Text: string): ()
if Debounce('PopUpState Change', 2.0) then return end
local GFX, Frame, Shader = GUI.GetInfo(PopUpName);
local CloseFrame, MinimizeFrame, MinimizeButton, Minimized, Title = Frame.Close, Frame.Minimize, Frame.Minimize.MinimizeButton, Frame.Minimize.Minimized, Frame.Title;
local Separator, UICorner, ManuallyOpened = Frame.Separator, Frame.UICorner, Frame.ManuallyOpened;
local IsMinimized = Minimized.Value;
local SizeTween = TS:Create(Frame, TI4, SizeSettings);
local PositionTween = TS:Create(Frame, TI4, PositionSettings);
local SeparatorTween = TS:Create(Separator, TI4, { Size = UDim2.new(SizeX, 0, 0, 0) });
local AdditionalTweens = {
TS:Create(CloseFrame, TI4, { Size = UDim2.new(0.1, 0, SizeY, 0) }),
TS:Create(MinimizeFrame, TI4, { Size = UDim2.new(0.1, 0, SizeY, 0) }),
TS:Create(Title, TI4, { Size = UDim2.new(0.76, 0, SizeY, 0) }),
TS:Create(UICorner, TI4, { CornerRadius = UDim.new(SizeY, 0) }),
};
OriginalSizeY = SizeY;
for _, Object in ipairs (Frame:GetDescendants()) do
local Parent = Object.Parent or '';
if (Parent ~= Frame and Parent ~= CloseFrame and Parent ~= MinimizeFrame and Parent ~= Separator) then
for Suffix, Property in pairs (PropertyMap) do
local Attribute = Object:GetAttribute('ID');
local HasProperty, Value = table.unpack(Check.ForProperty({ Object }, Property));
if HasProperty then
local Key = Object.Name .. Attribute .. Suffix;
AddTween(Object, Key, IsMinimized, Suffix);
TransparencyTable[Key] = Value;
end
end
end
end
if IsMinimized and IsMinimized ~= 'NaN' then
Database.SetFolderData(Player, { ['Opened'] = 'NaN' });
Database.SetFolderData(Player, { ['Minimized'] = (Frame.Name)} );
PositionTween:Play();
PositionTween.Completed:Wait();
SizeTween:Play();
task.wait(TI4.Time / 8);
Separator.Visible = true;
SeparatorTween:Play();
for i, Tween in ipairs(AdditionalTweens) do
Tween:Play();
if #AdditionalTweens == i then
Tween.Completed:Wait();
end
end
MinimizeButton.Text = Text;
for i, Tween in ipairs(FadeTweens) do
Tween:Play();
end
else
Database.SetFolderData(Player, { ['Opened'] = (Frame.Name) } );
Database.SetFolderData(Player, { ['Minimized'] = 'NaN' });
SeparatorTween:Play();
for i, Tween in ipairs(FadeTweens) do
Tween:Play();
if #FadeTweens == i then
Tween.Completed:Wait();
end
end
SizeTween:Play();
for i, Tween in ipairs(AdditionalTweens) do
Tween:Play();
if #AdditionalTweens == i then
Tween.Completed:Wait();
end
end
MinimizeButton.Text = Text;
SizeTween.Completed:Wait();
PositionTween:Play();
end
table.clear(FadeTweens);
table.clear(AdditionalTweens);
task.wait(TI4.Time / 4);
if IsMinimized then
GUI.EnableShader(Shader, GFX);
else
Separator.Visible = false;
GUI.DisableShader(Shader, GFX);
end
Minimized.Value = not Minimized.Value;
end
function GUI.Minimize(PopUpName: string)
ChangeState(PopUpName, TweenSettings3, TweenSettings4, 0.0, 1.0, '+');
end
function GUI.Maximize(PopUpName: string)
ChangeState(PopUpName, TweenSettings5, TweenSettings6, 0.95, 0.1, '-');
end
function GUI.Close(PopUpName: string): ()
if Debounce('PopUp', TI6.Time * 2.0) then return end
local GFX, Frame, Shader = GUI.GetInfo(PopUpName);
local ManuallyOpened = Frame.ManuallyOpened;
local Minimized = Frame.Minimize.Minimized;
local IsMinimized = Minimized.Value;
local Tween;
ManuallyOpened.Value = false;
if IsMinimized then
Database.SetFolderData(Player, { ['Minimized'] = 'NaN' });
Tween = TS:Create(Frame, TI6, TweenSettings8);
else
Database.SetFolderData(Player, { ['Opened'] = 'NaN' });
Tween = TS:Create(Frame, TI6, TweenSettings7);
end
Tween:Play();
GUI.DisableShader(Shader, GFX);
task.spawn(function(): ()
task.wait(1.5)
if IsMinimized then
GUI.Maximize(PopUpName);
end
Frame.Visible = false;
end);
end
function GUI.Open(PopUpName: string, Manual: boolean): ()
if Debounce('PopUp', TI6.Time * 2.0) then return end
local GFX, Frame, Shader = GUI.GetInfo(PopUpName);
local ManuallyOpened = Frame.ManuallyOpened;
local IsMinimized = Frame.Minimize.Minimized.Value;
local O, M = Fetch.Setting(Player, { 'Open', 'Minimized' });
if O ~= 'NaN' then
if M ~= 'NaN' then
GUI.Close((Frame.Parent:FindFirstChild(M).Name));
end
local FrameO = Frame.Parent:FindFirstChild(O);
if not FrameO.ManuallyOpened.Value then
GUI.Close(FrameO.Name);
else
GUI.Minimize(FrameO.Name);
end
Database.SetFolderData(Player, { ['Opened'] = (Frame.Name)} );
Database.SetFolderData(Player, { ['Minimized'] = O});
else
Database.SetFolderData(Player, { ['Opened'] = (Frame.Name) });
end
ManuallyOpened.Value = Manual;
Frame.Position = TweenSettings7.Position;
Frame.Visible = true;
GUI.EnableShader(Shader, GFX);
if IsMinimized then
GUI.Maximize(PopUpName);
task.wait(1.5);
end
local Tween = TS:Create(Frame, TI6, TweenSettings6);
Tween:Play();
end
function GUI.Animate(CallType: number, Button: Instance, PopUpName: string, EventName: string?, Arguments: { }?): ()
if CallType == 0.0 then
GUI.Resize(Button, 1.050);
elseif CallType == 2.0 then
GUI.Resize(Button, 0.950);
elseif CallType >= 1.0 then
GUI.Resize(Button, 1.0);
if CallType == 1.5 then
Play(Player, 'Click');
if EventName == 'Open' then
GUI.Open(PopUpName, true);
elseif EventName == 'Close' then
GUI.Close(PopUpName);
elseif EventName == 'Maximize' then
GUI.Maximize(PopUpName);
elseif EventName == 'Minimize' then
GUI.Minimize(PopUpName);
elseif EventName == 'Slide' then
TweenSlider(Button);
else
if Arguments then
local NewArguments = { EventName, table.unpack(Arguments) };
MouseInteraction:FireServer(NewArguments);
else
MouseInteraction:FireServer({ EventName });
end
end
end
end
end
return GUI;