📕

【Roblox】TextServiceによる不適切ワードのフィルタリング

2024/10/11に公開

はじめに

今回は、TextServiceを使用してテキストの不適切ワードのフィルタリングを行う方法を紹介します。

Robloxバージョン:0.638.1.6380615

不適切ワードのフィルタリング

Robloxではチャットを行うことができます。チャットでは不適切なワードは自動でフィルタリングしてくれます。


4文字の不適切なワードを入力したが「####」に変換された

しかし、独自に実装するテキスト入力機能(TextBoxなど)ではフィルタリングはされません。
ex) ペットの名前を決める、SurfaceGuiでメモをボードとして建てるなど

下記テキストフィルタリングの公式リファレンスには、このような警告文が書いてあります。
https://create.roblox.com/docs/ui/text-filtering

翻訳すると、「Roblox がレポートを受け取ったり、体験にテキストフィルタリングが適用されていないことを自動的に検出したりした場合、システムはフィルタリングが追加されるまでその体験を削除します。」とあります。

そのため、テキストのフィルタリングは非常に重要なことが分かります。

TextService

テキストにフィルタリングをかける場合は、TextServiceを使用します。
以下はサーバー側でテキストを受け取り、フィルタリング後のテキストをクライアントに送信するプログラムの例です。

local TextService = game:GetService("TextService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TextFilteringEvent = ReplicatedStorage:WaitForChild("GetFilteringText")

-- フィルタリングの結果を返す
local function getFilterResult(text:string, fromUserId:number)
    
    local filterResult
    local success, errorMessage = pcall(function()
        filterResult = TextService:FilterStringAsync(text, fromUserId)
    end)

    if success then
        return filterResult
    else
        warn("Error generating TextFilterResult:", errorMessage)
    end
end

-- フィルタリングを実行する
local function onFilteringText(player:Player, text:string)
    
    if text ~= "" then
        local filterResult = getFilterResult(text, player.UserId)
        
        if filterResult then
            local success, filteredText = pcall(function()
                return filterResult:GetNonChatStringForBroadcastAsync()
            end)

            if success then
                print("FILTERED:", filteredText)
                return filteredText
            else
                warn("Error filtering text!")
            end
        end
    end
end

TextFilteringEvent.OnServerInvoke = onFilteringText

解説

TextService:FilterStringAsync(text, fromUserId) でフィルタリング結果を取得します。
引数はフィルタリングしたい文字列とフィルタリング対象のユーザーIdです。
戻り値はTextFilterResultクラスが返されます。

このTextFilterResultからテキストを使用するパターンに応じてフィルタリングされたテキストを取得する仕組みです。

TextService:FilterStringAsync(text, fromUserId)の注意点

解決できないエラーがでる場合は再試行していけません。
このメソッドは内部で独自の再試行処理を行っているようです。
またこのメソッドが失敗した場合は、どのユーザーにもテキストは表示されないようです。

今のところ引数のformUserIdのユーザーは現在のサーバーでオンラインである必要があります。
将来的にはオフライン、別のサーバーのユーザーもサポートするみたいです。

TextFilterResult

次はTextFilterResultクラスについて説明します。
先ほどのプログラムの解説で使用するパターンに応じてフィルタリングされたテキストを取得するとありました。

大きく分けて2つのパターンを考える必要があります。

  • そのテキストはフィルタリング対象に設定したユーザー以外のユーザーが見る場合があるか。
  • チャットかどうか。

上記2つの条件で、テキストを取得するメソッドを変える必要があります。

ユーザー同士のチャット(独自で実装)の場合

local success, filteredText = pcall(function()
	return filterResult:GetChatForUserAsync(toUserId)
end)

ユーザー同士のチャットの場合はTextFilterResult:GetChatForUserAsync(toUserId)を使用します。
両ユーザーのチャットプライバシー設定が適用されたテキストを返します。

注意点

  • 両ユーザー以外に対しては不適切なテキストの可能性があるため、その他のユーザーに対してこのテキストを表示してはいけません。
  • お互いがチャット可能でない場合やサーバー上でオンラインでない場合などはエラーをスローします。この場合、テキストは表示されません。
  • 対象のユーザーがサーバーに入ってまもない場合は、フィルタリングの情報が取得でない場合があります。

独自にチャットを作成する場合や、メッセージのやり取りをする場合はこちらを使用しましょう。

全てのユーザーが見る可能性があり、チャットではない

local success, filteredText = pcall(function()
	return filterResult:GetNonChatStringForBroadcastAsync()
end)

全てのユーザーが見るチャット以外のテキストの場合はTextFilterResult:GetNonChatStringForBroadcastAsync()を使用します。
このメソッドは全てのユーザーに対して適切にフィルタリングしたテキストを返します。

メッセージ付きの看板を立てたり、ランキングボードに載る名前を自分で設定する機能などを作成するときはこちら使用しましょう。

指定のユーザーのみに表示する場合

local success, filteredText = pcall(function()
	return filterResult:GetNonChatStringForUserAsync(toUserId)
end)

指定のユーザーのみに表示する場合はTextFilterResult:GetNonChatStringForUserAsync(toUserId)を使用します。
このメソッドは、指定したユーザーの年齢やその他詳細に対してフィルタリングをかけた文字列を返します。

自分のみに表示するペット名などは、こちらを使用しましょう。

フィルタリングの確認

上記のテキストフィルタリングを設定することで、不適切ワードを「#」に置き換えられます。

※ 不適切ワードは念のためモザイクをかけています。

注意点として、テキストのフィルタリングはRobloxStudioでは機能しません
Robloxのゲーム上で確認するようにしましょう。

まとめ

  • テキストの入力機能をゲームに取り入れる場合は、フィルタリング機能を設定する。
  • TextService:FilterStringAsync(text, fromUserId)メソッドを呼び、戻り値のTextFilterResultクラスを取得する。
  • 取得したTextFilterResultクラスから、条件(テキストを見るユーザー、チャットの有無)に応じてメソッドを呼び、フィルタリング済みのテキストを取得する。
  • フィルタリングの確認はRobloxのゲーム上で確認する。

基本ユーザー同士のやり取りは、デフォルトのチャットで済むのでフィルタリングは意識しなくても大丈夫です。
しかし、ユーザーがテキストを入力する場合は必ずフィルタリングは必要になります。
テキストのフィルタリングを実装し、ユーザーにとって快適なゲームを作成しましょう!!

参考

https://create.roblox.com/docs/ui/text-filtering
https://create.roblox.com/docs/reference/engine/classes/TextService
https://create.roblox.com/docs/reference/engine/classes/TextFilterResult

ランド・ホー Roblox開発チーム

Discussion