This is the main ModuleScript on the client that deals with the buttons.
Buttons
local Buttons = {}
local Vars = require(game:GetService('ReplicatedStorage').CoreClientModules.ClientVars)
local Lib = require(game:GetService('ReplicatedStorage').CoreClientModules.ClientLib)
local MaxDistance = 6
local ButtonUI
local InteractionPart = nil
local ButtonsTweening = {}
local Connections = {}
local Tweens = {}
local TweenConnections = {}
local ButtonsTweening = {}
function GetInteractionParts()
local Buttons = {}
for i,v in pairs(Vars.Interactables:GetDescendants()) do
if v:IsA('BasePart') and v.Name == 'InteractionPart' then
table.insert(Buttons, v)
end
end
for i,v in pairs(workspace:GetChildren()) do
if v:FindFirstChild('Torso') and v.Torso:FindFirstChild('Settings') and Vars.Player.Character and v.Torso ~= Vars.Player.Character.Torso then
table.insert(Buttons, v.Torso)
end
end
return Buttons
end
function GetClosestInteractionPart()
local Buttons = GetInteractionParts()
local ClosestInteractionPart = nil
local ClosestDistance = math.huge
for i,v in pairs(Buttons) do
local Distance = Vars.Player:DistanceFromCharacter(v.Position)
if Distance <= MaxDistance and Distance < ClosestDistance then
ClosestInteractionPart = v
ClosestDistance = Distance
end
end
if ClosestInteractionPart ~= nil then
return ClosestInteractionPart
else
return false
end
end
function CanInteract(NewInteractionPart)
local InteractableBy = NewInteractionPart.Settings.InteractableBy
local ToolRequired = NewInteractionPart.Settings.ToolRequired
if ToolRequired.Value ~= 'None' and not Vars.Player.Character then
return false
elseif ToolRequired.Value ~= 'None' and Vars.Player.Character and not Vars.Player.Character:FindFirstChild(ToolRequired.Value) then
return false
end
if InteractableBy.Value == 'All' then
return true
elseif InteractableBy.Value == Vars.Player.Name then
return true
elseif InteractableBy.Value:find(Vars.Player.Team.Name) then
return true
else
return false
end
end
function TweenButton(Button, TweenType)
local function TweenOut(ButtonToTween)
local Goal = {}
Goal.Size = UDim2.new(1,0,0,0)
Goal.Position = UDim2.new(0,0,1,0)
local ResetProgress = Lib.CreateTween(ButtonToTween.Background.ProgressBar, 0, Goal)
ResetProgress:Play()
Goal = {}
Goal.Position = UDim2.new(-0.08, 0, -0.08, 0)
local ButtonOut = Lib.CreateTween(ButtonToTween.Background, 0.2, Goal)
ButtonOut:Play()
LastButton = nil
end
local function TweenIn()
Goal = {}
Goal.Position = UDim2.new(0, 0, 0, 0)
local ButtonIn = Lib.CreateTween(Button.Background, 0.2, Goal)
ButtonIn:Play()
local Goal = {}
Goal.Size = UDim2.new(1,0,1,0)
Goal.Position = UDim2.new(0,0,0,0)
local Progress = Lib.CreateTween(Button.Background.ProgressBar, 1, Goal)
Progress:Play()
return Progress
end
if TweenType == 'TweenIn' then
for i,v in pairs(ButtonsTweening) do
TweenOut(i)
i = nil
end
for i,v in pairs(Tweens) do
i:Cancel()
i = nil
end
local Progress = TweenIn()
Tweens[Progress] = true
ButtonsTweening[Button] = true
table.insert(Connections, Progress.Completed:Connect(function(PlaybackState)
if PlaybackState == Enum.PlaybackState.Completed then
print('completed!')
Vars.Remotes.ButtonEvent:FireServer(InteractionPart.Settings.Action.Value, InteractionPart, Button.Name)
TweenOut(Button)
Tweens[Progress] = nil
end
end))
elseif TweenType == 'TweenOut' then
TweenOut(Button)
ButtonsTweening[Button] = nil
end
end
function ConnectButtonEvents(ActionName, InputState)
local Button = nil
if ActionName == 'Button1' then
Button = ButtonUI.Frame.Button1
elseif ActionName == 'Button2' then
Button = ButtonUI.Frame.Button2
elseif ActionName == 'Button3' then
Button = ButtonUI.Frame.Button3
end
if Button ~= nil then
if InputState == Enum.UserInputState.Begin then
TweenButton(Button, 'TweenIn')
elseif InputState == Enum.UserInputState.End then
TweenButton(Button, 'TweenOut')
end
end
end
function EnableButtonForPlatform(Button)
local Controller = Vars.UserInputService.GamepadEnabled
local Touchscreen = Vars.UserInputService.TouchEnabled
if Controller then
if Button.Name == 'Button1' then
Button.Background.Keybind.Text = 'X'
elseif Button.Name == 'Button2' then
Button.Background.Keybind.Text = 'B'
elseif Button.Name == 'Button3' then
Button.Background.Keybind.Text = 'Y'
end
elseif Touchscreen then
Button.Background.Keybind.Text = ''
Button.Background.Keybind.TouchIcon.Visible = true
else
if Button.Name == 'Button1' then
Button.Background.Keybind.Text = 'E'
elseif Button.Name == 'Button2' then
Button.Background.Keybind.Text = 'F'
elseif Button.Name == 'Button3' then
Button.Background.Keybind.Text = 'G'
end
end
end
function Refresh()
for i,v in pairs(Connections) do
if v.Connected then
v:Disconnect()
v = nil
end
end
Connections = {}
ButtonsTweening = {}
for i,v in pairs(ButtonUI.Frame:GetChildren()) do
if v:IsA('Frame') then
v:Destroy()
end
end
for i = 1,3 do
Vars.ContextActionService:UnbindAction('Button'..tostring(i))
end
end
Buttons.Enable = function()
ButtonUI = script:WaitForChild('ButtonUI'):Clone()
ButtonUI.Parent = Vars.Player.PlayerGui
Vars.RunService.Heartbeat:Connect(function()
if Vars.Player.Character then
local NewInteractionPart = GetClosestInteractionPart()
if NewInteractionPart and NewInteractionPart ~= InteractionPart and NewInteractionPart.Settings.Interactable.Value and CanInteract(NewInteractionPart) then
Refresh()
InteractionPart = NewInteractionPart
ButtonUI.Adornee = InteractionPart
for i,v in pairs(InteractionPart.Settings.Options:GetChildren()) do
local NewButton = script.ButtonTemplate:Clone()
NewButton.Name = v.Name
EnableButtonForPlatform(NewButton)
NewButton.Background.Action.Text = v.Value
NewButton.Parent = ButtonUI.Frame
table.insert(Connections, NewButton.Background.Keybind.MouseButton1Down:Connect(function()
TweenButton(NewButton, 'TweenIn')
end))
table.insert(Connections, NewButton.Background.Keybind.MouseButton1Up:Connect(function()
TweenButton(NewButton, 'TweenOut')
end))
table.insert(Connections, v.Changed:Connect(function()
NewButton.Background.Action.Text = v.Value
end))
if v.Name == 'Button1' then
Vars.ContextActionService:BindAction('Button1', ConnectButtonEvents, false, Enum.KeyCode.E, Enum.KeyCode.ButtonX)
elseif v.Name == 'Button2' then
Vars.ContextActionService:BindAction('Button2', ConnectButtonEvents, false, Enum.KeyCode.F, Enum.KeyCode.ButtonB)
elseif v.Name == 'Button3' then
Vars.ContextActionService:BindAction('Button3', ConnectButtonEvents, false, Enum.KeyCode.G, Enum.KeyCode.ButtonY)
end
end
table.insert(Connections, InteractionPart.Settings.Interactable.Changed:Connect(function()
if InteractionPart.Settings.Interactable.Value then
ButtonUI.Adornee = InteractionPart
ButtonUI.Enabled = true
else
ButtonUI.Adornee = nil
ButtonUI.Enabled = false
end
end))
table.insert(Connections, InteractionPart.Settings.InteractableBy.Changed:Connect(function()
if not CanInteract(InteractionPart) then
Refresh()
ButtonUI.Enabled = false
ButtonUI.Adornee = nil
InteractionPart = nil
end
end))
table.insert(Connections, Vars.Player.Character.ChildRemoved:Connect(function()
if not CanInteract(InteractionPart) then
Refresh()
ButtonUI.Enabled = false
ButtonUI.Adornee = nil
InteractionPart = nil
end
end))
ButtonUI.Enabled = true
elseif not NewInteractionPart then
Refresh()
ButtonUI.Enabled = false
ButtonUI.Adornee = nil
InteractionPart = nil
end
end
end)
end
return Buttons```