I would like to loop through the module and update each input (excluding the function) from another local script and update the value hold time to something else.
However for some reason my index is changing to a table when I print it.
RunService.RenderStepped:Connect(function()
for i, v in pairs(PlayerInput) do
print(i, PlayerInput[i]) -- prints: â–¶ Space â–¶ {...}
if PlayerInput[i] ~= PlayerInput.UpdateInput then
if PlayerInput[i].isHeld == true then
print(i, PlayerInput[i]) -- prints: â–¶ {...} â–¶ {...}
PlayerInput[i].holdTime = tick() - PlayerInput[i].startTime
end
end
end
end)
If I print the actual table itself after updating holdTime it returns this
Check the three dots in the upper right of the output, make sure the log mode box is unchecked,
otherwise I would say it’s likely because you have a module script with a table, and it will default to the values every time as a module script does not change (if that makes sense0
I’m not sure I understand your question. A module script can be accesed by any local script when in Replicated Storage, and any Server Script when in ServerStorage. I reccomend changing the value on the server, as it will not update elsewhere.
As for moving the for loop, I’m not sure that would change anything but you can defo try
Before I was updating holdTime by doing it manually and it was working. However, as I add more inputs I don’t really want to be doing this everytime. How come this works but a for loop isn’t?
if PlayerInput.Space.isHeld == true then
PlayerInput.Space.holdTime = tick() - PlayerInput.Space.startTime
end
If I’m reading this right you want a datastore type of module script? I mean like something where you can call and change values with a single function or something?
To an extent yes, I need the module script to store when I’m pressing an input and how long.
local RunService = game:GetService("RunService")
local module = {
Space = {
isHeld = false,
startTime = 0,
holdTime = 0,
endTime = 0,
},
Tab = {
isHeld = false,
startTime = 0,
holdTime = 0,
endTime = 0,
},
}
function module:UpdateInput(input, state)
if state then
local values =
{
isHeld = true,
startTime = tick(),
holdTime = 0,
endTime = 0,
}
module[input] = values
else
local values =
{
isHeld = false,
startTime = 0,
holdTime = 0,
endTime = module[input].holdTime,
}
module[input] = values
end
end
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local PlayerInput = require(ReplicatedStorage:WaitForChild("PlayerInput"))
--Where the for loop was
UserInputService.InputBegan:Connect(function(input, gameProcessedEvent)
if input.KeyCode == Enum.KeyCode.Space and not gameProcessedEvent then
PlayerInput:UpdateInput(PlayerInput.Space, true)
end
if input.KeyCode == Enum.KeyCode.Tab then
PlayerInput:UpdateInput(PlayerInput.Tab, true)
end
end)
UserInputService.InputEnded:Connect(function(input)
if input.KeyCode == Enum.KeyCode.Space then
PlayerInput:UpdateInput(PlayerInput.Space, false)
end
if input.KeyCode == Enum.KeyCode.Tab then
PlayerInput:UpdateInput(PlayerInput.Tab, false)
end
end)
My other scripts then reference these values in the module script and decide what to do from there. I got sick of checking UserInputService in multiple scripts.
The server doesn’t need any of this information. I’m making this because I kept having to use UIS in multiple scripts that do the same thing (checking how long an input is held). The reason I have a local script is because I don’t think module scripts can access user input.
I mean bindable functions. They will allow cross connection so you can just put the user input stuff into a localscript and use the function via that bindable function each time to call it. Bindable Events and Functions | Roblox Creator Documentation
Give me 5 mins to write down what you need to do and a script with where you should put your code
I understand how that could work but its just another hassle to subscribe to events in each script.
It would result in me having to
-Fire an event each frame
-Reference the event
-Set local variables for each input
-Subscribe to function
-Set variables to use elsewhere
I’d much prefer just
-Reference a module script
-Access values as needed
Yeah for that you would need to script a ton of custom functions and events which idk how to do. Just use a bindable function to call it each time or just keep writing it each time. sorry
The “[Table(1615AD21188)]” that you are seeing is a representation of a table reference in Lua. It’s not an actual key or value in your table, but rather a representation of the memory address of the table object.
The reason you are seeing this is because you are using pairs() to iterate through the PlayerInput table, which iterates through both the keys and the values in the table. When you print i and PlayerInput[i], you are seeing the key (i) and the corresponding value (PlayerInput[i]) in the table.
In Lua, tables can have any type of values as keys, including tables. So when you have nested tables like in your module table, PlayerInput[i] can be a table object representing the nested table. This is why you see the memory address representation like “[Table(1615AD21188)]” when you print it.
If you want to access the nested tables in your module table and update their values, you can do so using the key-value pairs of the nested tables, like this:
for i, v in pairs(PlayerInput) do
if type(v) == "table" and v ~= module.UpdateInput then
if v.isHeld == true then
v.holdTime = tick() - v.startTime
end
end
end
Note that in the above code, v represents the values of the nested tables in PlayerInput, and you can directly update their values without using the PlayerInput[i] notation. Also, I’ve added a check to make sure the value v is a table and not the module.UpdateInput function, to avoid trying to update the function itself.
Actually turns out nothing was working and isHeld wasn’t actually being set. I reverted back to when it was working and it turns out it was this
function module:UpdateInput(input, state)
if state then
local values =
{
isHeld = true,
startTime = tick(),
holdTime = 0,
endTime = 0,
}
module[input] = values
else
local values =
{
isHeld = false,
startTime = 0,
holdTime = 0,
endTime = module[input].holdTime,
}
module[input] = values
end
end
--local script
PlayerInput:UpdateInput(PlayerInput.Space, false) -- This doesn't work
PlayerInput:SetInput("Space", true) -- does work
Is there any way I can use PlayerInput.Space instead of a string?
Also your solution worked, heldTime is now being set thank you. I’ll mark yours solution but let me know if you know the answer to my other question.