2017-03-07 6 views
1

오랫동안 검색 한 결과 인터넷에있는 루아에서 작성된 컴포넌트 기반 엔티티 시스템을 찾기가 불가능하기 때문에 여기에 오기로 결정했습니다.누구나 Lua의 컴포넌트 기반 엔티티 시스템에 대한 예제 코드를 제공 할 수 있습니까?

엔티티 -> "플레이어"가 있고 건강 및 워크 스피드가 포함되어 있습니다. 이 두 가지 Health 및 walkspeed는 예를 들어 Monster와 같은 다른 개체에서 나중에 사용할 수있는 구성 요소 자체를 고려 했습니까? 내 이해는 구성 요소가 나중에 다른 엔터티에 추가 할 수있는 메서드 및 속성을 가진 일반 테이블에 불과하다는 것입니다. 필요하다면 Health Component와 Stamina 구성 요소와 같이 두 개의 구성 요소를 하나씩 추가하거나 병합 할 수 있습니까? 내가 정말로 원하는 것은 샘플 코드입니다. 왜냐하면이 시스템이 어떻게 완전하게 작동하는지, 어떻게 구성 요소가 처음 만들어 지는지, 엔티티 등에 어떻게 추가 할 수 있는지 이해할 수 없기 때문입니다. 어떻게 될까요? 전역 _G 테이블 또는 모듈 덩어리로 저장? 나는 OOP와 상속이 루아에서 어떻게 작동하는지 완전히 이해하고 있지만, 컴포넌트 기반 엔티티 시스템은 그림과 다이어그램만으로 코드 예제를 가지고 있지 않다.

감사합니다 :)

답변

0

이 두 기사 : 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보다 유연합니다.


두 가지 구성 요소가 함께 추가하거나 필요한 경우, 하나에 예를 들어 건강 구성 요소 및 체력 구성 요소에 대한 병합 할 수 있습니까?

"시스템"에 따라 이러한 유형의 구성 요소가 필요하므로 일부 구성 요소가 분리되어있는 것이 좋습니다.

+0

대단히 감사합니다. 매우 도움이됩니다. –

+0

질문이 하나 더 있습니다. "Health_Bar"구성 요소가 "Health"구성 요소의 값을 가져 와서 "Health_Bar"에 따라 Health_Bar 크기를 표시하는 방법에 대해 3D 사용자 인터페이스 요소를 보유하는 "Health_Bar"구성 요소 인 current_health, max_health 특성을 보유하고있는 "Health"구성 요소가 있다고 가정 해 봅시다. Health "구성 요소 값. 나는 그들이 "Health"와 "Health_Bar"라는 별개의 구성 요소가되기를 원합니다. 왜냐하면 나는 모든 Entity에 Health_Bar를 표시하고 싶지 않기 때문입니다. –

+0

** 둘 다 ** Health 및 Health_Bar 구성 요소가 동시에있는 모든 엔티티를 가로 지르는 새로운 "시스템"을 추가해야합니다. "Health Bar system"코드 예제를 답변에 추가했습니다. –