I tried to find if a function is named after a Enum by using table.find. It works but I ran into another problem. If the function is named after a KeyCode, then the table.find that is looking for UserInputType will error, vice-versa. How do I get around this problem?
function Interaction.InteractConnections(self: ClassType): ()
if not self.CurrentObject:FindFirstChild("Interact") then
warn("Couldn't find interaction module inside of:", self.CurrentObject.Name)
return
end
local ModuleScript = self.CurrentObject.Interact
local Module = require(ModuleScript)
local UITenums = Enum.UserInputType:GetEnumItems()
local KCenums = Enum.KeyCode:GetEnumItems()
for fnName, fnCode in pairs(Module) do
if type(Module[fnName]) ~= "function" then
continue
end
if table.find(UITenums, Enum.UserInputType[fnName])then
print("UserInputType found inside of", ModuleScript.Name..":", fnName)
end
if table.find(KCenums, Enum.KeyCode[fnName]) then
print("KeyCode found inside of", ModuleScript.Name..":", fnName)
end
end
end
if table.find(UITenums, Enum.UserInputType[fnName])then
Mouse buttons are UserInputTypes!
If Enum.UserInputType[name] doesn’t have an index, it errors the function!
local index = table.find(Enum.UserInputType:GetEnumItems(),fnName) -- check enums for name
index = table.find(UITenums,Enum.UserInputType[index]) -- makes sure there's a table index or not
if index then -- now you have the current index
index = UITenums[index] -- if the table wasn't changed, you can get the value now
local KCindex = table.find(Enum.KeyCode:GetEnumItems(),fnName)
local UITindex = table.find(Enum.UserInputType:GetEnumItems(),fnName)
UITindex = table.find(UITenums,Enum.UserInputType[UITindex])
KCindex = table.find(KCenums,Enum.KeyCode[KCindex])
if UITindex then
print("UserInputType found inside of", ModuleScript.Name..":", fnName)
--self.InteractionConnections:Connect(UserInputService.InputBegan, function(input: InputObject, gameProcessedEvent: boolean)
-- if input.UserInputType == Enum.UserInputType[fnName] then
-- Module[fnName]()
-- end
--end)
end
if KCindex then
print("KeyCode found inside of", ModuleScript.Name..":", fnName)
--self.InteractionConnections:Connect(UserInputService.InputBegan, function(input: InputObject, gameProcessedEvent: boolean)
-- if input.KeyCode == Enum.KeyCode[fnName] then
-- Module[fnName]()
-- end
--end)
end
– fixed the local KCindex = table.find(Enum.KeyCode:GetEnumItems(),fnName)
You’ll always want to make sure the index isn’t nil, if you use table[index] as the table.find() search.
Your function is pretty much erroring because you’re running
table.find(validTable,existingTable[missingIndex]) == error
existingTable[missingIndex] would == nil because missingIndex wasn’t found
local index = table.find(Enum.UserInputType:GetEnumItems(),fnName) -- check enums for name
if index then -- if not nil continue
index = table.find(UITenums,Enum.UserInputType[index])
if index then -- now you have the current index
index = UITenums[index] -- if the table wasn't changed, you can get the value now
end
end
I don’t know, it seems like your nesting the if statements just for it to have the same issues, but when I tried this:
local KCindex = table.find(Enum.KeyCode:GetEnumItems(),fnName)
local UITindex = table.find(Enum.UserInputType:GetEnumItems(),fnName)
if UITindex then
UITindex = table.find(UITenums,Enum.UserInputType[UITindex])
print("UserInputType found inside of", ModuleScript.Name..":", fnName)
--self.InteractionConnections:Connect(UserInputService.InputBegan, function(input: InputObject, gameProcessedEvent: boolean)
-- if input.UserInputType == Enum.UserInputType[fnName] then
-- Module[fnName]()
-- end
--end)
end
if KCindex then
KCindex = table.find(KCenums,Enum.KeyCode[KCindex])
print("KeyCode found inside of", ModuleScript.Name..":", fnName)
--self.InteractionConnections:Connect(UserInputService.InputBegan, function(input: InputObject, gameProcessedEvent: boolean)
-- if input.KeyCode == Enum.KeyCode[fnName] then
-- Module[fnName]()
-- end
--end)
end
Why not just use the actual EnumItem as the key? That way, you can just check if the key exists in the array from :GetEnumItems():
local inputs = {
[Enum.KeyCode.R] = function()
print("Player has pressed R")
end;
[Enum.UserInputType.MouseButton1] = function()
print("Player has left clicked")
end;
[Enum.KeyCode.B] = function()
print("Player has pressed B")
end;
[Enum.UserInputType.MouseButton2] = function()
print("Player has right clicked")
end;
}
for key, func in pairs(inputs) do
if (table.find(Enum.UserInputType:GetEnumItems(), key)) then
print("This is a UserInputType:" .. key.Name)
func()
end
if (table.find(Enum.KeyCode:GetEnumItems(), key)) then
print("This is a KeyCode:" .. key.Name)
func()
end
end
Door has a tag called “Interactable”. The class checks all the tag items and looks for the module called Interact. Then inside the module you have functions that are named by controls.
The door interact has:
local Door = {}
function Door.MouseButton1()
print("Mousebutton1")
end
function Door.MouseButton2()
print("MouseButton2")
end
return Door
The class automatically checks for these functions and connects them once the player is able to interact with the Door. Now the player is able to right click or left click or use the key e on the door. The reason it is set up like this because I feel like it is more easier to change and more readable. If the player isn’t interacting with the door anymore, it disconnects all the interaction connections.
So TLDR: I can’t put a table with the enums inside the class because this is how I want it to be set up.
It didn’t work but luckily I found a solution that didn’t seem very performant to me.
Output:
21:54:44.924 KeyCode found inside of Interact: E - Client - Interaction:222
21:54:44.924 UserInputType found inside of Interact: MouseButton1 - Client - Interaction:209
21:54:44.924 UserInputType found inside of Interact: MouseButton2
Door module:
local Door = {}
function Door.E()
print("E")
end
function Door.MouseButton1()
print("Mousebutton1")
end
function Door.MouseButton2()
print("MouseButton2")
end
return Door
Function:
local function CheckEnums(string): string
for _, v in pairs(KCenums) do
if v.Name == string then
return "KeyCode"
end
end
for _, v in pairs(UITenums) do
if v.Name == string then
return "UserInputType"
end
end
return "None"
end
for fnName, fnCode in pairs(Module) do
if type(Module[fnName]) ~= "function" then
continue
end
local EnumType = CheckEnums(fnName)
if EnumType == "UserInputType" and table.find(UITenums, Enum.UserInputType[fnName])then
print("UserInputType found inside of", ModuleScript.Name..":", fnName)
self.InteractionConnections:Connect(UserInputService.InputBegan, function(input: InputObject, gameProcessedEvent: boolean)
if input.UserInputType == Enum.UserInputType[fnName] then
Module[fnName]()
end
end)
continue -- don't need to go to the other if statement if it goes through this.
end
if EnumType == "KeyCode" and table.find(KCenums, Enum.KeyCode[fnName]) then
print("KeyCode found inside of", ModuleScript.Name..":", fnName)
self.InteractionConnections:Connect(UserInputService.InputBegan, function(input: InputObject, gameProcessedEvent: boolean)
if input.KeyCode == Enum.KeyCode[fnName] then
Module[fnName]()
end
end)
continue
end
end
A lot of for in pairs loops. I’d still take any solution that is less performant than this.
If you connect InputBegan regardless of which input it is, I suggest just checking if input.KeyCode.Name or input.UserInputType.Name exists in the module:
self.InteractionConnections:Connect(UserInputService.InputBegan, function(input: InputObject, gameProcssedEvent: boolean)
local func = Module[input.KeyCode.Name] or Module[input.UserInputType.Name] -- If you pressed E, this would basically be Module["E"]
if (func ~= nil) then
func()
end
end)