이 항목에서는 런타임 게임 플레이 중 프로젝트의 엔티티와 상호 작용할 수 있는 방법에 대한 개요를 제공합니다.
런타임 시 엔티티와 상호 작용해야 하는 경우 주로 Lua를 통해 해야 합니다.
Story를 사용하여 일부 유형의 구성요소 데이터 값을 설정할 수 있습니다. Story Editor에서 엔티티 트랙에 엔티티를 추가할 때에는 트랙을 마우스 오른쪽 버튼으로 클릭하여 엔티티의 구성요소가 유지해야 하는 숫자 또는 부울 데이터 값에 대한 새로운 애니메이션 트랙을 추가할 수 있습니다. Story Editor도 참조하십시오.
사용자 정의 흐름 노드를 정의하여 필요한 모든 함수를 표시할 수는 있지만 아직 엔티티 시스템은 흐름에 표시되지 않습니다(Lua에서 사용자 정의 흐름 노드 생성 참조).
구성요소를 사용하여 작업할 때는 구성요소 관리자, 구성요소 ID 및 구성요소 인스턴스의 차이점을 이해해야 합니다.
각기 다른 구성요소 유형에 대해 엔진은 해당 구성요소 유형의 모든 개별 인스턴스를 생성하고 업데이트하는 구성요소 관리자를 생성합니다. 구성요소 관리자를 사용하여 개별 구성요소 인스턴스와 상호 작용할 수도 있습니다(예: 특성 값 가져오기 및 설정 또는 함수 호출).
엔티티 내의 각 개별 구성요소에는 소유하고 있는 엔티티 내에서 고유한 ID가 있어야 합니다. 이 이름은 엔티티를 선택할 때 Property Editor에 Transform, Unit 및 Flow와 같이 표시됩니다.
또한 흐름 및 Lua의 특정 구성요소에 액세스하여 해당 특성 값을 가져오거나 설정할 수 있습니다.
일반적으로 문자열로 구성요소의 이름을 지정하여 구별할 수 있습니다. 그러나 엔진은 이러한 이름을 내부적으로 해시된 정수 값으로 저장합니다. Lua를 사용 중이고 DataComponent.lookup()과 같은 함수에 ID를 전달해야 하는 경우 문자열 값이나 해시를 전달할 수 있습니다. 문자열을 전달하면 Stingray가 문자열을 변환합니다. 그러나 변환은 단방향이므로 DataComponent.instance_ids()와 같은 함수를 호출하여 엔진에서 ID 이름을 검색하면 해시된 정수가 반환됩니다.
구성요소 인스턴스는 엔진에서 실제로 생성된 특정 엔티티에 할당된 특정 구성요소를 나타냅니다. 일반적으로 다음 중 하나를 수행하여 해당 유형의 구성요소 관리자로부터 구성요소의 인스턴스를 가져옵니다.
중요: 구성요소 인스턴스는 검색한 프레임 내에서만 유효합니다. 구성요소 인스턴스를 저장하여 이후 프레임에 사용할 수는 없습니다. 대신 구성요소의 인스턴스 ID를 저장한 다음 필요할 때 해당 ID를 통해 또 다른 조회를 수행하여 인스턴스를 다시 가져옵니다.
관리자를 사용하면 일반적으로 사용자가 영향을 주려는 인스턴스를 전달하거나 사용자가 영향을 주려는 인스턴스를 식별하는 엔티티 및 구성요소 ID를 전달하여 사용자가 개별 구성요소와 상호 작용할 수 있습니다. 후자의 경우 구성요소 관리자가 조회를 수행합니다. 예를 들어 DataComponent.set_property ( self, instance, key, value )를 사용하여 인스턴스에 특성을 설정하거나 DataComponent.set_property_by_id ( self, entity, id, key, value )를 사용하여 DataComponent가 사용자가 제공한 엔티티와 ID에서 인스턴스를 조회하도록 할 수 있습니다.
구성요소 ID를 사용하는 것이 더 편리할 수 있습니다. 그러나 지정된 프레임 내의 동일한 구성요소 인스턴스에 대해 동일한 구성요소 관리자를 여러 번 호출해야 하는 경우 추가 조회 호출의 (작은) 오버헤드를 피하기 위해 구성요소 인스턴스를 사용자가 직접 찾는 것이 보다 일반적입니다.
참고: Lua의 인스턴스와 인스턴스 ID에 대해 혼란스러운 점은 둘 다 숫자로 표시된다는 것입니다. ID란 무엇이고 실제 인스턴스에 대한 참조는 무엇인지 이해해야 합니다.
Stingray 편집기에서 수준에 배치하는 엔티티는 런타임 시 해당 수준을 게임에 로드할 때 자동으로 생성됩니다. 이 엔티티는 아직 삭제되지 않은 경우 수준이 언로드되면 자동으로 삭제됩니다.
또한, EntityManager API에서 다음 방식을 사용하여 런타임 시 엔티티를 생성할 수 있습니다.
게임에서 더 이상 필요 없는 엔티티가 있으면 EntityManager.destroy()를 호출해 삭제하면 됩니다. 위의 함수를 호출하여 동적으로 생성한 엔티티든, 수준을 게임에 로드했을 때 자동으로 생성된 엔티티든 이 함수는 모든 엔티티를 대상으로 호출할 수 있습니다.
엔티티 목록을 가져오는 기본적인 방법은 두 가지입니다.
stingray.World.entities()는 현재 "라이브" 상태인 모든 엔티티의 목록을 반환합니다. 해당 구성요소는 다음과 같습니다.
stingray.Level.entities()는 Stingray 편집기에서 지정한 수준에 배치하여, 해당 수준을 로드했을 때 생성된 모든 엔티티의 목록을 반환합니다. Lua 스크립트에 의해 동적으로 삭제되었거나 해당 수준을 언로드하여 삭제된 엔티티는 목록에 포함되지 않습니다.
Stingray 편집기에서 하듯이 구성요소를 동적으로 추가 및 제거하여 게임 플레이 코드에 엔티티를 설정할 수 있습니다. 이 작업은 엔티티에 대해 생성 또는 삭제하려는 구성요소 유형에 사용할 수 있는 구성요소 관리자를 통해 진행할 수 있습니다. 이 구성요소 관리자는 EntityManager에서 검색합니다.
예:
function add_remove_components(entity) -- get the component managers local data_component_manager = stingray.EntityManager.data_component() local xform_component_manager = stingray.EntityManager.transform_component(SimpleProject.world) -- assign a new data component local id = "My New Data Component" local new_component_id = stingray.DataComponent.create(data_component_manager, entity, id) -- remove the first instance of a given component on an entity local xform_component_ids = { stingray.TransformComponent.instance_ids(xform_component_manager, entity) } if next(xform_component_ids) then stingray.TransformComponent.destroy(xform_component_manager, entity, xform_component_ids[1]) end -- remove a component instance with a specific ID local my_instance = stingray.DataComponent.lookup(data_component_manager, entity, "My New Data Component") if my_instance then stingray.DataComponent.destroy(data_component_manager, my_instance) end end
Lua를 사용하여 엔티티에 할당한 구성요소에 액세스할 수 있습니다. 구성요소 인스턴스가 생성되고 나면 관련 구성요소 관리자 오브젝트의 API가 해당 구성요소와 상호 작용할 수 있는 함수를 제공합니다.
예를 들어, 다음 함수는 TransformComponent를 사용하여 해당 변환 구성요소로부터 엔티티의 표준 공간 위치를 가져오는 방법을 보여줍니다. 또한 DataComponent 관리자 API를 사용하여 사용자 정의 데이터 구성요소에 대한 새로운 데이터 값을 설정하는 방법도 보여 줍니다.
function change_component_values(entity) -- get the component managers local data_component_manager = stingray.EntityManager.data_component() local xform_component_manager = stingray.EntityManager.transform_component(SimpleProject.world) -- get component values from a transform component. -- there can only be one transform component on an entity, so instances() returns a single ID. local xform_component_id = stingray.TransformComponent.instances(xform_component_manager, entity) if xform_component_id then -- get its data values local world_matrix = stingray.TransformComponent.world_pose(xform_component_manager, entity) -- use the values print("Entity's world space transform: " .. tostring(world_matrix)) end -- set new data component values on a data component. -- there can be many different data components with different fields, so we -- need to iterate through a list of IDs to find the one that has the value we want to set. local data_component_ids = { stingray.DataComponent.instances(data_component_manager, entity) } for index, data_component_id in ipairs(data_component_ids) do -- check that the data component contains the field we want to change... local property_value = stingray.DataComponent.get_property(data_component_manager, entity, data_component_id, "custom_numeric_field") if property_value then -- set the new value stingray.DataComponent.set_property(data_component_manager, entity, data_component_id, "custom_numeric_field", 250) end end end