오버레이 라이트 제어하기

# 학습 과정 소개

Overlay Light를 사용하면 월드에 광원을 만들고, 여러 개의 광원을 겹쳐서 사용할 수 있습니다. OverlayLightComponent, OverlayLightService를 활용해 월드에서 다양한 모양의 광원을 만들 수 있습니다.

# Overlay Light 확인하기

#### Scene에서 확인하기

Overlay Light (Scene-Only) 버튼을 활성화해 Scene에서 Overlay Light를 확인할 수 있습니다.

[png](1768815334039499e1127879541809b4ac65049d8c739)

#### Play에서 확인하기

월드에 처음 진입해 Overlay Light를 사용하려면 메소드를 활용해야 합니다. `SetOverlayLightEnabled()`의 값을 true로 변경해야 합니다. 맵에 광원이 1개 이상 있어야 정상적으로 확인이 가능합니다. 광원이 없는 경우 월드 전체가 암흑으로 보이게 됩니다.
    
    
    @Component
    script OverlayLightEnabler extends Component
        @ExecSpace("ServerOnly")
        method void OnBeginPlay()
            _OverlayLightService:SetOverlayLightEnabled(true)
        end
    end
    

# 광원 종류

광원 종류는 총 4가지입니다. 크리에이터의 필요에 따라 사용할 수 있습니다.

#### Spot

원형으로 나타나는 광원입니다. 프로퍼티 값을 조정해 원형의 모양을 조정할 수 있습니다. `TransformComponent.Scale`의 영향을 받지 않습니다. [png](1768806563088453cd1c0bd1343fb9ae6a2831c42472a)

#### Freeform

크리에이터가 광원을 원하는 모양으로 만들 수 있습니다. [png](176880659998300d7ad91465c4202bd72461fd6d1977a)

#### Global

화면 전체에 적용되는 광원입니다. SortingLayer는 여러 개의 Global Light로부터 동시에 광원 효과를 받을 수 없습니다. [png](17688065857736f88865eafe848bb9ad57a593e2a3d4f)

#### Sprite

크리에이터가 지정한 스프라이트의 RGBA 색상 정보를 조합해 광원의 형태와 색이 나타납니다. [png](1768806616414dd2742c352b94e2593bdb10c27eaf428)

# 주요 프로퍼티

#### 빛의 혼합

OverlapOperation은 여러 개의 광원이 겹칠 경우 어떤 방식으로 빛을 계산해 보여줄 것인지를 결정하는 프로퍼티입니다. 프로퍼티의 값은 두 가지로 Additive, AlphaBlend가 있습니다.

  * Additive: 빛이 겹쳐질수록, 겹치는 부분이 밝은 빛으로 나타납니다. [png](17688093939099217ddd692914320ae627a2988768431)

  * AlphaBlend: LightOrder 값이 큰 광원의 색이 겹치는 부분에 나타납니다. [png](176889079569765366e3dcd9a428d94e0a4a05283396a)




#### 발광 제어

빛의 강도, 감소 영역, 그리고 빛 퍼짐 정도를 다양한 프로퍼티 값을 변경해 제어할 수 있습니다. 광원의 종류마다 사용할 수 있는 프로퍼티 종류가 다릅니다.

  * InnerRadius: 값이 커질수록 빛의 강도가 100%인 범위가 넓어집니다. 광원이 Spot일 때 사용합니다.
  * OuterRadius: 값이 커질수록 빛의 강도가 0%인 범위가 넓어지며, 은은하게 퍼지는 빛의 모양이 됩니다. 광원이 Spot일 때 사용합니다.
  * SpotInnerAngle: 빛의 강도가 100%로 보여질 각도를 설정합니다. 광원이 Spot일 때 사용합니다.
  * SpotOuterAngle: 빛의 강도가 0%로 보여질 각도를 설정합니다. 광원이 Spot일 때 사용합니다.
  * FalloffIntensity: 빛의 감쇠가 일어나는 가파름의 정도를 설정합니다. 광원이 Spot, Freeform일 때 사용합니다.
  * FalloffDistance: 광원을 이루는 점들로부터 빛이 퍼지는 범위를 설정합니다. 값이 커질수록 은은하게 퍼지는 빛의 모양이 됩니다. 광원이 Freeform일 때 사용합니다.



# 광원 제어하기

Overlay Light를 제어하는 방법은 두 가지입니다. 크리에이터가 제작하는 월드에 맞게 OverlayLightComponent, OverlayLightService를 활용할 수 있습니다.

## OverlayLightComponent

OverlayLightComponent를 활용하면 제작 중 Scene에서 광원의 모습을 확인할 수 있습니다. OverlayLightComponent를 활용해 광원을 만드는 기본적인 방법은 아래와 같습니다.

### 활용 예제

TransformComponent만 가진 엔티티를 생성해 맵에 배치하고, OverlayLightComponent를 활용해 광원을 생성하고, 제어해봅시다.

#### 광원 생성하기

  1. 새로운 모델을 만들고, TransformComponent를 추가합니다.
  2. 월드에 진입하면 Spot 타입의 광원이 생성되도록 아래와 같이 작성합니다.


    
    
    @Component
    script OverlayLightSetup extends Component
        @ExecSpace("ClientOnly")
        method void OnBeginPlay()
        -- Overlay Light를 활성화합니다.
        _OverlayLightService:SetOverlayLightEnabled(true)
    
        local lightEntity = _SpawnService:SpawnByModelId("model://New_Model", "Light", Vector3.zero, self.Entity)
    
        -- 엔티티에 OverlayLightComponent를 추가합니다.
        ---@type any
        local overlayLightComponent = lightEntity:AddComponent(OverlayLightComponent)
        end
    end
    

Freeform 타입의 광원을 생성할 때는 광원을 만드는 점들의 정보를 함께 작성해야 합니다.
    
    
    @Component
    script FreeformOverlayLightCreator extends Component
        @ExecSpace("ClientOnly")
        method void OnBeginPlay()
        _OverlayLightService:SetOverlayLightEnabled(true)
    
        local lightEntity = _SpawnService:SpawnByModelId("model://New_Model", "Light", Vector3.zero, self.Entity)
    
        ---@type OverlayLightComponent
        local overlayLightComponent = lightEntity:AddComponent(OverlayLightComponent)
    
        -- 광원 타입을 Freeform으로 변경합니다.
        overlayLightComponent.Type = OverlayLightType.Freeform
    
        -- Freeform 타입 광원의 형상을 정의하는 정점 목록을 작성합니다. 
        local freeformPoints = table.create(4)
        freeformPoints[1] = Vector2(1, 0)
        freeformPoints[2] = Vector2(0, 1)
        freeformPoints[3] = Vector2(-1, 0)
        freeformPoints[4] = Vector2(0, -1)
        overlayLightComponent.FreeformPoints = freeformPoints
        end
    end
    

#### 광원 제거하기

OverlayLightComponent를 삭제해 광원을 제거해봅시다. 10초 뒤 광원이 제거되도록 아래 내용을 가장 아래에 추가합니다.
    
    
    @Component
    script DelayedOverlayRemoval extends Component
        @ExecSpace("ServerOnly")
        method void OnBeginPlay()
            wait(10)
            lightEntity:RemoveComponent(OverlayLightComponent)
        end
    end
    

## OverlayLightService

OverlayLightService로 광원을 제어할 때는 Scene에서 제작한 모습을 확인할 수 없습니다. 그러나 엔티티를 생성하지 않기 때문에 OverlayLightComponent를 사용할 때에 비해 상대적으로 부하가 적습니다. OverlayLightService로 광원을 생성하면 광원마다 시리얼 값이 생성됩니다. 이 시리얼 값을 활용해 광원을 삭제할 수 있습니다.

### 활용 예제

OverlayLightService를 활용해 광원을 생성하고, 제어해 봅시다.

#### 광원 생성하기
    
    
    @Component
    script FreeformOverlayLightSpawner extends Component
        @ExecSpace("ClientOnly")
        method void OnBeginPlay()
        _OverlayLightService:SetOverlayLightEnabled(true)
    
        -- 생성할 Freeform 타입 광원의 정보를 담을 객체를 생성합니다.
        local overlayLightInfo = FreeformTypeOverlayLightInfo(self.Entity)
    
        -- 광원 모양을 만들 점의 정보들을 입력합니다.
        local freeformPoints = table.create(4)
        freeformPoints[1] = Vector2(1, 1)
        freeformPoints[2] = Vector2(-1, 1)
        freeformPoints[3] = Vector2(-1, -1)
        freeformPoints[4] = Vector2(1, -1)
        overlayLightInfo.FreeformPoints = freeformPoints
    
        local serial = _OverlayLightService:SpawnFreeformTypeOverlayLight(overlayLightInfo)
        end
    end
    

> Tip. 광원의 FalloffDistance를 제어하고 싶을 경우 `overlayLightInfo.FalloffDistance = 2.5` 와 같이 값을 설정해 조정할 수 있습니다.

#### 광원 제거하기

OverlayLightService로 생성한 광원은 OverlayLightService의 메소드를 사용해 제거해야 합니다.
    
    
    @Component
    script OverlayLightDestroyer extends Component
        @ExecSpace("ClientOnly")
        method void OnBeginPlay()
        _OverlayLightService:DestroyOverlayLight(serial)
        end
    end