As the title says, I’m making a custom chat. Basically, like the majority of the players communicate, they use the / key to trigger the chat box where they input the message and then send it. However, I’m not sure how that can be accomplished.
You can use UserInputService for that. The code must be client-sided, Since UserInputService only works via Client. It would look like this:
-- Variables
local UserInputService = game:GetService("UserInputService")
local SlashKeyCode = Enum.KeyCode.Slash
-- Main
UserInputService.InputBegan:Connect(function(Input: InputObject, IsTyping: boolean)
if not IsTyping then
-- Will only run if we're not Typing
-- For example, Writing on a TextBox.
if Input.KeyCode == SlashKeyCode then
-- Will only run if the Key Pressed is Slash
-- You can write the code here.
end
end
end)
local uis = game:GetService("UserInputService")
local KeyFunctions = {}
function KeyFunctions.Slash()
local a,b
a = -- TextBox
a.Text = ""
game:GetService("RunService").RenderStepped:Wait()
a:CaptureFocus()
local function FocusLost()
if b then
b:Disconnect()
ChatRemote:FireServer(a.Text)
a.Text = ""
end
end
b = a.FocusLost:Connect(FocusLost)
end
function Handler(k,gpe)
if not gpe and KeyFunctions[(k.Name or "1")] ~= nil then
KeyFunctions[k.Name]
end
end
uis.InputBegan:Connect(Handler)
I decided to create a system for this as well, as of right now it just displays the text in the console for every client (via print commands) but that can easily be changed to have the text display on a ScreenGui/SurfaceGui/BillboardGui GuiObject instance instead.
--LOCAL
local StarterGui = game:GetService("StarterGui")
StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Chat, false)
--LOCAL
local Run = game:GetService("RunService")
local UserInput = game:GetService("UserInputService")
local Replicated = game:GetService("ReplicatedStorage")
local FilterRemote = Replicated:WaitForChild("FilterRemote")
local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local TextBox = script.Parent
local function OnInputDetected(Input, Processed)
if Processed then
return
end
if Input.KeyCode == Enum.KeyCode.Slash then
Run.RenderStepped:Wait()
TextBox:CaptureFocus()
end
end
local function OnTextBoxFocusLost(Return, Input)
if TextBox.Text:len() > 0 then
FilterRemote:FireServer(TextBox.Text)
TextBox.Text = ""
end
end
local function OnFilterRemoteFired(Message)
print(Player.Name..": "..Message)
end
FilterRemote.OnClientEvent:Connect(OnFilterRemoteFired)
UserInput.InputBegan:Connect(OnInputDetected)
TextBox.FocusLost:Connect(OnTextBoxFocusLost)
--SERVER
local Text = game:GetService("TextService")
local Replicated = game:GetService("ReplicatedStorage")
local FilterRemote = Replicated.FilterRemote
local ProtectedCall = pcall
local function OnFilterRemoteFired(Player, Message)
local Success1, Result1 = ProtectedCall(function()
return Text:FilterStringAsync(Message, Player.UserId, Enum.TextFilterContext.PublicChat)
end)
if Success1 then
local Success2, Result2 = ProtectedCall(function()
return Result1:GetNonChatStringForBroadcastAsync()
end)
if Success2 then
FilterRemote:FireAllClients(Result2)
else
warn(Result2)
end
else
warn(Result1)
end
end
FilterRemote.OnServerEvent:Connect(OnFilterRemoteFired)
This implementation makes use of 3 scripts and 1 RemoteEvent instance (which is used to fire both the server & its clients). The first local script which goes inside the ReplicatedFirst folder (such that its replication is prioritised over the other elements of the experience) disables the existing core chat gui (this is optional), the second local script is placed inside the “TextBox” instance which is receiving user inputted text and the server script is placed inside the ServerScriptService folder. The single RemoteEvent instance used is named “FilterRemote” and it’s parented to the ReplicatedStorage directory.
If you need any additional help/support let me know.