You can write your topic however you want, but you need to answer these questions:
- What do you want to achieve? Keep it simple and clear!
I want to achieve a module where I could create Tool Classes In where I could call to create UI/Switch Visibility and Bind it to the preferred input like in Blox Fruit by the way here is the UI:
- What is the issue? Include screenshots / videos if possible!
Everything works fine like for everything but when the player dies it goes bonkers nothing errors but nothing works like the Tweening of UI and Binding Input. Note: when not firing replica everything works but when i fire the replica in the function sended to bindPC it doesnt work!
- What solutions have you tried so far? Did you look for solutions on the Creator Hub?
I have tried looking into different implementations through many documentations and AI ![]()
After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!
Here is what happens when the player resets and yes i am clicking after i died like left mouse clicking and the inputs specified on the UI:
This is the Module Script [Element Controller]:
----!strict
local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local Trove = require(ReplicatedStorage.Packages.Trove)
local t = require(ReplicatedStorage.Packages.t)
local CooldownHandler = require(ReplicatedStorage.Modules.CooldownHandler)
type Controller = {
__index: Controller,
new: (Name: string, Player: Player, Module: ModuleScript) -> Class,
UIPC: (self: Class, show: boolean) -> (),
BindPC: (self: Class, functionT1:()->(), functionT1:()->(), functionT1:()->(), functionM1:()->()) -> (),
}
type Class = typeof(setmetatable({} :: {
Name: string,
Player: Player,
Module: typeof(require(ReplicatedStorage.Modules.Configurations.Static)),
UI: CanvasGroup?,
Thread: thread?,
FirstTime: boolean,
Equip: boolean,
Hold: boolean,
_trove: typeof(Trove.new())
}, {} :: Controller))
function Tweenrow(UI: CanvasGroup, Row: string, Duration: number, self)
if not UI or not UI.Parent then
warn("TweenRow: UI is missing or destroyed for;", self.Name)
return
end
local holder = UI:FindFirstChild("Holder")
if not holder then warn("Holder not found in CanvasGroup") return end
local rowFrame = holder:FindFirstChild(Row)
if not rowFrame then warn(Row .. " not found in UI Holder!") return end
local bar = rowFrame:FindFirstChild("Bar") :: Frame
if not (bar and bar:IsA("Frame")) then
warn("TweenRow: Missing Bar for", Row)
return
end
local info = TweenInfo.new(Duration, Enum.EasingStyle.Linear, Enum.EasingDirection.Out)
local tween = game:GetService("TweenService"):Create(bar, info, {Size = UDim2.new(1, 0, 1, 0)})
tween:Play()
tween.Completed:Connect(function()
bar.Size = UDim2.new(0, 0, 1, 0)
end)
end
local Controller : Controller = {} :: Controller
Controller.__index = Controller
function Controller.new(Name, Player, Module)
local self = setmetatable({}, Controller)
self.Name = Name
self.Player = Player
self.Module = Module
self.UI = nil
self.Thread = nil
self.FirstTime = true
self.Equip = false
self.Hold = false
self._trove = Trove.new()
return self
end
function Controller:UIPC(show)
if UserInputService.PreferredInput ~= Enum.PreferredInput.KeyboardAndMouse then return end
if self.FirstTime then
local CanvasGroup = script.CanvasGroup:Clone()
CanvasGroup.Name = self.Name
CanvasGroup.DisplayName.Text = self.Name
CanvasGroup.Parent = self.Player.PlayerGui:WaitForChild("Tool_UI")
for _, v in pairs(self.Module) do
local Row = script.Template_PC:Clone()
Row.Name = v.Name
Row.DisplayName.Text = v.Name
Row.Key.Text = v.RepresentKey
Row.Parent = CanvasGroup.Holder
end
if show then
CanvasGroup.Visible = true
CanvasGroup.Active = true
self.Equip = true
self.UI = CanvasGroup
self.FirstTime = false
self._trove:Add(CanvasGroup)
self._trove:Add(function()
print("TROVE CLEANED UP!")
end)
end
self.UI = CanvasGroup
self._trove:Add(CanvasGroup)
end
if not self.FirstTime then
if show and self.UI then
self.UI.Visible = true
self.UI.Active = true
self.Equip = true
elseif not show and self.UI then
self.UI.Visible = false
self.UI.Active = false
self.Equip = false
end
end
end
function Controller:BindPC(F1,F2,F3,M1)
assert(t.callback(F1))
assert(t.callback(F2))
assert(t.callback(F3))
assert(t.callback(M1))
if not self._trove then warn("Trove non-existance can't be called for use!") return end
local functionArray = {F1,F2,F3,M1}
for i, v in self.Module do
local keyAllocations = {}
keyAllocations[v.Key] = {
FUNCTION = functionArray[i];
NAME = v.Name;
DURATION = v.Duration;
}
self._trove:Add(UserInputService.InputBegan:Connect(function(Input, Gpe)
if not self.Equip then return end
if Gpe then return end
if Input.KeyCode ~= v.Key then return end
if keyAllocations[v.Key] then
local key = keyAllocations[v.Key]
if CooldownHandler.Check(self.Player.Name, key.NAME) then
CooldownHandler.Add(self.Player.Name, key.NAME, key.DURATION)
key.FUNCTION(self._trove)
if self.UI then
Tweenrow(self.UI, key.NAME, key.DURATION, self)
else
warn("Unable to tweenrow due to ui set to nil!")
end
end
end
end))
end
self._trove:Add(UserInputService.InputBegan:Connect(function(Input, Gpe)
if not self.Equip then return end
if Gpe then return end
if Input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
self.Hold = true
if self.Thread then
self._trove:Remove(self.Thread)
self.Thread = nil
end
self.Thread = self._trove:Add(task.spawn(function()
while self.Hold do
if not self.Equip then return end
if CooldownHandler.Check(self.Player.Name, string.format("%s: M1", self.Name)) then
CooldownHandler.Add(self.Player.Name, string.format("%s: M1", self.Name), 0.1)
if self._trove then
M1(self._trove)
end
end
RunService.Heartbeat:Wait()
end
end))
end))
self._trove:Add(UserInputService.InputEnded:Connect(function(Input, Gpe)
if not self.Equip then return end
if Gpe then return end
if Input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
self.Hold = false
if self.Thread then
self._trove:Remove(self.Thread)
self.Thread = nil
end
end))
local Character = self.Player.Character :: Model
local Humanoid = Character:WaitForChild("Humanoid") :: Humanoid
self._trove:Add(Humanoid.Died:Connect(function()
local storedFunctions = {F1, F2, F3, M1}
if self._trove then
self._trove:Destroy()
end
self.Hold = false
self.Equip = false
self.UI = nil
self.Thread = nil
self.FirstTime = true
self._trove = Trove.new()
local newCharacter = self.Player.Character :: Model
local Humanoid = newCharacter:WaitForChild("Humanoid") :: Humanoid
local success, errorMessage = pcall(function()
self:BindPC(storedFunctions[1], storedFunctions[2], storedFunctions[3], storedFunctions[4])
end)
if success then
print("Successfully rebound after death!")
else
warn("Failed to rebind after death:", errorMessage)
end
end))
end
return Controller
Here is the Local Script under a tool name Static which is using the replicaController
To send data to the server with the functions!
local newElementController = require(game.ReplicatedStorage.Shared.Controllers.NewElementController)
local static = require(game.ReplicatedStorage.Modules.Configurations.Static)
local ReplicaController = require(game.ReplicatedStorage.Network.ReplicaController)
local player = game.Players.LocalPlayer
local tool = script.Parent
local newClass = newElementController.new("Static", player, static)
ReplicaController.RequestData()
tool.Equipped:Connect(function()
newClass:UIPC(true)
end)
tool.Unequipped:Connect(function()
newClass:UIPC(false)
end)
print("=== SCRIPT RUNNING ===")
local replica = ReplicaController.GetReplicaById("Static")
if replica then
local function Move1()
replica:FireServer(1)
end
local function Move2()
replica:FireServer(2)
end
local function Move3()
replica:FireServer(3)
end
local function M1()
replica:FireServer(4)
end
newClass:BindPC(Move1, Move2, Move3, M1)
else
replica = ReplicaController.ReplicaOfClassCreated("Static", function(replica)
local function Move1()
replica:FireServer(1)
end
local function Move2()
replica:FireServer(2)
end
local function Move3()
replica:FireServer(3)
end
local function M1()
replica:FireServer(4)
end
newClass:BindPC(Move1, Move2, Move3, M1)
end)
end
Here is the server if you are wondering:
--!strict
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerScriptService = game:GetService("ServerScriptService")
local ReplicaService = require(ServerScriptService.Shared.Modules.ReplicaService)
local newReplica = ReplicaService.NewReplica({
ClassToken = ReplicaService.NewClassToken("Static"),
Data = {},
Replication = "All"
})
newReplica:ConnectOnServerEvent(function(plr, num)
print("Received on [server]: of function of ".. num)
end)
Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category.
