Ad
Log in to vote
2

How can I properly use/code the 'InputBegan' event of 'UserInputService'?

Asked by 7 years ago

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)
0
@Alpha; this is a very non-trivial question. In order to give you a proper answer, I would basically need to write an essay on how to make a chat system. For now, I'll leave an answer that explains how to properly use the UserInputService's events. adark 5487 — 7y

2 answers

Log in to vote
4
Answered by 7 years ago

InputObject

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

Using This

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)

Summary

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!


Issues to Avoid

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.

Useful Links

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

0
There's a lot wrong with this but I am way too tired to write right now. adark 5487 — 7y
0
Sorry if my wording is off. I literally just did some quick tests from what I read off the Wiki. Can you give me a general pointer as to what is wrong? I wanna make sure I get this accurate DigitalVeer 1473 — 7y
0
I just tried the code, however, the result ended like this; 'Type Text Here, or hit the '/' key to typeSlashSlashUnknownUnknownUnknownSlashSDASDWASDReturnReturnUnknownUnknownReturnReturn' Also, sorry if I sound like I'm being picky, I'm just having a hard time programming all this into my head. TheeDeathCaster 2368 — 7y
0
I see lots of incorrect parts. woodengop 1134 — 7y
View all comments (6 more)
0
Continent, care to ellaborate? DigitalVeer 1473 — 7y
0
Like I said, I'm too tired to write out a solid answer to this question. I'll check back in the morning and help then if it isn't sorted out. For now, I'll leave and answer with how I currently use the UserInputService. adark 5487 — 7y
0
Continent, can you please elaborate? You seem to be up DigitalVeer 1473 — 7y
0
I'd love to, but I'm busy. And i'm to stupid to script right now :P woodengop 1134 — 7y
0
Hmmm. Sure. Wanna at least mention one? DigitalVeer 1473 — 7y
0
nvm, mb woodengop 1134 — 7y
Ad
Log in to vote
0
Answered by
adark 5487 Badge of Merit Moderation Voter Community Moderator
7 years ago

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)

Answer this question