이 두 기사 : 1, 2 아주 잘 세부 사항 ECS (엔티티 컴포넌트 시스템)에 대해 설명합니다.
Lua에서 ECS를 쉽게 구현할 수 있습니다.
"entity"는 테이블입니다. keys는이 엔터티에 속한 구성 요소 유형 이름이고 값은 true
입니다.
"구성 요소"는 일부 데이터가 포함 된 테이블 일뿐 아니라 일부 구성 요소 유형의 경우 테이블이 비어있을 수 있습니다.
당신이 필요합니다 :
- 글로벌 테이블 "All_Components를"키 값, 값은 구성 요소,
- 글로벌 테이블 "All_Entities"키 개체 ID가되는 서브 테이블이다, 구성 요소 유형의 이름입니다 (키는 엔티티 ID, 값은 엔티티),
update()
함수는 논리적으로 정렬 된 "시스템"체인으로 구성됩니다 ("시스템"은 구성 요소의 특정 조합으로 구성 요소가있는 모든 엔티티에 대해 몇 가지 작업을 수행하는 코드 블록입니다. 유형).
엔티티에 새 구성 요소를 추가하는 것은 구성 요소 테이블을 작성하고 All_Components 및 All_Entities 내의 일부 필드를 수정하는 것입니다. > "플레이어"그것은 건강과 Walkspeed을 포함 -
내가 엔티티를 갖고 있다고 할 수 있습니다. 이 두 가지 Health와 walkspeed는 예를 들어 Monster와 같은 다른 객체에서 나중에 사용할 수있는 구성 요소 자체를 고려합니까?
구성 요소는 해당 엔티티의 비공개 데이터입니다.
다른 엔티티에 대한 구성 요소 인스턴스를 새로 만들어야합니다.
All_Entities = {
[100] = { Health = true, Velocity = true, .... }, -- Player
[101] = { Health = true, Velocity = true, .... }, -- Monster
....
}
All_Components = {
Health = {
[100] = { max_hp = 42, current_hp = 31 }, -- Player's health
[101] = { max_hp = 20, current_hp = 20 }, -- Monster's health
....
},
Velocity = {
[100] = { max_speed = 1.0, speed_x = 0, speed_y = 0 }, -- Player
[101] = { max_speed = 2.5, speed_x = -2.5, speed_y = 0 }, -- Monster
....
},
....
}
function update(dt)
....
-- "Health system" will act on all entities having "Health" component
for entity_id, component in pairs(All_Components.Health) do
-- 5 minutes for full regeneration
component.current_hp = math.min(
component.max_hp,
component.current_hp + component.max_hp * dt/(5*60)
)
end
....
-- "Health_Bar system" will traverse over all the entities
-- having both Health and Health_Bar components simultaneously
for entity_id, comp_Health_Bar in pairs(All_Components.Health_Bar) do
local comp_Health = All_Components.Health[entity_id]
if comp_Health then
-- entity "entity_id" has two components:
-- comp_Health and comp_Health_Bar
-- Now we have all the info needed to draw its health bar
....
end
end
....
end
여기에 OOP가 전혀 없다는 점에 유의하십시오. ECS는 OOP와 아무 관련이 없습니다.
물론 OOP를 추가하여 같은 유형의 모든 구성 요소를 일부 클래스의 인스턴스로 처리 할 수 있습니다. 하지만 정말로 필요하니?
ECS의 개념 : "구성 요소"는 원시 데이터이며, 모든 코드는 "시스템"안에 있으며,이 접근법은 OOP보다 유연합니다.
두 가지 구성 요소가 함께 추가하거나 필요한 경우, 하나에 예를 들어 건강 구성 요소 및 체력 구성 요소에 대한 병합 할 수 있습니까?
"시스템"에 따라 이러한 유형의 구성 요소가 필요하므로 일부 구성 요소가 분리되어있는 것이 좋습니다.
대단히 감사합니다. 매우 도움이됩니다. –
질문이 하나 더 있습니다. "Health_Bar"구성 요소가 "Health"구성 요소의 값을 가져 와서 "Health_Bar"에 따라 Health_Bar 크기를 표시하는 방법에 대해 3D 사용자 인터페이스 요소를 보유하는 "Health_Bar"구성 요소 인 current_health, max_health 특성을 보유하고있는 "Health"구성 요소가 있다고 가정 해 봅시다. Health "구성 요소 값. 나는 그들이 "Health"와 "Health_Bar"라는 별개의 구성 요소가되기를 원합니다. 왜냐하면 나는 모든 Entity에 Health_Bar를 표시하고 싶지 않기 때문입니다. –
** 둘 다 ** Health 및 Health_Bar 구성 요소가 동시에있는 모든 엔티티를 가로 지르는 새로운 "시스템"을 추가해야합니다. "Health Bar system"코드 예제를 답변에 추가했습니다. –