「ロブロックスで、プレイヤーが文字を入力できる欄を作りたい」「入力した言葉を看板に出したいけれど、悪い言葉が出たらどうしよう」
ロブロックス(Roblox)スタジオのテキストボックス(TextBox)の使い方を、実際の画像付きで誰でも簡単に分かるように解説します。ここでは、画面の下の入力欄に言葉を入れて「看板に書く」ボタンかEnterキーを押すと、広場の看板にその言葉が出る仕組みを作ります。入れた人以外にも見える文字なので、Robloxの決まりに合わせて、必ず文字のフィルターをかけてから看板に出します。
上級ステップ15/40 前の記事:ロブロックス(Roblox)スタジオでインベントリ(持ち物)を作る方法 全体の順番を見る
使うもの:Roblox Studioが起動するパソコン、マウス、キーボード。看板に文字を出す方法は文字の入れ方、画面のボタンはUIの作り方、プレイヤーのパソコンからサーバーへ伝える部品(RemoteEvent)はRemoteEventの使い方で解説しています。
先に答え
| 知りたいこと | 答え |
|---|---|
| テキストボックスとは | プレイヤーが文字を入力できる画面の部品。押すと入力でき、入った文字は Text で読める |
| 入力が終わったのを知るには | 入力欄でEnterキーを押したときや、ほかの場所を押したときに FocusLost が起きる。Enterキーかどうかは1つ目の値で分かる |
| ほかの人にも見せるときは | ==サーバーで TextService:FilterStringAsync を使ってフィルターをかけてから出す==。公式の説明では、フィルターをかけていないゲームは、かけるまで消されることがある |
| 入力した人にだけ見えるなら | 入力している途中の文字は、1文字ごとにフィルターしなくてよい。送られたあとにフィルターする(公式の説明) |
今回の完成状態:下の画像のように、入力欄に入れた言葉が広場の看板に出れば成功です。

1. 文字を出す看板を置く
看板の板を置く
新しいBaseplateを開きます。エクスプローラの「Workspace」にマウスを乗せて、右に出る「+」を押し、一覧から「Part」を入れます。
入れたPartをエクスプローラで選んだままF2キーを押して、名前を「Sign」に変えます。続けてSignのプロパティを次のように変えます。
| プロパティ | 値 |
|---|---|
| Size | 12, 6, 1 |
| Position(▼CFrameのすぐ下) | 0, 3, -16 |
| Color | 255, 255, 255 |
| Anchored | チェックを入れる |
どのプロパティも、Signを選んだ状態でプロパティの検索欄に名前(「Size」など)を入力し、右の欄を押して数字を書きかえてEnterキーを押します。Positionは「▼CFrame」のすぐ下のPositionに入れます。Anchoredは右の四角を押してチェックを入れます。
エクスプローラにSignが入り(画像の1)、Sizeが「12, 6, 1」になって(画像の2)、白い板が立ちます(画像の3)。下の画像は斜めから見ているので、板はスタートの台の左に写っています。スタートの台に立つと、板は正面の奥に見えます。

看板に文字の部品を貼る
エクスプローラの「Sign」にマウスを乗せて、右に出る「+」を押します。一覧の検索欄に「SurfaceGui」と入れ、「SurfaceGui」を押します。SurfaceGuiは、パーツの1つの面に画面の部品を貼るものです。
エクスプローラで入れたSurfaceGuiを選んだ状態で(画像の1)、プロパティの検索欄に「Face」と入力します。Faceは最初「Front」になっています。右の「Front」を押すと面の一覧が開くので、「Back」を押します(画像の2)。Frontのままだと、スタートの台から見て看板の裏側に貼られてしまい、文字が見えません。

続けて、エクスプローラの「SurfaceGui」にマウスを乗せて、右に出る「+」を押し、一覧から「TextLabel」を入れます。TextLabelを選んだままF2キーを押して、名前を「SignText」に変えます。SignTextのプロパティを次のように変えます。
| プロパティ | 値 | 理由 |
|---|---|---|
| Size | {1, 0},{1, 0} | 看板の面いっぱいに広げる(最初は {0, 200},{0, 50}) |
| TextScaled | チェックを入れる | 看板の大きさに合わせて文字を大きくする(最初はチェックなし) |
| Text | ここに文字が出ます | 最初に看板に出しておく文字(最初は「Label」) |
Sizeは、SignTextを選んだ状態でプロパティの検索欄に「Size」と入力します。AbsoluteSizeなどほかの行も出るので、名前がちょうど「Size」の行の右の欄を押して全部消してから「{1, 0},{1, 0}」とかっこも入れてそのまま入力し、Enterキーを押します。
TextScaledは、SignTextを選んだまま、検索欄に「TextScaled」と入力し、右の四角を押してチェックを入れます。
Textは、SignTextを選んだまま、検索欄に「Text」と入力し、名前がちょうど「Text」の行の右の欄を押して「ここに文字が出ます」に書きかえ、Enterキーを押します。
エクスプローラのSurfaceGuiの中にSignTextが入り(画像の1)、Textが変わって(画像の2)、看板に「ここに文字が出ます」と出ます(画像の3)。

看板の文字を大きくする
SignTextのTextを変えた直後の画面では、看板の大きさに対して文字が小さく見えます。SurfaceGuiは最初、看板の面を「横800・縦600」の広い画面として扱っているので、TextScaledにしても、看板の上では文字が小さく見えます。
エクスプローラで「SurfaceGui」を押して選び、プロパティの検索欄に「CanvasSize」と入力します。最初は「800, 600」になっています。右の欄を押して「240, 120」に書きかえ、Enterキーを押します(画像の1)。看板の横と縦の長さ(12と6)と同じ2対1の割合にしています。看板の文字が大きくなります(画像の2)。

2. サーバーで文字を受け取って看板に出す
伝えるための部品を入れる
入力欄はプレイヤーのパソコンの画面にあり、看板はほかの人にも見えるサーバー側にあります。プレイヤーのパソコンからサーバーへ文字を送るために、RemoteEventを使います。
エクスプローラの「ReplicatedStorage」にマウスを乗せて、右に出る「+」を押し、一覧の検索欄に「RemoteEvent」と入れて「RemoteEvent」を押します。入れたRemoteEventを選んだままF2キーを押して、名前を「SignEvent」に変えます(赤い枠)。

サーバーのスクリプトを書く
エクスプローラの「ServerScriptService」にマウスを乗せて、右に出る「+」を押し、一覧から「Script」を入れます。Scriptを入れると、3D画面のところにスクリプトの画面が開きます。
エクスプローラで、入れた「Script」を押して選び、F2キーを押して名前を「SignScript」に変えます(赤い枠)。

3D画面の上のタブ「SignScript」を押してスクリプトの画面に戻ります。中のコードを全部消して、次のコードを貼り付けます。
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TextService = game:GetService("TextService")
local signEvent = ReplicatedStorage:WaitForChild("SignEvent")
local signText = workspace:WaitForChild("Sign"):WaitForChild("SurfaceGui"):WaitForChild("SignText")
local MAX_LENGTH = 30
local COOLDOWN = 3
local lastWrite = {}
signEvent.OnServerEvent:Connect(function(player, text)
-- 文字ではないもの、空、長すぎる文字は受け取らない
if typeof(text) ~= "string" then
return
end
local length = utf8.len(text)
if not length or length == 0 or length > MAX_LENGTH then
return
end
-- COOLDOWN 秒たつまで、同じ人は書きこめない
local now = os.clock()
if lastWrite[player] and now - lastWrite[player] < COOLDOWN then
return
end
lastWrite[player] = now
-- 必ずフィルターしてから看板に出す
local ok, result = pcall(function()
local filterResult = TextService:FilterStringAsync(text, player.UserId)
return filterResult:GetNonChatStringForBroadcastAsync()
end)
if ok then
signText.Text = result
print("入力:", text, "→ 看板:", result)
else
warn("フィルターできなかったので看板に出しません:", result)
end
end)
Players.PlayerRemoving:Connect(function(player)
lastWrite[player] = nil
end)
フィルターの2つの段階
文字のフィルターは、次の2つの段階で行います。
| 段階 | 書いてある行 | すること |
|---|---|---|
| 1 | TextService:FilterStringAsync(text, player.UserId) | 入力された文字と、入力した人の番号(UserId)を渡して、フィルターの結果を受け取る |
| 2 | filterResult:GetNonChatStringForBroadcastAsync() | サーバーにいる全員に見せる用の文字を取り出す |
Robloxの公式の説明では、2つ目は見せる相手によって使い分けます。
| 見せる相手 | 使うもの | 公式の説明 |
|---|---|---|
| サーバーにいる全員 | GetNonChatStringForBroadcastAsync() | 全員に見える文字に使う。例として、全員に見える看板に文字を書く画面が挙げられている |
| 1人だけ | GetNonChatStringForUserAsync(見る人のUserId) | 特定の1人に見せる文字に使う。見る人の年れいなどに合わせてフィルターされる |
この記事の看板はみんなが見るので、1つ目を使っています。
公式の説明の例でも、フィルターの処理は失敗に備えて pcall で包んでいます。pcall で包んでおくと、失敗してもスクリプトが止まらず、ok に成功したかどうかが入ります。失敗したときは、フィルターしていない文字を看板に出さないように、何もせずに終わります。
そのほかの行の役目
| 行 | 役目 |
|---|---|
if typeof(text) ~= "string" then | 文字以外のもの(数や表)が送られてきたら受け取らない |
utf8.len(text) と MAX_LENGTH = 30 | 文字の数を数え、MAX_LENGTHで決めた30文字より長いときは受け取らない。日本語の1文字も1と数える |
COOLDOWN = 3 と lastWrite | 同じ人が書いてから、COOLDOWNで決めた3秒たつまでは次を受け取らない。連打で看板を書きかえ続けられないようにする |
Players.PlayerRemoving | 抜けた人の記録を消す |
LocalScriptで入力欄の文字の数を確かめることもできますが、プレイヤーのパソコンの中のことは、プレイヤーが自分で書きかえられます。そのため、長さや回数の確かめは、必ずサーバーのスクリプトで行います。
3. 入力欄とボタンを作る
画面の入れ物を作る
エクスプローラの「StarterGui」にマウスを乗せて、右に出る「+」を押し、一覧から「ScreenGui」を入れます。ScreenGuiは、プレイヤーの画面に入力欄やボタンを並べるための入れ物です。入れたScreenGuiをエクスプローラで選んだままF2キーを押して、名前を「SignGui」に変えます。
テキストボックスを入れる
エクスプローラの「SignGui」にマウスを乗せて、右に出る「+」を押します。一覧の検索欄に「TextBox」と入れ(画像の1)、一覧の「TextBox」を押します(画像の2)。

入れたTextBoxを選んだままF2キーを押して、名前を「InputBox」に変えます。InputBoxのプロパティを次のように変えます。
| プロパティ | 値 | 最初の値 |
|---|---|---|
| Size | {0, 300},{0, 50} | {0, 200},{0, 50} |
| Position | {0.5, -150},{1, -130} | {0, 0},{0, 0} |
| Text | (全部消して空にする) | TextBox |
| PlaceholderText | 看板に書く言葉(30文字まで) | 空 |
| TextScaled | チェックを入れる | チェックなし |
SizeとPositionは、InputBoxを選んだ状態でプロパティの検索欄に名前を入力します。右の欄を押して全部消してから、表の値をかっこも入れてそのまま入力し、Enterキーを押します。Sizeの検索ではAbsoluteSizeなどほかの行も出るので、名前がちょうど「Size」の行に入れます。Positionも同じように、名前がちょうど「Position」の行に入れます。
Textは、InputBoxを選んだまま、プロパティの検索欄に「Text」と入力します。名前がちょうど「Text」の行の右の欄を押して、「TextBox」の文字を全部消してからEnterキーを押します。
PlaceholderTextは、InputBoxを選んだまま、検索欄に「PlaceholderText」と入力し、右の欄を押して「看板に書く言葉(30文字まで)」と入れ、Enterキーを押します。PlaceholderTextは、入力欄が空のときだけ薄い色で出る案内の文字です。
TextScaledは、検索欄に「TextScaled」と入力し、右の四角を押してチェックを入れます。
TextとPlaceholderTextの違いは次のとおりです。
| プロパティ | 何の文字か |
|---|---|
| Text | 入力欄に入っている本当の文字。プレイヤーが入力すると変わり、スクリプトはここを読む |
| PlaceholderText | Textが空のときだけ出る案内。スクリプトで読んでも、入力した文字にはならない |
ClearTextOnFocusは、最初からチェックが入っています。チェックが入っていると、入力欄を押したときに、入っていた文字が消えます。
エクスプローラのSignGuiの中にInputBoxが入り(画像の1)、PlaceholderTextが変わって(画像の2)、画面の下のほうに入力欄が出ます(画像の3)。

「看板に書く」ボタンを入れる
エクスプローラの「SignGui」にマウスを乗せて、右に出る「+」を押し、一覧の検索欄に「TextButton」と入れて「TextButton」を押します。入れたTextButtonを選んだままF2キーを押して、名前を「WriteButton」に変えます。WriteButtonのプロパティを次のように変えます。
| プロパティ | 値 | 最初の値 |
|---|---|---|
| Size | {0, 300},{0, 50} | {0, 200},{0, 50} |
| Position | {0.5, -150},{1, -70} | {0, 0},{0, 0} |
| Text | 看板に書く | Button |
| TextScaled | チェックを入れる | チェックなし |
SizeとPositionの入れ方はInputBoxと同じです。Textは、WriteButtonを選んだまま検索欄に「Text」と入力し、名前がちょうど「Text」の行の右の欄を押して「看板に書く」に書きかえ、Enterキーを押します。TextScaledは、検索欄に「TextScaled」と入力し、右の四角を押してチェックを入れます。
Positionの「{0.5, -150}」は、画面の横のまん中から、ボタンの幅の半分(150)だけ左という意味で、ボタンが横のまん中に出ます。「{1, -70}」は、ボタンの上の端を、画面の下の端から70ピクセル上に置くという意味です。入力欄は「{1, -130}」なので、ボタンのすぐ上に並びます。
エクスプローラにWriteButtonが入り(画像の1)、TextScaledにチェックが入って(画像の2)、入力欄の下に「看板に書く」ボタンが出ます(画像の3)。

送るスクリプトを書く
エクスプローラの「SignGui」にマウスを乗せて、右に出る「+」を押し、一覧から「LocalScript」を入れます。LocalScriptは、プレイヤーのパソコンの中で動くスクリプトです(ローカルスクリプトとは)。
スクリプトの画面が開くので、エクスプローラで入れた「LocalScript」を押して選び、F2キーを押して名前を「SignInput」に変えます(赤い枠)。

3D画面の上のタブ「SignInput」を押してスクリプトの画面に戻ります。中のコードを全部消して、次のコードを貼り付けます。
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local signEvent = ReplicatedStorage:WaitForChild("SignEvent")
local gui = script.Parent
local inputBox = gui:WaitForChild("InputBox")
local writeButton = gui:WaitForChild("WriteButton")
-- 入力された文字をサーバーに送り、入力欄を空にする
local function send()
local text = inputBox.Text
if text == "" then
return
end
signEvent:FireServer(text)
inputBox.Text = ""
end
-- 「看板に書く」ボタンを押したとき
writeButton.Activated:Connect(send)
-- 入力欄でEnterキーを押したとき
inputBox.FocusLost:Connect(function(enterPressed)
if enterPressed then
send()
end
end)
| 行 | 役目 |
|---|---|
inputBox.Text | 入力欄に入っている文字を読む |
signEvent:FireServer(text) | 文字をサーバーに送る。サーバーのSignScriptの OnServerEvent が受け取る |
inputBox.Text = "" | 送ったあと、入力欄を空にする |
inputBox.FocusLost | 入力欄から入力の状態が外れたときに起きる。Enterキーを押したときは enterPressed が true、ほかの場所を押したときは false |
FocusLost で enterPressed を確かめているのは、入力の途中でほかの場所を押しただけで送られないようにするためです。
4. テストする
3D画面の上の作品のタブ「Place1」を押して3D画面に戻り、F5キーでテストを始めます(タブの名前はパソコンによって違います)。
画面の下の入力欄を押すと、入力できる状態になります。言葉を入れると、入力欄にその言葉が出ます(赤い枠)。下の画像は「ようこそ広場へ」と入れたテストの画面です。

「看板に書く」ボタンを押すと、入力欄が空に戻り、看板に「ようこそ広場へ」と出ます(画像の1)。出力には「入力: ようこそ広場へ → 看板: ようこそ広場へ」と出ます(画像の2)。スタートの台に立ったままだと、アバターの体で看板が隠れることがあります。下の画像は、看板が見えるように、W・A・S・Dキーで少し横へ歩いてから撮ったものです。

入力欄に言葉を入れてEnterキーを押しても、同じように看板に出ます。
以下は、アソビシフト編集部が2026年10月27日にStudioのテストで確かめた結果です。
| 送った言葉 | 送り方 | 看板 |
|---|---|---|
| ようこそ広場へ(7文字) | 「看板に書く」ボタン | 「ようこそ広場へ」が出た |
| あしたも遊ぼう(7文字) | Enterキー | 「あしたも遊ぼう」が出た |
| 31文字の言葉 | Enterキー | 変わらなかった(MAX_LENGTHの30文字より長い) |
| 同じ言葉「はやい」を3秒以内に続けて2回 | Enterキー | 出力の「入力: はやい → 看板: はやい」の行が1つだけ出た(COOLDOWNの3秒の間は受け取らない) |
| でんわは09012345678 | Enterキー | そのまま出た(5節) |
31文字の言葉を送ったあとの看板は、前の「あしたも遊ぼう」のままです(赤い枠)。

5. Studioのテストではフィルターされたか分からない
電話番号のような数字を入れて送ると、Studioのテストでは、看板にもそのまま出ました(画像の1)。出力でも、入力と看板の文字が同じです(画像の2)。

Robloxの公式の説明では、フィルターは見せてはいけない言葉や、電話番号のような個人の情報を見せないためのものです。ただ、編集部がStudioのテストで試したかぎりでは、数字はそのまま出ました。Studioのテストでは隠れた様子を確かめられないので、「看板に出たから大丈夫」と考えず、コードで必ず FilterStringAsync を通しているかを見て確かめます。
公式の説明では、Robloxは、フィルターをかけていないゲームを見つけたり報告を受けたりすると、フィルターを足すまでそのゲームを消すと書かれています。ゲームを公開する前に、ほかの人に見える文字を出しているところが、すべてこの記事の形になっているか確かめます。
| 出す文字 | フィルター |
|---|---|
| ゲームの中のチャット(Robloxの標準のチャット) | Robloxが自動でかける |
| プレイヤーが入力して、ほかの人にも見せる文字(看板、ペットの名前など) | 自分でかける(この記事の方法) |
| 保存しておいた、プレイヤーが入力した文字を、あとで出すとき | 公式の説明では、出すときにフィルターする |
| 入力した人にだけ見える、入力中の文字 | 1文字ごとにはかけない。送られたあとにかける |
| 作った人が自分で書いた文字(看板の「ここに文字が出ます」など) | 公式がフィルターするよう求めているのは、作った人が自分で決められない文字。自分で書いた文字はこれに当たらない |
Shift + F5キーでテストを停止します。
うまくいかないとき
| こまっていること | 見るところ | 直し方 |
|---|---|---|
| 入力欄を押しても入力できない | InputBoxのTextEditable(入力欄に文字を入れられるかどうかを決めるプロパティ) | チェックが入っているか確かめる(最初はチェックあり) |
| 「看板に書く」を押しても看板が変わらない | 出力の黄色い文字 | 「Infinite yield possible on 〜」と出たら、その最後に書かれた名前の部品が見つかっていない。名前が「SignEvent」「Sign」「SurfaceGui」「SignText」「InputBox」「WriteButton」とコードで同じか確かめる(Infinite yield possibleの直し方) |
| 看板が変わらず、出力に何も出ない | 送った言葉と時間 | MAX_LENGTHで決めた30文字より長くないか、前に送ってからCOOLDOWNで決めた3秒たったか確かめる |
| 看板の文字が小さい | SurfaceGuiのCanvasSize | 看板の横と縦の割合に合わせて小さくする(この記事では 240, 120) |
| 看板に文字が出ない | SurfaceGuiのFace | スタートの台から見える面(Back)になっているか確かめる |
| 入力欄に「TextBox」と出たままになる | InputBoxのText | 全部消して空にする |
| 出力に「フィルターできなかったので看板に出しません」 | Robloxのサーバー | 時間をおいてもう一度送る。続くときはスクリプトが動かないときの確認手順を見る |
よくある質問
入力欄の文字の数を、入力の途中で止められる?
公式のTextBoxの説明には、入力できる文字の数を決めるプロパティはありません(MaxVisibleGraphemesは、見せる文字の数を決めるもので、入力は止まりません)。LocalScriptで inputBox:GetPropertyChangedSignal("Text") を使って、長すぎたら切ることはできます。ただし、プレイヤーのパソコンの中のことは書きかえられるので、この記事のSignScriptのように、サーバーでも必ず長さを確かめます。
数字だけを入力させたい
入力欄に数字以外が入っていないかは、tonumber(inputBox.Text) で確かめられます。数字でなければ nil になるので、そのときは送らないようにします。数字だけでも、サーバーでもう一度確かめるのは同じです。
入力した名前をあとで出すために保存したい
DataStoreの使い方の方法で保存できます。公式の説明では、保存しておいた文字を出すときにもフィルターをかけます。保存のときにかけた結果だけを使うのではなく、出すたびにこの記事の FilterStringAsync を通します。ただし公式の説明では、FilterStringAsync は、入力した人(fromUserId の人)が今のサーバーにいないと失敗します。入力した人が抜けたあとにも出したいときは、この記事のコードのままでは出せないので、公式の Text filtering のページの方法を確かめてから作ります。
次は、コインを渡す処理を1つのModuleScriptにまとめ、3つのアイテムからrequireで呼びます。次のステップ(上級 16/40)
次に知りたいことを選ぶ
- 次のステップ:コインを渡す処理を1つのModuleScriptにまとめ、3つのアイテムからrequireで呼びます → ロブロックス(Roblox)のモジュールスクリプト(ModuleScript)の使い方
- プレイヤーのパソコンとサーバーのやりとりを知りたい → ロブロックス(Roblox)のRemoteEventの使い方
- 看板の文字の出し方を基本から知りたい → ロブロックス(Roblox)スタジオで文字を出す方法
- ボタンや入力欄をスマホでも崩れないように並べたい → ロブロックス(Roblox)スタジオのUIの作り方