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)の形で最適化します。