머티리얼 응용하기

# 학습 과정 소개

머티리얼은 SpriteRendererComponent 외의 다른 여러 가지 렌더러 컴포넌트에서 사용할 수 있습니다. 이를 통해 크리에이터는 시각적으로 다채롭고 색다른 나만의 월드를 구현할 수 있습니다. 이번 과정에서는 여러 컴포넌트에서 어떻게 머티리얼을 사용하는지 알아보겠습니다. 또한 예제를 통해 스크립트로 머티리얼을 제어하는 방법도 살펴보겠습니다.

# 여러 가지 컴포넌트에서 머티리얼 사용하기

머티리얼은 다양한 렌더러 컴포넌트에서 사용할 수 있습니다. 사용 방법은 SpriteRendererComponent에 머티리얼을 적용하는 방법과 동일합니다.

> 더 알아보기 [머티리얼 활용하기](/docs/?postId=828) 가이드에서 머티리얼 생성 및 적용 방법을 확인할 수 있습니다.

머티리얼은 다양한 렌더러 컴포넌트에 적용할 수 있습니다. 단, 일부 렌더러 컴포넌트에서는 사용할 수 있는 셰이더 종류가 제한됩니다. 각 컴포넌트 별로 사용할 수 있는 셰이더를 확인하려면 Shader Picker 창의 필터에서 컴포넌트를 선택하면 됩니다. [png](16868168758722d20cb35ccae47d29c99d45b0314426c)

# 스크립트로 머티리얼 교체하기

플레이어 캐릭터와 닿으면 엔티티의 머티리얼이 교체되는 예제를 살펴봅시다.

  1. 새 머티리얼을 만들고 이름에 Material01을 입력합니다.

  2. Scene에 원하는 엔티티를 배치합니다. 이 예제에서는 Preset List - npc-964를 사용했습니다. [png](166849476370816e1074387b747d684879d5a30fcb8a8)

  3. npc-964의 프로퍼티 에디터 - SpriteRendererComponent - MaterialID에서 [png](1668408907363c261c9faa43d4ee3b131624dd723e3a2) 버튼을 클릭하고 Reference 창에서 Material01을 선택합니다. [png](1668494966129a62b76ffce2740339a667c03d48974c8)

  4. Material01의 프로퍼티 에디터에서 Shader - Outline - InnerOutline을 선택합니다. [png](16684932469197db2f5663ffe4856adf503ff2bb3e8e3)

  5. 새 스크립트 컴포넌트 MaterialTest를 생성하고 npc-964에 추가합니다.

  6. 플레이어 캐릭터와의 충돌을 확인하기 위해 npc-964에 TriggerComponent도 추가합니다.

  7. 새 머티리얼을 만들고 이름에 Material02를 입력합니다.

  8. Material02의 프로퍼티 에디터에서 Shader - ColorEffect - Rainbow를 선택합니다.

  9. Workspace - MyDesk - Material02의 콘텍스트 메뉴에서 Copy Entry ID를 클릭합니다. [png](166856445652712d2f198c1c94887a49a7b3a9075715f)

  10. MaterialTest 스크립트를 연 뒤, TriggerEnterEvent를 추가하고 아래와 같이 작성합니다. 위에서 복사한 Material02의 Entry ID를 ChangeMaterial에 붙여 넣습니다.
         
         @Component
         script TriggerMaterialChanger extends Component
         @EventSender("Self")
         handler HandleTriggerEnterEvent(TriggerEnterEvent event)
         --------------- Native Event Sender Info ----------------
         -- Sender: TriggerComponent
         -- Space: Server, Client
         ---------------------------------------------------------
         
         -- Parameters
         -- local TriggerBodyEntity = event.TriggerBodyEntity
         ---------------------------------------------------------
         
         self.Entity.SpriteRendererComponent:ChangeMaterial("material://Entry ID")
         -- 위에서 복사했던 Material02의 Entry ID를 "material://Entry ID" 부분에 붙여 넣기
         end
         end
         



    
    
    11.  **[시작]** 버튼을 누른 뒤 테스트해 봅시다. 플레이어 캐릭터가 닿으면 **InnerOutline**에서 **Rainbow**로 셰이더가 바뀌는 것을 확인할 수 있습니다.
        [gif](1668496643847defbbbec4521479f96f8f9c2fc2768f2)
    
    # 머티리얼 프로퍼티 제어
    
    스크립트를 활용해 월드 플레이 도중 머티리얼 프로퍼티를 제어할 수 있습니다.
    예제를 통해 머티리얼 프로퍼티 제어 방법을 살펴봅시다.
    
    1. "기본" 템플릿으로 월드를 생성합니다.
        [png](1656419849546d61c1ab96b5d454a971009e8053fe3c1)
    
    2. 맵에 상호 작용할 오브젝트를 배치합니다.
        예제에서는 **Preset List - Object - object-273**을 사용했습니다. 
        그리고 **object-273**의 이름을 **StarTree**로 변경합니다.
        [png](16728125334251c9368198cf54d0a93fc0d2f46d44ce6)
    
    3. **Workspace - MyDesk**의 콘텍스트 메뉴에서 **Create Material**을 클릭해 새 머티리얼을 생성하고 이름을 **NewMaterial**로 설정합니다.
    
    4. **NewMaterial**의 프로퍼티 에디터에서 **Shader** 프로퍼티를 **Blurry - Pixel**로 설정합니다.
        [png](16733186086991f9a5b0bd0204fccaf1aaa7cbfe781ed)
    
    5. **StarTree** 오브젝트의 프로퍼티 에디터에서 **SpriteRendererComponent**의 **MaterialID**에 **NewMaterial**을 적용합니다.
        [png](1672813499766954bfde0c3e44620a6138288f25d19d9)
    
    6. 새 스크립트 컴포넌트 **MaterialTest**를 생성하고 **StarTree** 엔티티에 **MaterialTest** 컴포넌트를 추가합니다. 
    
    7. 플레이어와 오브젝트 사이의 거리에 따라 **PixelateSize** 프로퍼티가 변경되도록 해봅시다. 
    **MaterialTest** 컴포넌트에 `OnUpdate()` 함수를 추가하고 실행 공간은 **client only**로 설정합니다. 이후 `OnUpdate()` 함수 내용을 아래와 같이 작성합니다.
        ```lua
    @Component
    script PlayerProximityPixelator extends Component
        @ExecSpace("ClientOnly")
        method void OnUpdate(number delta)
        local userPosition = _UserService.LocalPlayer.TransformComponent.Position
        local selfPosition = self.Entity.TransformComponent.Position
    
        local v = Vector2(userPosition.x - selfPosition.x, userPosition.y - selfPosition.y)
        local dist = Vector2.Distance(Vector2.zero, v)
    
        local changeValue = {["PixelateSize"] = dist * 16 + 16;}
        -- 아래 NewMaterial Entry ID 에는 NewMaterial의 Entry ID를 복사해서 붙여넣기
        _MaterialService:ChangeMaterialProperty("NewMaterial Entry ID", changeValue)
        end
    end
    

  8. 위에 작성한 코드에서 NewMaterial Entry ID 부분에는 자신이 생성한 NewMaterial의 Entry ID을 복사해서 붙여 넣어야 합니다. NewMaterial의 콘텍스트 메뉴에서 Copy Entry ID를 클릭합니다. [png](167331896565459a96e99c98942dab9fb9c85f4013d86)

그 다음, MaterialTest 스크립트를 열고 `OnUpdate()` 함수의 "NewMaterial Entry ID" 부분에 붙여 넣습니다.

  9.  [시작] 버튼을 누른 뒤 테스트해 봅시다. StarTree 오브젝트에 플레이어가 가까이 다가가면 나무가 점점 픽셀화되는 것을 확인합니다. [gif](16733192431971878d51398c04d65bcb4083bbba1cab6)