Reason behind question: I am currently coding a Chat
-like GUI that which will enter in strings
, characters, and then display the message, however, UserInputService
keeps on error-ring, as I have never used it before, what makes it harder is, the ROBLOX Wiki has the Documentary, however, it does not include an example code sadly.
The Output keeps saying InputObject
18:13:31.806 - Players.Player1.PlayerGui.Chat.MainScript:13: attempt to concatenate local 'k2' (a userdata value)
18:13:31.807 - Stack Begin
18:13:31.809 - Script 'Players.Player1.PlayerGui.Chat.MainScript', Line 13
18:13:31.809 - Stack End
, but, because I don't know how to properly code this, I knew something like this would happen, also, yes, I have looked up if there were questions like this; There were, however, they did not explain anything related to my problem of doing a Chat
-like GUI, so, that information didn't really help me when I was developing this code.
This is the code I am using [Keep in mind: I forgot to tab the code while writing it, so, please excuse me if I missed any tabs];
repeat wait() until game.Players.LocalPlayer local plr = game.Players.LocalPlayer; repeat wait() until plr.Character and plr.Character:FindFirstChild("Head") local m = plr:GetMouse(); local head = plr.Character['Head']; repeat wait() until game:GetService("Chat") and script.Parent:FindFirstChild("Txt") local Chat = game:GetService("Chat"); local Started = false; local Txt = script.Parent['Txt']; m.KeyDown:connect(function(k) if k:lower() == '/' then if not Started then Started = true EVENT = game:GetService("UserInputService").InputBegan:connect(function(k2) print(k2) if not Started then return end if k2 == Enum.KeyCode.I then k2 = "i" or "I" elseif k2 == Enum.KeyCode.O then k2 = "o" or "O" end Txt.Text = Txt.Text .. k2 if string.byte(k2) == 13 then print(Txt.Text) Chat:Chat(head,Txt.Text) Txt.Text = "Type Text Here, or hit the '/' key to type" Started = false EVENT:disconnect() end end) end end end)
So, I tested your code and saw that 'k2' was always being printed as an InputObject
.
If you look at the Wiki that contains the properties of InputObject
, you'll see that it actually has a KeyCode
property.
Basically, the KeyCode property will return the 'Enum' of what was pressed.
Now of course, if you tried printing the KeyCode, you'd get output such as this:
Enum.KeyCode.A
Enum.KeyCode.B
Enum.KeyCode.G
However, luckily for us, Enums themselves ALSO have properties. To be exact, they have two properties: Value & Name
http://wiki.roblox.com/index.php?title=Enum
Value and Name
Value will return the byte value of that Enum, which can be found here:
http://wiki.roblox.com/index.php?title=API:Enum/KeyCode
Name will return the 'key' which was hit: LeftShift, A, B , C, Return, ETC
The error is that an InputObject
is NOT at all a String, so rather, you need to obtain the StringValue of that object. To do this, we can change that line simply to use the Value property of the Enum given to us by KeyCode.
[This is a slight cutdown on your code which I used for testing]
repeat wait() until game.Players.LocalPlayer local plr = game.Players.LocalPlayer; repeat wait() until plr.Character and plr.Character:FindFirstChild("Head") local m = plr:GetMouse(); local head = plr.Character['Head']; repeat wait() until game:GetService("Chat") local Chat = game:GetService("Chat"); local Started = false; m.KeyDown:connect(function(k) if k:lower() == 'g' then if not Started then Started = true local EVENT = game:GetService("UserInputService").InputBegan:connect(function(k2) print(k2.KeyCode.Name) -- < end) end end end)
The following code gave me output such as:
A
B
G
D
A
E
H
Now, let's edit your code with this!
repeat wait() until game.Players.LocalPlayer local plr = game.Players.LocalPlayer; repeat wait() until plr.Character and plr.Character:FindFirstChild("Head") local m = plr:GetMouse(); local head = plr.Character['Head']; repeat wait() until game:GetService("Chat") and script.Parent:FindFirstChild("Txt") local Chat = game:GetService("Chat"); local Started = false; local Txt = script.Parent['Txt']; m.KeyDown:connect(function(k) if k:lower() == '/' then if not Started then Started = true EVENT = game:GetService("UserInputService").InputBegan:connect(function(k2) print(k2) if not Started then return end if k2.KeyCode == Enum.KeyCode.I then k2 = "i" or "I" elseif k2.KeyCode == Enum.KeyCode.O then k2 = "o" or "O" end Txt.Text = Txt.Text .. k2.KeyCode.Name if k2.KeyCode.Value == 13 then print(Txt.Text) Chat:Chat(head,Txt.Text) Txt.Text = "Type Text Here, or hit the '/' key to type" Started = false EVENT:disconnect() end end) end end end)
1.) You can't concatenate InputObjects with Strings
2.) InputObjects have a KeyCode property that returns the 'Enum' of the KeyCode
3.) 'Enums' also have two properties, Value and Name.
4.) The Value property returns the byte value of the Enum
5.) The Name Property returns the actual 'thing' which was hit.
6.) You can't call 'string.byte' on the InputObject, but rather this must be done on the KeyCode's Value!
7.) You can't compare InputObjects with Enums! You must compare the KeyCode of it!
Of course, you can use 'string.char' on the byte Value returned by the Value property, however this can lead to some issues.
print(string.char(304)) --304 is Left Shift --Errors
That is why it is a safer option to try and use the 'Name' property when dealing with your situation. Of course, your code can be adapted to using String.char, but this is just a general warning.
http://wiki.roblox.com/index.php?title=API:Class/InputObject
http://wiki.roblox.com/index.php?title=API:Enum/KeyCode
http://wiki.roblox.com/index.php?title=Enum
I understand my explanation may not be the best, but I'm just trying to show how to get the actual 'key' which was hit
You should be using the events provided by UserInputService directly:
local uis = Game:GetService("UserInputService") uis.InputBegan:connect(function(inpt) if inpt.UserInputType == Enum.UserInputType.Keyboard then --KEYDOWN print(inpt.KeyCode.Name) if inpt.KeyCode == Enum.KeyCode.R then game.Players.LocalPlayer.Character.Humanoid.Health = 0 end end end) uis.InputEnded:connect(function(inpt) if inpt.UserInputType == Enum.UserInputType.Keyboard then --KEYUP print(inpt.KeyCode.Name) end end)