ゲーム レベルのオブジェクトを、ユーザ独自のカスタム カテゴリを作成して Explorer パネルで整理することができます。これらの新しいカテゴリは、Explorer ビューのツリー ビュー、および Explorer ビューと Layers ビュー両方のフィルタ コントロールに表示されます。
たとえば、次のイメージには、「Entities」、「Units」、「Lights」、「Triggers」などの組み込みカテゴリの他に、「Enemies」および「Targets」などのカスタム カテゴリが表示されています。
新しいカテゴリを作成するには:
カテゴリは、プロジェクト フォルダ内の .object_filter リソース ファイル内で定義されます。Explorer パネルに表示する新しい各カテゴリに対して、以下に示すように SJSON フォーマットに従った新しいテキスト ファイルを作成し、拡張子を .object_filter にする必要があります。
カテゴリ フィルタを再適用するには
カテゴリを作成または修正するときに、変更を Explorer パネルに表示するために、Stingray Editor を再起動する必要はありません。代わりに、プロジェクトのソース フォルダからのリソースを更新するには、[F5]キーを押します。
次の .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 つのパラメータを渡します。
level_object: レベル エディタの Lua 環境でテストする必要のある、ゲーム オブジェクトを表すラッパー オブジェクトです。このラッパーを使用して、オブジェクトのタイプや 3D 空間での座標など、そのゲーム オブジェクトに関する情報を検索することができます。
現在、これらのラッパー オブジェクトに関して記載するドキュメントはありませんが、core/editor_slave/editor フォルダ内からコードを利用することができます。基本オブジェクトの定義は、object.lua 内にあり、unit.lua で定義された UnitObject など、その他の種類の特別なオブジェクトによって継承されています。また、オブジェクト管理とユーティリティのテストができる level_editing.lua 内の LevelEditing オブジェクトも参照してください。
engine_object: 1 番目のパラメータによってラップされているゲーム オブジェクトです。これは、Stingray のランタイムの Lua API で公開されているさまざまな種類のオブジェクトのいずれかとなります(stingray.Unit、stingray.Light、stingray.Cameraなど)。このパラメータがどの種類のゲーム オブジェクトを表すのかがオブジェクト レベルから判明したら、オブジェクトを操作するために適切なランタイム API を使用できます。
この関数は、渡されるオブジェクトがこのカテゴリに含まれる必要がある場合は 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]を押してフィルタを再適用し、変更を有効にする必要があります。