중복 컴포넌트 수정하기

# 학습 과정 소개

MSW는 크리에이터의 월드 제작을 지원하기 위해 다양한 기능을 지속적으로 업데이트하고, 수정하고 있습니다. MSW는 앞으로 중복 컴포넌트가 발생하지 않도록 작업 중입니다. 기능 지원이 완전히 종료되기 전에 미리 가이드를 참고해 월드가 문제 없이 동작할 수 있도록 중복 컴포넌트가 있는지 확인하고 수정하시길 권장합니다.

# 중복 컴포넌트

엔티티나 모델에 동일한 혹은 동류의 컴포넌트가 2개 이상 추가되었다면 그 컴포넌트들을 중복 컴포넌트라 칭합니다. 중복 컴포넌트는 제작 과정에서 예상치 못하게 하나의 엔티티에 동일한 종류의 컴포넌트를 여러 번 추가하거나, 부모-자식 관계의 모델, 엔티티에서 상속 받은 컴포넌트를 인지하지 못한 채 컴포넌트를 추가할 때 주로 발생합니다.

#### 중복 컴포넌트 예시

컴포넌트가 중복될 때 발생하는 문제를 예시와 함께 살펴보며 알아봅시다.

`DoorComponent`는 `Open`, `Close` 함수를 가지고 있습니다.
    
    
    @Component
    script DoorController extends Component
        method void Open()
        log("Door Open")
        end
    
        method void Close()
        log("Door Close")
        end
    end
    

이 컴포넌트를 Extend해 `RevolvingDoorComponent`, `AutomaticSlidingDoorComponent`를 만들고 함수를 재정의했습니다.

  * `RevolvingDoorComponent`
        
        @Component
        script RevolvingDoorController extends Component
        override method void Open()
        log("revolving Door Open")
        end
        
        override method void Close()
        log("Revolving Door Close")
        end
        end
        



    
    
    * `AutomaticSlidingDoorComponent`
        ```lua
    @Component
    script AutomaticSlidingDoor extends Component
        override method void Open()
        log("Automatic Sliding Door Open")
        end
    
        override method void Close()
        log("Automatic Sliding Door Close")
        end
    end
    

`AutomaticSlidingDoorComponent`는 Door1 엔티티에, `RevolvingDoorOpenComponent`는 Door2에 추가했습니다. 그 후 아래와 같은 로직을 작성해서 `DoorComponent`를 통해 확장한 두 컴포넌트의 함수를 호출할 수 있습니다.
    
    
    @Component
    script DoorGroupOpener extends Component
        property Entity Door1 = "/maps/map01/Door1"
        property Entity Door2 = "/maps/map01/Door2"
    
        method void OpenAll()
        self.Door1.DoorComponent:Open() -- Automatic Sliding Door Open
        Self.Door2.DoorComponent:Open() -- Revolving Door Open
        end
    end
    
    
    
    

그러나 두 컴포넌트를 하나의 TestEntity에 추가했다 생각해봅시다. TestEntity에서 `self.TestEntity.DoorComponent:Open()`로 함수를 호출하게 되면 둘 중 어떤 컴포넌트의 Open 함수를 호출해야 하는지 알 수 없습니다. 두 컴포넌트 모두 `DoorComponent`의 함수를 확장해 사용하고 있기에 `AutomaticSlidingDoorComponent`, `RevolvingDoorComponent`중 어떤 것이 더 적절한지 모호하기 때문입니다.
    
    
    
    
    
    @Component
    script DoorOpener extends Component
        -- AutomaticSlidingDoorComponent/RevolvingDoorComponent 모두 존재하는 엔티티
        property Entity Door = "/maps/map01/TestEntity"
    
        method void OpenAll()
        -- AutomaticSlidingDoorComponent/RevolvingDoorComponent 둘 중 어떤 Open()을 할지 모호함
        self.Door.DoorComponent:Open() 
        end
    end
    
    
    
    

# 중복된 컴포넌트 수정하기

중복된 컴포넌트가 있을 경우 Console, Build Console 창에 관련 로그 메시지가 발생합니다. 이 로그 메시지들은 주로 메이커에서 제작 중인 월드에 처음 들어갈 때, 맵을 변경할 때 출력됩니다. 내용과 상황에 따라 적절하게 컴포넌트를 수정하거나, 제거하면 됩니다. 컴포넌트 중복은 주로 아래 네 가지 상황에서 발생합니다. [png](16844893719830c8cccd36923447fac8f6fc1cb46a27c)

#### 맵에 이미 배치된 Entity에서 중복 컴포넌트 발생

맵에 배치된 Entity에 중복된 Component가 있을 경우 메이커 프로 모드 최초 진입 시 또는 메이커에서 맵 이동 시 로그 메시지가 Console 창에 발생합니다. 맵에 배치된 엔티티는 두 가지로 나눌 수 있으며 상황에 맞게 중복된 컴포넌트를 해결해야 합니다.

  1. 모델에서 배치된 Entity 중복된 컴포넌트를 삭제합니다. 월드 동작에 맞게 모델 또는 엔티티에서 중복된 컴포넌트를 삭제해야 합니다.

  2. 맵에 배치된 Entity 에러 메시지를 참고해 중복된 컴포넌트 중 하나를 삭제합니다.




#### 동적으로 생성한 Entity에서 중복 컴포넌트 발생

동적으로 생성한 Entity에 중복된 Component가 있을 경우 테스트 플레이 시, 월드 플레이 시 로그 메시지가 Console 창에 발생합니다. 주로 아래 세 가지 경우에서 발생합니다.

  1. `AddComponent()` 함수로 컴포넌트 추가 `AddComponent()`를 사용해 플레이 중 Entity를 동적으로 추가하는 과정에서 컴포넌트 중복이 발생할 수 있습니다. 컴포넌트를 추가하기 전에 Entity나 Model에서 컴포넌트를 삭제하고 추가하는 것이 좋습니다.
  2. 맵 이동으로 Entity 생성 다른 맵으로 이동하면 이동한 맵의 Entity를 불러오게 됩니다. 이때 이동할 맵에 중복된 컴포넌트를 가진 Entity가 있을 수 있습니다. 발생하는 로그 내용에 따라 중복 컴포넌트가 있는 엔티티를 찾아 문제를 해결하세요.
  3. 모델을 통해 Entity 스폰 모델에 중복 컴포넌트가 있는지 확인하고, 삭제합니다. 자세한 내용은 Model에서 중복 컴포넌트 발생 내용을 참고하세요.



#### Model Extend로 중복된 컴포넌트 발생

여러 개의 모델을 부모-자식 관계로 만들 수 있습니다. 이때 자식 모델은 부모 모델의 Component를 상속 받기 때문에 중복 컴포넌트가 발생할 수 있습니다. Build Console 창에 나타난 로그 메시지를 참고해 컴포넌트를 삭제합니다. 두 가지 경우에서 자주 중복 컴포넌트가 발생합니다.

  1. 완전히 동일한 Component가 추가된 경우 부모 모델과 자식 모델에서 모두에서 동일한 컴포넌트를 추가해 중복 컴포넌트가 발생한 경우입니다. 월드 동작에 맞게 부모, 자식 모델 중 중복된 컴포넌트를 제거하면 됩니다. 부모 모델에서 컴포넌트를 지운다면, 자식 모델의 컴포넌트 중 하나가 지워집니다. 이때 자식 모델에 남은 컴포넌트 값이 초기화될 수 있음을 염두에 두시길 바랍니다. [png](1684565806299564f6ae6ea59402eb33cfbb57fa921cc)
  2. 같은 류의 Component가 추가된 경우 최상위 부모를 공유하는 컴포넌트들 동시에 추가했을 수 있습니다. 이 컴포넌트들은 최상위 부모가 같으므로 중복 컴포넌트로 구분됩니다. 이 경우 월드 동작에 맞추어 적절한 컴포넌트 하나를 남기도록 수정합니다. [png](1684566220223902fa85801c94710a3b3d029922da031)



#### 필요 컴포넌트 추가로 중복 컴포넌트 발생

몇몇 컴포넌트는 사용 시 필수로 함께 사용해야 하는 필요 컴포넌트가 있습니다. 이 필요 컴포넌트는 특정 컴포넌트를 추가했을 때 자동으로 추가되고 있습니다. 이 동작으로 인해 연관 컴포넌트끼리의 추가 순서에 따라 중복 컴포넌트가 발생할 수 있습니다. 이 경우 추가한 컴포넌트를 삭제하고, 재추가해 수정합니다. 이 과정에서 로직 수정이 필요할 수 있습니다. 필요 컴포넌트가 있는 컴포넌트는 아래의 표에서 확인할 수 있습니다.

[png](1690333286437d3f1d73f2865486587ca983f6f6fee13)

[{"추가한 Component":"AIChaseComponent","필요 Component":"StateComponent"},{"추가한 Component":"AIWanderComponent","필요 Component":"StateComponent"},{"추가한 Component":"DistanceJointComponent","필요 Component":"PhysicsRigidbodyComponent, PhysicsColliderComponent"},{"추가한 Component":"PrismaticJointComponent","필요 Component":"PhysicsRigidbodyComponent, PhysicsColliderComponent"},{"추가한 Component":"PulleyJointComponent","필요 Component":"PhysicsRigidbodyComponent, PhysicsColliderComponent"},{"추가한 Component":"RevoluteJointComponent","필요 Component":"PhysicsRigidbodyComponent, PhysicsColliderComponent"},{"추가한 Component":"WeldJointComponent","필요 Component":"PhysicsRigidbodyComponent, PhysicsColliderComponent"},{"추가한 Component":"WheelJointComponent","필요 Component":"PhysicsRigidbodyComponent, PhysicsColliderComponent"},{"추가한 Component":"PhysicsRigidbodyComponent","필요 Component":"PhysicsColliderComponent, TransformComponent"},{"추가한 Component":"PhysicsColliderComponent","필요 Component":"TransformComponent"},{"추가한 Component":"KinematicbodyComponent","필요 Component":"TransformComponent"},{"추가한 Component":"RigidbodyComponent","필요 Component":"TransformComponent"},{"추가한 Component":"SideviewbodyComponent","필요 Component":"TransformComponent"}]