カテゴリでレベル オブジェクトを整理する

ゲーム レベルのオブジェクトを、ユーザ独自のカスタム カテゴリを作成して Explorer パネルで整理することができます。これらの新しいカテゴリは、Explorer ビューのツリー ビュー、および Explorer ビューと Layers ビュー両方のフィルタ コントロールに表示されます。

たとえば、次のイメージには、「Entities」、「Units」、「Lights」、「Triggers」などの組み込みカテゴリの他に、「Enemies」および「Targets」などのカスタム カテゴリが表示されています。

新しいカテゴリを作成するには:

カテゴリは、プロジェクト フォルダ内の .object_filter リソース ファイル内で定義されます。Explorer パネルに表示する新しい各カテゴリに対して、以下に示すように SJSON フォーマットに従った新しいテキスト ファイルを作成し、拡張子を .object_filter にする必要があります。

カテゴリ フィルタを再適用するには

カテゴリを作成または修正するときに、変更を Explorer パネルに表示するために、Stingray Editor を再起動する必要はありません。代わりに、プロジェクトのソース フォルダからのリソースを更新するには、[F5]キーを押します。

.object_filter リソース フォーマット

次の .object_filter の例は、上記のカテゴリ「Enemies」を作成するために使用されました。

category_display_name = "Enemies"
category_type_name = "enemies"
evaluation_priority = 10.0
ui_order = 0.0
is_type = """
    -- params: (level_object, engine_object)
    if level_object._unit ~= nil then
        if Unit.has_data(level_object._unit, "is_enemy") then
            return Unit.get_data(level_object._unit, "is_enemy")
        end
    end
    return false
"""

次のパラメータを設定できます。

category_display_name

Explorer パネルに表示されるカテゴリの名前です。

category_type_name

このカテゴリ タイプの内部の名前です。この名前は、コア リソースの組み込みカテゴリを含めて、プロジェクトで使用するすべての .object_filter 定義間で一意である必要があります。

evaluation_priority

このフィルタの優先順位を指定します。レベル内のオブジェクトが複数のカテゴリのフィルタ関数と一致する場合、そのオブジェクトは最も高い評価の優先順位値を持つカテゴリ内に配置されます。

ui_order

このカテゴリが Explorer のツリー ビューで表示される順序を指定します。順序は上から下の順序で、数値が高いほど、カテゴリはリストの下部に配置されます。同じ ui_order 値を持つカテゴリはアルファベット順にソートされます。

このフィールドはオプションです。値を指定しない場合は、そのカテゴリはリストの最後に配置され、ui_order 値を持たないその他のカテゴリとはアルファベット順にソートされます。

フィルタ リスト内のカテゴリは、常に単純なアルファベット順にソートされます。

is_type

オブジェクトがこのカテゴリに配置されているかどうかを決定するために、レベル内の各オブジェクトに対して呼び出される Lua 関数。Lua コードを 3 重引用符 """ で囲んでいることを確認します。詳細については次のセクションを参照してください。

フィルタ関数を作成する

各カテゴリには、エディタがレベル内の各オブジェクトに対して呼び出す is_type 関数が含まれている必要があります。is_type 関数の役割は、エディタによって渡される単一レベルのオブジェクトがこのカテゴリに含まれるかどうかを決定することです。

エディタは、この関数に次の 2 つのパラメータを渡します。

この関数は、渡されるオブジェクトがこのカテゴリに含まれる必要がある場合は true、含まれる必要がない場合は false を返す必要があります。

例: スクリプト データによるフィルタ

上記の例では、フィルタ関数は、特定のタイプのスクリプト データが設定されたユニットに対してのみ true を返します。

if level_object._unit ~= nil then
    if Unit.has_data(level_object._unit, "is_enemy") then
        return Unit.get_data(level_object._unit, "is_enemy")
    end
end
return false

このコードを使用し、オブジェクト タイプを識別する異なるスクリプト データでタグ付けすることで、ゲーム ユニットをカテゴリに分割します。たとえば、景色のオブジェクト、プロップ、車両、またはキャラクタに対して異なるスクリプト データ値を設定できます。これは設定するカテゴリ応じて異なります。

Unit Editor でユニット リソースのスクリプト データを設定できます。

例: リソース名によるフィルタ

リソース名に基づいて、オブジェクトをカテゴリごとに整理できます。たとえば次の関数は、オブジェクトのユニット リソースが指定したリストの値のいずれかと一致する場合のみ true を返します。

local resource_names = {
    "content/models/character/character",
    "content/models/props/target"
}
if level_object._unit ~= nil then
    for _, name in pairs(resource_names) do
        if stingray.Unit.is_a(level_object._unit, name) then return true end
    end
end

例: エディタ ユニット名によるフィルタ

Editor でスポーンしたユニットに名前を割り当てるために明確に定義されたスキームがある場合は、この命名スキームを活用してオブジェクトをカテゴリごとに整理することができます。たとえば次の関数は、ユニットの名前が enemy_ 文字列で始まる場合のみ true を返します。

if level_object.name:find("^enemy_") then return true end
return false

例: ダイナミック データによるフィルタ

オブジェクトの静的プロパティによるフィルタリングだけには制限されません。レベル エディタの現在の状態の動的な面を、フィルタで考慮に入れることもできます。

唯一の注意点は、地表の編集中に変更される可能性があるデータにフィルタリングが依存している場合、そのデータが変更されたときに[F5]を押してカテゴリのフィルタリングを再適用する必要があることです。

たとえば、次の関数は、現在エディタで選択されているすべてのオブジェクトを収集します。これにより、レベル デザイナーはその場でカテゴリに任意のオブジェクト セットを追加することができます。

if level_object._unit ~= nil then
    if LevelEditing.selection:includes(level_object.id) then return true end
end
return false

この手法のその他の使用例としては、カメラの現在のフラスタム内のすべてのオブジェクト、またはエディタ内で現在非表示になっているすべてのオブジェクトを(他のリストからそれらを分離するために)グループ化することです。

例: レベル配置によるフィルタ

3D シーン内での位置によってリソースを整理できます。たとえば、次の関数には、参照位置から 10 メートルの範囲内にある、すべてのユニットが含まれます。

reference_point = stingray.Vector3(0,0,0)
distance_threshold = 10
if level_object._unit ~= nil then
    local position = level_object:local_position()
    if stingray.Vector3.distance(reference_point, position) < distance_threshold then return true end
end
return false

この例では、参照ポイントは原点ですが、ビューポートのカメラ位置、選択したオブジェクト、またはマウスの画面位置で選択したユニットなど他のポイントを使用できます。

該当する領域でユニットがシーンに追加されるたびに、自動的にカテゴリに追加されます。ただし、既存のユニットをこの領域に移動した場合は、[F5]を押してフィルタを再適用し、変更を有効にする必要があります。

関連項目