Robloxでのテキスト出力の基本方針
Robloxでは任意のファイル書き出しは不可ですが、GUIへのテキスト出力は柔軟に設計できます。スクロール可能な領域にログやテキストを流す場合は「ScrollingFrame+TextLabel(もしくはTextBox)」の組み合わせが定番です。長文・連続出力・整形表示にそれぞれ適した設計を選ぶのがポイントです。
推奨構成
- スクロール容器: ScrollingFrame(CanvasSizeを内容に合わせて更新)
- テキスト表示: TextLabel(読み取り専用)または TextBox(編集可能)
- 自動サイズ: UIListLayout(行ごと)または TextService:GetTextSize(まとまった塊)
- 整形: RichText(タグで色・太字・リンク風の強調)
- 性能管理: 行の保持上限、バッチ追記、デバウンス(RemoteEvent受信頻度調整)
3つの表示パターン
-
まとまった長文(レポートやドキュメント)
- 構成: ScrollingFrame + 単一TextLabel
- 利点: シンプル・軽量。RichTextで整形が容易。
- 注意: 巨大文字列は再計算コストが増える。追記はバッファリング推奨。
-
ログ/イベントストリーム(行単位で増える)
- 構成: ScrollingFrame + UIListLayout + 行ごとのTextLabel
- 利点: 行単位で管理できる、末尾自動スクロールが簡単。
- 注意: 行数が増えすぎると負荷増。古い行の削除(リングバッファ)を。
-
ユーザー編集を許すノートやメモ
- 構成: ScrollingFrame不要、TextBoxのMultiLineでスクロール
- 利点: 直接編集可能。ClearTextOnFocus=falseで保持。
- 注意: 編集とログの混在は混乱しやすい。編集用と表示用を分離推奨。
実装例(ログストリーム:行単位)
-- StarterGui内のScreenGuiに作成する例
local Players = game:GetService("Players")
local player = Players.LocalPlayer
-- GUI生成
local screenGui = Instance.new("ScreenGui")
screenGui.ResetOnSpawn = false
screenGui.Name = "LogGui"
screenGui.Parent = player:WaitForChild("PlayerGui")
local frame = Instance.new("Frame")
frame.Size = UDim2.new(0, 600, 0, 300)
frame.Position = UDim2.new(0, 20, 0, 20)
frame.BackgroundColor3 = Color3.fromRGB(25, 25, 25)
frame.Parent = screenGui
local scrolling = Instance.new("ScrollingFrame")
scrolling.Size = UDim2.new(1, -20, 1, -20)
scrolling.Position = UDim2.new(0, 10, 0, 10)
scrolling.BackgroundTransparency = 1
scrolling.ScrollBarThickness = 8
scrolling.CanvasSize = UDim2.new(0, 0, 0, 0)
scrolling.Parent = frame
local list = Instance.new("UIListLayout")
list.Padding = UDim.new(0, 4)
list.SortOrder = Enum.SortOrder.LayoutOrder
list.Parent = scrolling
-- 末尾スクロール & CanvasSize更新
local function updateCanvasAndScrollToEnd()
local contentHeight = list.AbsoluteContentSize.Y
scrolling.CanvasSize = UDim2.new(0, 0, 0, contentHeight)
scrolling.CanvasPosition = Vector2.new(0, math.max(0, contentHeight - scrolling.AbsoluteWindowSize.Y))
end
-- 行追加
local MAX_LINES = 500 -- 性能のため上限
local function addLine(text, color)
local label = Instance.new("TextLabel")
label.Text = text
label.TextColor3 = color or Color3.fromRGB(220, 220, 220)
label.BackgroundTransparency = 1
label.Font = Enum.Font.Code
label.TextSize = 16
label.TextWrapped = true
label.RichText = true -- <b></b>など使用可能
label.Size = UDim2.new(1, -10, 0, 0)
label.AutomaticSize = Enum.AutomaticSize.Y
label.Parent = scrolling
-- 上限超過で先頭削除
if #scrolling:GetChildren() > MAX_LINES + 1 then
for _, child in ipairs(scrolling:GetChildren()) do
if child:IsA("TextLabel") then
child:Destroy()
break
end
end
end
updateCanvasAndScrollToEnd()
end
-- 例: 追記
addLine("<b>System</b>: ログ出力開始", Color3.fromRGB(120, 200, 255))
for i = 1, 50 do
addLine(("イベント #%d が処理されました。詳細は…"):format(i))
end
addLine("<i>完了</i> — 末尾に自動スクロールします。")
実装例(まとまった長文:単一ラベル)
local content = table.concat({
"<b>レポート</b>(2025-12-24)",
"1) 概要…",
"2) 指標…",
"3) 考察…",
}, "\n")
local label = Instance.new("TextLabel")
label.BackgroundTransparency = 1
label.Font = Enum.Font.UIText
label.TextSize = 18
label.RichText = true
label.TextXAlignment = Enum.TextXAlignment.Left
label.TextYAlignment = Enum.TextYAlignment.Top
label.TextWrapped = true
label.Size = UDim2.new(1, -20, 0, 0)
label.AutomaticSize = Enum.AutomaticSize.Y
label.Text = content
label.Parent = scrolling
-- サイズに応じてCanvas更新
updateCanvasAndScrollToEnd()
性能と使い勝手の工夫
- バッファリング: 受信イベントごとに追記せず、一定間隔でまとめて追加(例:0.1–0.5秒バッチ)。
- リングバッファ: MAX_LINESを設け古い行を削除、メモリとレイアウト再計算を抑制。
- 軽量フォントとTextSize: 再計算コスト低減。必要な箇所のみRichText。
- ユーザー操作: コピー用ボタン(SetClipboardに相当機能はなし)代替として選択可能TextBoxに複写。
- サーバー同期: RemoteEventでメッセージ送信、サーバー側で頻度制御(スパム・レート制限)。
欲しい追加条件
- 用途: ログ、レポート、メモのどれが主用途ですか?
- 出力量: 想定最大文字数・行数はどれくらいでしょう?
- 整形: 色分け・タグ・リンク風表現など必要なスタイルはありますか?
要件が分かれば、GUI(アフィン変換ツール群)に馴染むミニマルなコンポーネント化(ModuleScript)の形で最適化します。