고유한 사용자 정의 범주를 생성해 Explorer 패널에서 게임 수준의 오브젝트를 잘 정리해 둘 수 있습니다. 이러한 새 범주는 Explorer 뷰 및 Layers 뷰 둘 다의 필터 컨트롤과 Explorer 뷰의 트리 뷰에 표시됩니다.
예를 들어 다음 이미지는 "Entities", "Units", "Lights" 및 "Triggers"와 같은 기본 범주 옆에 "Enemies" 및 "Targets"와 같은 사용자 정의 범주를 보여줍니다.
새 범주를 만드는 방법:
범주는 프로젝트 폴더 내의 in .object_filter 리소스 파일에서 정의됩니다. Explorer 패널에 표시하려는 각각의 새 범주에 대해 아래 표시된 SJSON 형식을 따르는 새 텍스트 파일을 만든 다음 .object_filter 확장자를 지정해야 합니다.
범주 필터를 다시 적용하는 방법
범주를 생성하거나 수정하는 경우 Explorer 패널에 변경 사항을 표시하기 위해 Stingray 편집기를 다시 시작할 필요가 없습니다. 대신, F5 키를 눌러 프로젝트의 소스 폴더에서 리소스를 갱신합니다.
위에 표시된 "Enemies"범주를 만드는 데 다음 .object_filter 예제가 사용되었습니다.
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 함수의 기능은 편집기에서 전달하는 단일 오브젝트 수준을 이 범주에 포함할지 여부를 결정하는 것입니다.
편집기에ㅅ는 이 함수에 다음과 같은 두 가지 매개변수를 전달합니다.
level_object: 수준 편집기의 Lua 환경 내에서 테스트해야 하는 게임 오브젝트를 나타내는 래퍼 오브젝트입니다. 이 래퍼는 오브젝트 유형 또는 3D 공간 내에서 오브젝트의 좌표와 같은 게임 오브젝트에 대한 정보를 찾는 데 사용할 수 있습니다.
이러한 래퍼는 현재 문서화되어 있지 않지만 core/editor_slave/editor 폴더에서 래퍼의 코드를 찾을 수 있습니다. unit.lua에 정의된 UnitObject와 같은 다른 종류의 특수 오브젝트에서 상속하는 기본 오브젝트 정의는 object.lua에 있습니다. 일부 오브젝트 관리 및 테스트 기능을 제공하는 level_editing.lua의 LevelEditing 오브젝트를 참조하십시오.
engine_object: 첫 번째 매개변수가 래핑한 게임 오브젝트입니다. 이는 Stingray runtime 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
편집기에서 생성한 유닛에 이름을 할당하는 방식을 잘 정의한 경우 이러한 명명 방식을 활용해 오브젝트를 범주로 정리할 수 있습니다. 예를 들어, 다음 함수는 이름이 문자열 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 키를 눌러 필터를 다시 적용해 변경 사항을 반영해야 합니다.