msw-ai-tf/maplestory-worlds-creator-docs huggingface dataset:
OverlayLightService

광원의 생성 및 파괴 기능을 제공합니다.

# Methods

[{"index":"void DestroyOverlayLight(integer serial) (ClientOnly)","0":"광원을 제거합니다. serial에 제거할 광원의 식별 번호를 전달합니다."}]

[{"index":"void SetOverlayLightEnabled(boolean enable) (ClientOnly)","0":"오버레이 라이트의 활성 여부 결정합니다."}]

[{"index":"integer SpawnFreeformTypeOverlayLight(FreeformTypeOverlayLightInfo overlayLightInfo) (ClientOnly)","0":"Freeform 타입의 광원을 맵에 스폰합니다. overlayLightinfo에 Freeform 타입 광원 정보인 FreeformTypeOverlayLightInfo를 전달합니다. 반환값은 생성된 광원의 식별 번호로, 생성에 실패할 경우 0을 반환합니다."}]

[{"index":"integer SpawnFreeformTypeOverlayLightAttached(AttachedFreeformTypeOverlayLightInfo overlayLightInfo) (ClientOnly)","0":"Freeform 타입의 광원을 자식 엔티티로 스폰합니다. overlayLightinfo에 Freeform 타입 광원 정보인 AttachedFreeformTypeOverlayLightInfo를 전달합니다. 반환값은 생성된 광원의 식별 번호로, 생성에 실패할 경우 0을 반환합니다."}]

[{"index":"integer SpawnGlobalTypeOverlayLight(GlobalTypeOverlayLightInfo overlayLightInfo) (ClientOnly)","0":"Global 타입의 광원을 맵에 스폰합니다. overlayLightinfo에 Global 타입 광원 정보인 GlobalTypeOverlayLightInfo를 전달합니다. 반환값은 생성된 광원의 식별 번호로, 생성에 실패할 경우 0을 반환합니다."}]

[{"index":"integer SpawnGlobalTypeOverlayLightAttached(AttachedGlobalTypeOverlayLightInfo overlayLightInfo) (ClientOnly)","0":"Global 타입의 광원을 자식 엔티티로 스폰합니다. overlayLightinfo에 Global 타입 광원 정보인 AttachedGlobalTypeOverlayLightInfo를 전달합니다. 반환값은 생성된 광원의 식별 번호로, 생성에 실패할 경우 0을 반환합니다."}]

[{"index":"integer SpawnSpotTypeOverlayLight(SpotTypeOverlayLightInfo overlayLightInfo) (ClientOnly)","0":"Spot 타입의 광원을 맵에 스폰합니다. overlayLightinfo에 Spot타입 광원 정보인 SpotTypeOverlayLightInfo를 전달합니다. 반환값은 생성된 광원의 식별 번호로, 생성에 실패할 경우 0을 반환합니다."}]

[{"index":"integer SpawnSpotTypeOverlayLightAttached(AttachedSpotTypeOverlayLightInfo overlayLightInfo) (ClientOnly)","0":"Spot 타입의 광원을 자식 엔티티로 스폰합니다. overlayLightinfo에 Spot 타입 광원 정보인 AttachedSpotTypeOverlayLightInfo를 전달합니다. 반환값은 생성된 광원의 식별 번호로, 생성에 실패할 경우 0을 반환합니다."}]

[{"index":"integer SpawnSpriteTypeOverlayLight(SpriteTypeOverlayLightInfo overlayLightInfo) (ClientOnly)","0":"Sprite 타입의 광원을 맵에 스폰합니다. overlayLightinfo에 Sprite 타입 광원 정보인 SpriteTypeOverlayLightInfo를 전달합니다. 반환값은 생성된 광원의 식별 번호로, 생성에 실패할 경우 0을 반환합니다."}]

[{"index":"integer SpawnSpriteTypeOverlayLightAttached(AttachedSpriteTypeOverlayLightInfo overlayLightInfo) (ClientOnly)","0":"Sprite 타입의 광원을 자식 엔티티로 스폰합니다. overlayLightinfo에 Sprite 타입 광원 정보인 AttachedSpriteTypeOverlayLightInfo를 전달합니다. 반환값은 생성된 광원의 식별 번호로, 생성에 실패할 경우 0을 반환합니다."}]

##### inherited from Service:

[{"index":"EventHandlerBase ConnectEvent(string key, IScriptFunction eventHandler)","0":"이벤트를 연결합니다. 이 서비스에서 타입의 이름이 key인 이벤트가 발생하면, 핸들러로 통지받습니다. 핸들러는 event 매개 변수를 전달받습니다."}]

[{"index":"EventHandlerBase ConnectEvent(Type eventType, IScriptFunction eventHandler)","0":"이벤트를 연결합니다. 이 서비스에서 타입이 eventType인 이벤트가 발생하면, 핸들러로 통지받습니다. 핸들러는 event 매개 변수를 전달받습니다."}]

[{"index":"boolean DisconnectEvent(string key, EventHandlerBase eventHandler)","0":"타입의 이름이 key인 이벤트와 핸들러와의 이벤트 연결을 끊습니다."}]

[{"index":"boolean DisconnectEvent(Type eventType, EventHandlerBase eventHandler)","0":"타입이 eventType인 이벤트와 핸들러와의 연결을 끊습니다."}]

[{"index":"void SendEvent(EventType sendEvent)","0":"이벤트를 발생시킵니다."}]
TweenCircularComponent

Entity가 원 경로를 따라 회전합니다.

# Properties

[{"index":"float Degree (Sync)","0":"총 회전 각도를 설정합니다. 값이 360인 경우 한 바퀴 회전하고, 0인 경우 무한히 회전합니다."}]

[{"index":"boolean IsClockwise (Sync)","0":"어느 방향으로 회전할지 정의합니다. true인 경우 시계 방향으로 회전합니다."}]

[{"index":"boolean LookAtCenter (Sync)","0":"값이 true인 경우 중심을 바라보며 회전합니다."}]

[{"index":"float Radius (Sync)","0":"회전 반경을 설정합니다."}]

[{"index":"float Speed (Sync)","0":"초당 몇 도만큼 회전할지 회전 속도를 설정합니다. 값이 360인 경우 1초에 한 바퀴 회전합니다."}]

##### inherited from TweenBaseComponent:

[{"index":"boolean AutoDestroy (Sync)","0":"true일 경우, 트윈이 목적지에 도달하여 끝나거나 직접 Stop()을 호출했을 때 이 컴포넌트를 엔티티에서 제거합니다."}]

[{"index":"boolean AutoStart (Sync)","0":"값이 true일 경우, 게임이 시작되면 트윈이 자동으로 재생합니다."}]

[{"index":"TweenState CurrentState (Sync) (ReadOnly) (HideFromInspector)","0":"현재 재생 상태입니다."}]

[{"index":"Vector3 OriginPosition (Sync) (ReadOnly) (HideFromInspector)","0":"트윈의 시작 위치입니다."}]

[{"index":"Quaternion OriginRotation (Sync) (ReadOnly) (HideFromInspector)","0":"트윈의 시작 회전값입니다."}]

[{"index":"Vector3 OriginScale (Sync) (ReadOnly) (HideFromInspector)","0":"트윈의 시작 크기입니다."}]

[{"index":"TweenSyncType SyncType (ReadOnly)","0":"재생 주체를 설정합니다. 기본값은 Default입니다. 서버와 클라이언트에서 함수로 트윈을 제어할 수 있습니다. 서버 상태는 클라이언트로 항상 동기화됩니다. 실행 공간 제어를 client only로 설정하면 클라이언트에서만 트윈을 제어하도록 제한하고, 서버로 동기화하지 않습니다.트윈 제어 함수: Play, Pause, Stop, Destroy, RestartFromCurrentPosition"}]

[{"index":"number TweenTime (ReadOnly) (HideFromInspector)","0":"트윈이 시작된 후 경과한 시간입니다. 초 단위입니다."}]

##### inherited from Component:

[{"index":"boolean Enable (Sync)","0":"컴포넌트 활성화 여부를 확인합니다."}]

[{"index":"boolean EnableInHierarchy (ReadOnly) (HideFromInspector)","0":"계층 구조상에서 이 컴포넌트가 Enable 상태인지를 반환합니다. Enable이 true일지라도 엔티티의 Enable이 false라면 false를 반환합니다."}]

[{"index":"Entity Entity (ReadOnly)","0":"이 컴포넌트를 소유한 엔티티입니다."}]

# Methods

##### inherited from TweenBaseComponent:

[{"index":"void Destroy()","0":"컴포넌트를 제거합니다. CurrentState를 Destroying으로 변경합니다."}]

[{"index":"void Pause()","0":"트윈을 일시정지합니다. CurrentState를 Pausing으로 변경합니다."}]

[{"index":"void Play()","0":"트윈을 재생합니다. CurrentState를 Playing으로 변경합니다."}]

[{"index":"void RestartFromCurrentPosition()","0":"현재 위치에서 재시작합니다."}]

[{"index":"void Stop(boolean reset)","0":"트윈을 중지합니다. CurrentState를 Idle로 변경합니다. reset에 true를 지정할 경우 트윈의 위치와 진행도를 초기 상태로 되돌립니다."}]

##### inherited from Component:

[{"index":"boolean IsClient()","0":"현재 실행 환경이 클라이언트인지 아닌지의 여부를 반환합니다."}]

[{"index":"boolean IsServer()","0":"현재 실행 환경이 서버인지 아닌지의 여부를 반환합니다."}]

# Examples

`TweenCircularComponent`가 있는 엔티티를 무한히 회전하게 만드는 예제입니다.
    
    
    @Component
    script CircularMovementConfig extends Component
        @ExecSpace("ServerOnly")
        method void OnBeginPlay()
            local tween =self.Entity.TweenCircularComponent
            tween.Degree = 0
            
            -- 회전 반경을 2로 설정합니다.
            tween.Radius = 2
            
            -- 1초에 180도만큼의 속력으로 회전합니다. 한 바퀴 회전하는 데 2초가 소요됩니다.
            tween.Speed = 180
        end
    end
    

# SeeAlso

  * [엔티티 구간 이동시키기](/docs?postId=122)
LightComponent

광원을 출력합니다. TransformComponent와 함께 사용하는 것을 권장합니다.

# Properties

[{"index":"Color Color (Sync)","0":"광원의 색상입니다."}]

[{"index":"float FalloffDistance (Sync)","0":"광원이 Freeform 타입일 때, 빛이 FreeformPoints로부터 얼마나 뻗어 나갈지 결정합니다. 값이 클수록 크기가 커집니다."}]

[{"index":"float FalloffIntensity (Sync)","0":"광원이 사라지는 곡선의 부드러움을 조절합니다. 값이 클수록 광원의 경계선이 흐릿하고 부드러워 보입니다. 값이 작을수록 광원의 경계선이 날카롭고 또렷하게 보입니다."}]

[{"index":"SyncList FreeformPoints (Sync)","0":"Freeform 타입의 광원 모양을 정의하는 점들입니다. 점의 개수는 2000개를 초과할 수 없습니다."}]

[{"index":"boolean IgnoreMapLayerCheck (Sync)","0":"SortingLayer에 Map Layer 이름을 지정했을 때 자동 치환을 수행하지 않습니다."}]

[{"index":"float InnerRadius (Sync)","0":"광원이 Spot 타입일 때 최대 밝기를 갖는 내부 광원 영역의 반경입니다. OuterRadius보다 큰 값을 가질 수 없습니다."}]

[{"index":"float Intensity (Sync)","0":"광원의 강도입니다."}]

[{"index":"int32 LightOrder (Sync)","0":"광원이 라이트 텍스처에 렌더링되는 순서를 결정합니다. 작은 값의 광원이 먼저 렌더링되고, 큰 값의 광원이 그 위에 렌더링됩니다."}]

[{"index":"float OuterRadius (Sync)","0":"Spot 타입의 광원 크기를 결정하는 외부 반경입니다. InnerRadius의 끝에서부터 빛이 감쇠되기 시작하여 이 반지름에 도달하면 빛의 강도가 0%가 됩니다."}]

[{"index":"LightOverlapOperation OverlapOperation (Sync)","0":"광원의 연산 방식입니다."}]

[{"index":"float PlayRate (Sync)","0":"Sprite 타입의 광원일 때 사용하는 애니메이션 클립 리소스의 재생 속도입니다. 숫자가 클수록 재생 속도가 빨라집니다."}]

[{"index":"float SpotInnerAngle (Sync)","0":"Spot 타입 광원의 내부 각도입니다. 각도가 클수록 간격이 넓어집니다. 내부 각도에 있는 모든 픽셀은 빛의 강도가 100%로 적용됩니다. SpotOuterAngle보다 큰 값을 가질 수 없습니다."}]

[{"index":"float SpotOuterAngle (Sync)","0":"Spot 타입 광원의 외부 각도입니다. 값이 클수록 각도가 넓어집니다. SpotInnerAngle의 끝에서부터 빛이 감쇠되기 시작하여 SpotOuterAngle에 도달하면 빛의 강도는 0%가 됩니다."}]

[{"index":"string SpriteRUID (Sync)","0":"Sprite 타입의 광원이 그려낼 스프라이트의 RUID입니다."}]

[{"index":"boolean TargetAllSortingLayers (Sync)","0":"이 광원이 모든 SortingLayer에 영향을 줄지 설정합니다."}]

[{"index":"SyncList TargetSortingLayers (Sync)","0":"이 광원이 영향을 줄 SortingLayer를 선택합니다."}]

[{"index":"LightType Type (Sync)","0":"광원의 종류입니다. Spot, Freeform, Global, Sprite 네 가지 광원을 사용할 수 있습니다."}]

##### inherited from Component:

[{"index":"boolean Enable (Sync)","0":"컴포넌트 활성화 여부를 확인합니다."}]

[{"index":"boolean EnableInHierarchy (ReadOnly) (HideFromInspector)","0":"계층 구조상에서 이 컴포넌트가 Enable 상태인지를 반환합니다. Enable이 true일지라도 엔티티의 Enable이 false라면 false를 반환합니다."}]

[{"index":"Entity Entity (ReadOnly)","0":"이 컴포넌트를 소유한 엔티티입니다."}]

# Methods

##### inherited from Component:

[{"index":"boolean IsClient()","0":"현재 실행 환경이 클라이언트인지 아닌지의 여부를 반환합니다."}]

[{"index":"boolean IsServer()","0":"현재 실행 환경이 서버인지 아닌지의 여부를 반환합니다."}]
화면에 Grayscale 효과 적용하기

이 게시글은 기존 정보에 기반해 크리에이터에게 유용하도록 AI가 재구성한 내용입니다.

# 화면에 Grayscale 효과 적용하기

> 화면에 Grayscale 효과를 적용하는 방법을 단계별로 설명하여, 사용자에게 시각적으로 차별화된 경험을 제공하는 방법을 안내합니다.

## Grayscale 효과의 개념

Grayscale 효과는 화면의 색상을 흑백으로 변환하여 독특한 시각적 경험을 제공합니다. 이러한 효과는 게임, 애플리케이션 등에서 분위기를 조성하거나 특정 시각적 강조를 위해 사용됩니다. Grayscale 효과를 적용하기 위해서는 `CameraComponent`의 `ChangeMaterial` 메서드를 활용하여 `Material`을 교체하는 방법을 사용할 수 있습니다.

## Grayscale 효과의 필요성과 사용 사례

Grayscale 효과는 다음과 같은 상황에서 유용하게 사용됩니다:

  * 게임에서 특정 이벤트 발생 시 시각적 강조를 주기 위해
  * 애플리케이션에서 사용자 인터페이스의 일관성을 유지하면서도 특별한 변화를 주고자 할 때
  * 영화나 비디오에서 특정 장면의 감정적 강조를 위해



이러한 효과는 사용자 경험을 강화하고, 콘텐츠의 몰입도를 높이는 데 기여합니다.

## Grayscale 효과 적용 절차

Grayscale 효과를 화면에 적용하는 구체적인 방법을 단계별로 설명합니다.

### 1\. 머티리얼 생성

Workspace에서 새로운 `Material`을 생성하고, 이름을 지정합니다. 이때, `Shader` 타입을 Grayscale로 설정하여 Grayscale 효과를 적용할 준비를 합니다.

### 2\. CameraComponent 활용

현재 적용 중인 `CameraComponent`를 가져와서 Grayscale 머티리얼을 적용하는 것이 핵심입니다. 이를 위해 `CameraService`의 `GetCurrentCameraComponent` 메서드를 사용합니다.
    
    
    local cameraComponent = _CameraService:GetCurrentCameraComponent()
    cameraComponent:ChangeMaterial('생성한 머티리얼의 EntryID')
    

### 3\. 화면 전환 설정

`CameraService`의 기능을 사용하여 카메라 전환 시 Grayscale 효과가 지속되도록 설정합니다. `TransitionBlendTime`과 `TransitionBlendType` 프로퍼티를 조정하여 전환 효과를 부드럽게 만듭니다.

### 4\. 테스트 및 최적화

화면에 Grayscale 효과가 제대로 적용되었는지 테스트합니다. 필요에 따라 `ZoomRatio`, `Damping` 등의 `CameraComponent` 프로퍼티를 조정하여 최적화된 화면 연출을 보장합니다.

### 5\. 사용자 경험 개선

`UI 에디터`를 사용하여 Grayscale 효과와 조화를 이루는 UI 디자인을 추가합니다. 사용자 피드백을 반영하여 Grayscale 효과의 강도나 적용 범위를 조정할 수 있도록 옵션을 제공합니다.

## 잠재적 문제 및 해결책

Grayscale 효과 적용 시 다음과 같은 문제를 고려해야 합니다:

  * 성능 저하: Grayscale 효과는 추가적인 그래픽 연산을 요구할 수 있으므로, 성능 최적화가 필요합니다.
  * 사용자 혼란: Grayscale 효과가 지속적으로 적용되면 사용자가 혼란스러워할 수 있으므로, 명확한 사용 목적과 타이밍을 설정합니다.



각 문제는 `CameraComponent`와 `CameraService`의 적절한 프로퍼티 및 메서드를 활용하여 해결할 수 있습니다.

## 결론 및 추가 자료

Grayscale 효과는 사용자에게 독특한 시각적 경험을 제공할 수 있는 강력한 도구입니다. 이를 효과적으로 활용하기 위해서는 `CameraComponent`와 `CameraService`를 적절히 활용하는 것이 중요합니다.

추가 학습을 위해 다음의 링크를 참고하세요:

  * 
  *
게임 시작 위치 설정

# 학습 과정 소개

플레이어 아바타의 등장 위치 설정 방법을 소개합니다. 게임 시작 위치, 재등장(리스폰), 게임 제작 중 테스트 위치 설정에 대해 알아보겠습니다.

# 플레이어 아바타의 기본 위치

플레이어 아바타의 기본 위치는 화면 중간입니다. X, Y 좌표상 X값 0, Y값 0인 위치입니다. 기본적으로 게임 시작과 리스폰 위치가 이 설정을 따릅니다. 플레이어 아바타의 기본 위치는 [png](16346008379922a9b756c3912461db7195808cb554abd) DefaultPlayer의 TransformComponent에서 확인할 수 있습니다. [png](163515895824953612927a52740079e54f5fff52a4db3)

# SpawnLocation을 이용한 시작 위치 설정

배치한 맵이 시작 맵이라면, 배치한 'SpawnLocation' 위치에 플레이어 아바타가 처음 등장하게 됩니다. 타 맵에 배치한 'SpawnLocation'은 맵에 진입했을 때 혹은 리스폰 위치로 이용할 수 있습니다.

  1. Preset List에서Special Model을 클릭합니다.
  2. SpawnLocation 모델을 [png](163452458863504f49c7a23aa4a41af56b5b4611a6daf)Scene에 배치합니다.  
[png](1656036546711155b8385c0fb4001bda8ec16387d412e)



# 플레이 중 리스폰 위치

'SpawnLocation'은 맵마다 필요한 만큼 배치할 수 있습니다. 여러 'SpawnLocation'이 한 맵에 있으면 'SpawnLocation'과 플레이어 아바타 사이의 거리가 재등장 위치 선택 기준이 됩니다. 아래와 같이 플레이어 아바타가 두 개의 스폰 로케이션 사이에서 죽었을 경우, 아바타의 진행 방향이 왼쪽이라 할지라도 오른쪽의 'SpawnLocation'이 더 가깝기에 오른쪽에서 재등장하게 됩니다. [png](1634957591109e98512448cae4044ae9a75e96b22221a) 'SpawnLocation'을 적절히 배치한다면 게임 중간의 체크포인트처럼 이용할 수 있습니다. 게임을 처음부터 다시 하지 않아도 되기 때문에 유저가 다시 도전할 수 있는 동기가 될 것입니다.

# 테스트 시작 위치 설정

게임 제작 중 특정 구간을 반복 확인하고 싶을 때가 있습니다. 이때 처음부터 테스트를 진행하는 것보다 원하는 위치에서 시작해 일정 구간을 테스트 하는 것이 훨씬 효율적입니다. [png](1634538307569eec2919eb0d84163aa7be63651bd165d) 여기서 시작을 이용해 테스트 시작 위치를 설정할 수 있습니다.

  1. [png](163452458863504f49c7a23aa4a41af56b5b4611a6daf)Scene 탭 아래에 위치한 [png](1634538307569eec2919eb0d84163aa7be63651bd165d) 여기서 시작 버튼을 선택합니다.   
[png](17617248549680bd501dfcee840dbb7eb05c1fed935eb)
  2. 테스트를 시작하고 싶은 위치(타일 혹은 발판 위)로 움직여 배치합니다.  
[png](1740551251453a53f6916f5d6499e86c8c453f7304fdc)
  3. 시작[png](163453086660754178e0ff96a45c58d1a580a4dfab9d1)을 눌러 테스트를 시작합니다.
  4. 설정한 곳에서 플레이어 아바타가 등장합니다.



> Tip. 이미 배치한 SpawnLocation이 있더라도, 테스트 시에는 배치한 '여기서 시작' 위치가 우선입니다.

> Tip. 맵에 발판/타일을 배치하지 않고 시작 위치를 지정하게 되면, 테스트가 시작될 때 캐릭터가 임의로 화면 중앙에 배치됩니다. 의도한 곳에 캐릭터가 나타나길 원한다면 캐릭터가 설 수 있는 발판 영역 위에 두어야 합니다.

##### 참고 가이드

[캐릭터 초기 속성 편집](/docs?postId=48)
얼굴이 보이는 탈

# 학습 과정 소개

얼굴이 보이는 탈 시트를 소개합니다. [아바타 아이템 제작의 기본 개념](/docs?postId=588%7B%22target%22:%22_self%22%7D)을 참고해 아바타의 기본 개념을 먼저 숙지하길 바랍니다.

# 사전 준비

아이템 제작을 위해선 Adobe Photoshop이 필요합니다. 해당 소프트웨어를 설치한 후 아래 파일을 받아 엽니다. $$attachFile {"name":"Avatar_Cap_F.psd","url":"https://mod-file.dn.nexoncdn.co.kr/storage/Avatar_psd/version4_230221/Avatar_Cap_F.psd"} $$

> Tip. 모자는 아바타 발을 기준으로 최대 120x120 안에서 제작을 권장합니다. [png](16769485559327fc72cf03aca4128998b423540c3e049)

# 제작 시트 설명

모자 제작 시트는 회색, 빨간색, 노란색 레이어로 구분되어 있습니다. 회색 레이어는 이미지를 데이터화하기 위한 data 폴더, 이미지 제작에 도움을 줄 아바타 body 레이어, 가이드용 선 레이어가 있습니다. 회색 레이어는 모두 잠겨있고, 작업 중에 수정은 필요하지 않습니다. 노란색 레이어는 크리에이터가 실제 아이템을 그릴 수 있는 곳입니다. 빨간색 레이어는 모자와 헤어의 우선순위를 결정하는 역할을 합니다.

> Tip. 모든 레이어의 이름을 수정하거나 삭제할 경우 아이템을 제작할 수 없습니다. 절대 이름을 변경하지 마세요.

### 회색 레이어/빨간색 레이어

  1. data 폴더: data 폴더는 아이템을 데이터화하기 위해 필요한 폴더입니다. 이미지 제작에는 영향을 주지 않습니다. 
     * data:origin: 빨간색 점으로 데이터의 중심을 표시합니다.
     * data:type:Cap: 어떤 종류의 데이터인지 알 수 있습니다.
     * data:use_zmap_preset1: 아바타를 구성하는 이미지는 층층이 쌓여 만들어집니다. 아바타의 다양한 몸동작을 만들기 위해 몸을 바탕으로 옷, 방패, 무기 순으로 이미지가 층층이 위에 쌓이는 구조입니다.  
아이템에 따라 분리된 각 Sprite의 높이가 순서대로 정리된 파일이 zmap입니다.
  2. guide_ 레이어: 아바타의 샘플 body입니다. 레이어 이름 뒤에 붙은 숫자가 클수록 아래에 배치되는 내부적인 규칙입니다.  

  3. (빨간색 레이어) data:vslot:CpH1H2H3H4H5H6HfHsHbHcAe : 빨간색 레이어는 모자에만 있는 개념입니다. 모자 제작 파일에서의 vslot 레이어는 머리카락과 모자가 겹칠 경우 보이는 우선순위를 결정하는 역할을 합니다. [png](16770339977519ce67c0abb134ff4b6e40e636da925d6)



### 노란색 레이어

노란색 레이어에 크리에이터가 제작할 얼굴이 보이는 탈을 그릴 수 있습니다.

  1. case1.front: 얼굴이 보이는 탈의 앞모습을 그릴 레이어와 앞모습의 일반 헤어와 눌린 헤어 샘플이 포함되어 있습니다. 
     * edithere:cap_cap_34: 얼굴이 보이는 탈의 앞모습을 그릴 수 있는 레이어입니다.
  2. case2.back: 얼굴이 보이는 탈의 뒷모습을 그릴 레이어와 뒷모습의 일반 헤어와 눌린 헤어 샘플이 포함되어 있습니다. 
     * edithere:cap_backCap_92: 얼굴이 보이는 탈의 뒷모습을 그릴 수 있는 레이어입니다. [png](1677034011337213501bd84684eeebd56d177670563f1)
Regex

정규식으로 문자열을 검색하고 치환할 수 있습니다. 정규식은 제한 시간이 있으므로 일정 시간 안에 완료하지 않으면 실패합니다.

# Properties

[{"index":"boolean IsRightToLeft (ReadOnly)","0":"정규식 매치 방향이 오른쪽에서 왼쪽인지를 확인합니다."}]

# Constructors

[{"index":"Regex(string pattern)","0":"기본값으로 Regex를 초기화합니다."}]

[{"index":"Regex(string pattern, RegexOption options)","0":"지정한 pattern, options 값으로 Regex를 초기화합니다."}]

# Methods

[{"index":"table GetGroupNames()","0":"정규식에 대한 그룹 이름들을 반환합니다."}]

[{"index":"table GetGroupNumbers()","0":"정규식에 대한 그룹 번호들을 반환합니다."}]

[{"index":"string GroupNameFromNumber(int32 number)","0":"그룹 번호가 number인 그룹의 이름을 가져옵니다. 일치하는 항목이 없는 경우 nil을 반환합니다."}]

[{"index":"int32 GroupNumberFromName(string name)","0":"그룹 이름이 name인 그룹의 번호를 가져옵니다. 일치하는 항목이 없는 경우 -1을 반환합니다."}]

[{"index":"boolean IsMatch(string origin)","0":"origin 문장에서 정규식 패턴과 일치하는 항목이 있는지 확인합니다."}]

[{"index":"boolean IsMatch(string origin, int32 startIndex)","0":"origin 문장의 startIndex부터 정규식 패턴과 일치하는 항목이 있는지 확인합니다."}]

[{"index":"RegexMatch Match(string origin)","0":"origin 문장에서 정규식 패턴과 일치하는 첫 번째 항목을 검색합니다. 실패 시 nil을 반환합니다."}]

[{"index":"RegexMatch Match(string origin, int32 startIndex)","0":"origin 문장에서 startIndex부터 정규식 패턴과 일치하는 첫 번째 항목을 검색합니다. 실패 시 nil이 반환됩니다."}]

[{"index":"RegexMatch Match(string origin, int32 startIndex, int32 length)","0":"origin 문장에서 startIndex부터 지정된 길이의 문자열 내에서 정규식 패턴에 일치하는 첫 번째 항목을 검색합니다. 정규식 실패 시 nil이 반환됩니다."}]

[{"index":"table Matches(string origin)","0":"origin 문장에서 정규식 패턴과 일치하는 모든 항목을 검색합니다."}]

[{"index":"table Matches(string origin, int32 startIndex)","0":"origin 문장의 startIndex부터 정규식 패턴과 일치하는 모든 항목을 검색합니다."}]

[{"index":"string Replace(string origin, string replacement)","0":"origin 문장에서 정규식 패턴과 일치하는 모든 항목을 replacement으로 변경합니다. 실패 시 nil을 반환합니다."}]

[{"index":"string Replace(string origin, string replacement, int32 count)","0":"origin 문장에서 정규식 패턴과 일치하는 항목을 지정된 개수까지 replacement 으로 변경합니다. 실패 시 nil을 반환합니다."}]

[{"index":"string Replace(string origin, string replacement, int32 count, int32 startIndex)","0":"origin 문장에서 startIndex부터 정규식 패턴과 일치하는 항목을 찾습니다. 찾은 항목을 지정된 개수까지 replacement으로 변경합니다. 실패 시 nil을 반환합니다."}]

[{"index":"string ReplaceByEvaluator(string origin, func -> string evaluator)","0":"origin 문장에서 정규식 패턴과 일치하는 모든 항목을 evaluator로 반환된 문자열로 변경합니다. 실패 시 nil을 반환합니다."}]

[{"index":"string ReplaceByEvaluator(string origin, func -> string evaluator, int32 count)","0":"origin 문장에서 정규식 패턴과 일치하는 항목을 지정된 개수까지 evaluator로 반환된 문자열로 변경합니다. 실패 시 nil을 반환합니다."}]

[{"index":"string ReplaceByEvaluator(string origin, func -> string evaluator, int32 count, int32 startIndex)","0":"origin 문장의 startIndex부터 정규식 패턴과 일치하는 항목을 지정된 개수까지 evaluator로 반환된 문자열로 변경합니다. 실패 시 nil을 반환합니다."}]

[{"index":"table Split(string origin)","0":"origin 문장에서 정규식 패턴에 일치하는 항목을 기준으로 문자열을 분할합니다. 실패 시 nil을 반환합니다."}]

[{"index":"table Split(string origin, int32 count)","0":"origin 문장에서 정규식 패턴과 일치하는 항목을 기준으로 문자열을 분할합니다. 지정된 개수까지만 분할합니다. 실패 시 nil을 반환합니다."}]

[{"index":"table Split(string origin, int32 count, int32 startIndex)","0":"origin 문장의 startIndex부터 정규식 패턴과 일치하는 항목을 기준으로 문자열을 분할합니다. 지정된 개수까지만 분할합니다. 실패 시 nil을 반환합니다."}]

# SeeAlso

  * [정규식](/docs?postId=1041)
  * [정규식 언어](/docs?postId=1043)
Play

# 학습 과정 소개

제작한 월드를 테스트할 수 있는 Play 창에 대해 알아봅시다.

#### 참고 가이드

  * [Scene](/docs/?postId=1152%7B%22target%22:%22_blank%22%7D)
  * [Workspace](/docs/?postId=121%7B%22target%22:%22_blank%22%7D)
  * [Hierarchy](/docs/?postId=453%7B%22target%22:%22_blank%22%7D)
  * [프로퍼티 에디터](/docs/?postId=1087%7B%22target%22:%22_blank%22%7D)
  * [UI 에디터 활용과 제어](/docs/?postId=120%7B%22target%22:%22_blank%22%7D)



# Play

Play 창은 만든 월드를 테스트할 때 사용합니다. [시작] 버튼을 눌러 플레이 테스트를 실행했을 때만 활성화됩니다. 월드를 편집하는 Scene 창과 별개의 카메라로 동작하므로 테스트 시에 화면 이동이 동기화되지 않습니다. 하지만 Scene에서 클라이언트 부분을 변경하면, Play 창에도 반영됩니다. 테스트 플레이 전 테스트 화면비를 설정할 수 있으며, 테스트 중 가상의 클라이언트를 추가해 멀티 테스트를 진행할 수 있습니다.

#### Play의 기능

Play의 상태에 맞는 다양한 기능을 사용할 수 있습니다. 상단에 아이콘이 노출됩니다.

[png](17370970458165d802f305fde434d9020a4eac96ab265)

[{"아이콘":"-","이름":"시뮬레이터","설명":"테스트 화면비를 설정할 수 있습니다. 기본값은 PC입니다. PC: FHD 해상도(1920x1080)를 기준으로 동작합니다. 화면 비율은 16:9로 고정되어 있습니다.Mobile: 다양한 모바일 기기의 화면비로 Scene과 Play의 크기를 조정합니다. 테스트 시에도 화면비가 유지됩니다. Safe Area를 활성화할 수 있습니다.Free: 자유롭게 시뮬레이터의 화면비를 설정할 수 있습니다. Play의 창 크기를 기준으로 화면비가 결정됩니다."},{"아이콘":"-","이름":"테스트 플레이 언어","설명":"테스트할 언어를 지정할 수 있습니다. 테스트 중에는 언어 변경은 불가능합니다."},{"아이콘":"!","이름":"성능 통계","설명":"플레이 중인 월드의 FPS, 메모리 정보를 실시간으로 보여줍니다."},{"아이콘":"!","이름":"창 최대화","설명":"Play 창을 전체 화면으로 전환합니다. [축소] 버튼을 누르면 이전 크기로 돌아갑니다."}]

#### 테스트 시의 Play

테스트 시 Play 창에서 사용할 수 있는 기능이 변경됩니다. [png](1737452078994c0fb1a6973394aa4b20d64ba20768447)

[{"아이콘":"-","이름":"시뮬레이터","설명":"테스트 중인 화면비 정보를 나타냅니다."},{"아이콘":"-","이름":"테스트 플레이 언어","설명":"테스트 중인 언어 설정을 나타냅니다. 테스트 중에는 언어 변경은 불가능합니다."},{"아이콘":"!","이름":"성능 통계","설명":"플레이 중인 월드의 FPS, 메모리 정보를 실시간으로 보여줍니다."},{"아이콘":"!","이름":"창 최대화","설명":"Play 창을 전체 화면으로 전환합니다. [축소] 버튼을 누르면 이전 크기로 돌아갑니다."},{"아이콘":"!","이름":"가상의 플레이어 추가","설명":"테스트 시 활성화되며, 가상의 클라이언트를 여러개 띄울 수 있습니다."},{"아이콘":"-","이름":"가상의 플레이어 수","설명":"추가할 가상 플레이어 수를 설정해 여러 개의 클라이언트를 한꺼번에 열 수 있습니다. 최대 10개의 가상의 클라이어트를 열 수 있습니다. 테스트를 종료하면 모두 사라집니다."}]
얼굴을 가리는 탈

# 학습 과정 소개

얼굴을 가리는 탈 제작 시트를 소개합니다. [아바타 아이템 제작의 기본 개념](/docs?postId=588%7B%22target%22:%22_self%22%7D)을 참고해 아바타의 기본 개념을 먼저 숙지하길 바랍니다.

# 사전 준비

아이템 제작을 위해선 Adobe Photoshop이 필요합니다. 해당 소프트웨어를 설치한 후 아래 파일을 받아 엽니다. $$attachFile {"name":"Avatar_Cap_E.psd","url":"https://mod-file.dn.nexoncdn.co.kr/storage/Avatar_psd/version4_230221/Avatar_Cap_E.psd"} $$

> Tip. 모자는 아바타 발을 기준으로 최대 120x120 안에서 제작을 권장합니다. [png](16769485559327fc72cf03aca4128998b423540c3e049)

# 제작 시트 설명

모자 제작 시트는 회색, 빨간색, 노란색 레이어로 구분되어 있습니다. 회색 레이어는 이미지를 데이터화하기 위한 data 폴더, 이미지 제작에 도움을 줄 아바타 body 레이어, 가이드용 선 레이어가 있습니다. 회색 레이어는 모두 잠겨있고, 작업 중에 수정은 필요하지 않습니다. 노란색 레이어는 크리에이터가 실제 아이템을 그릴 수 있는 곳입니다. 빨간색 레이어는 모자와 헤어의 우선순위를 결정하는 역할을 합니다.

> Tip. 모든 레이어의 이름을 수정하거나 삭제할 경우 아이템을 제작할 수 없습니다. 절대 이름을 변경하지 마세요.

### 회색 레이어/빨간색 레이어

  1. data 폴더: data 폴더는 아이템을 데이터화하기 위해 필요한 폴더입니다. 이미지 제작에는 영향을 주지 않습니다. 
     * data:origin: 빨간색 점으로 데이터의 중심을 표시합니다.
     * data:type:Cap: 어떤 종류의 데이터인지 알 수 있습니다.
     * data:use_zmap_preset1: 아바타를 구성하는 이미지는 층층이 쌓여 만들어집니다. 아바타의 다양한 몸동작을 만들기 위해 몸을 바탕으로 옷, 방패, 무기 순으로 이미지가 층층이 위에 쌓이는 구조입니다.  
아이템에 따라 분리된 각 Sprite의 높이가 순서대로 정리된 파일이 zmap입니다.
  2. guide_ 레이어: 아바타의 샘플 body입니다. 레이어 이름 뒤에 붙은 숫자가 클수록 아래에 배치되는 내부적인 규칙입니다.  

  3. (빨간색 레이어) data:vslot:CpH1H2H3H4H5H6HfHsHbHcAfAyAsAe : 빨간색 레이어는 모자에만 있는 개념입니다. 모자 제작 파일에서의 vslot 레이어는 머리카락과 모자가 겹칠 경우 보이는 우선순위를 결정하는 역할을 합니다. [png](167703389960214c1a08396d74ffeba19e07a5787b1eb)



### 노란색 레이어

노란색 레이어에 크리에이터가 제작할 얼굴을 가리는 탈을 그릴 수 있습니다.

  1. case1.front: 얼굴을 가리는 탈의 앞모습을 그릴 레이어와 앞모습의 일반 헤어와 눌린 헤어 샘플이 포함되어 있습니다. 
     * edithere:cap_cap_34: 얼굴을 가리는 탈의 앞모습을 그릴 수 있는 레이어입니다.
  2. case2.back: 얼굴을 가리는 탈의 뒷모습을 그릴 레이어와 뒷모습의 일반 헤어와 눌린 헤어 샘플이 포함되어 있습니다. 
     * edithere:cap_backCap_92: 얼굴을 가리는 탈의 뒷모습을 그릴 수 있는 레이어입니다. [png](1724918527383e3a3141a069e42d7a212bfaec518a4be)
Vector4

4차원 벡터입니다.

# Properties

[{"index":"float w","0":"벡터의 w축 원소입니다."}]

[{"index":"float x","0":"벡터의 x축 원소입니다."}]

[{"index":"float y","0":"벡터의 y축 원소입니다."}]

[{"index":"float z","0":"벡터의 z축 원소입니다."}]

[{"index":"Vector4 negativeInfinity (Static) (ReadOnly) (HideFromInspector)","0":"Vector4(-inf, -inf, -inf, -inf)를 간단히 사용할 수 있습니다."}]

[{"index":"Vector4 one (Static) (ReadOnly) (HideFromInspector)","0":"Vector4(1, 1, 1, 1)을 간단히 사용할 수 있습니다."}]

[{"index":"Vector4 positiveInfinity (Static) (ReadOnly) (HideFromInspector)","0":"Vector4(inf, inf, inf, inf)를 간단히 사용할 수 있습니다."}]

[{"index":"Vector4 zero (Static) (ReadOnly) (HideFromInspector)","0":"Vector4(0, 0, 0, 0)을 간단히 사용할 수 있습니다."}]

# Constructors

[{"index":"Vector4(float x, float y, float z, float w)","0":"지정한 값으로 Vector4를 초기화합니다."}]

# Methods

[{"index":"Vector4 Clone()","0":"복사본을 생성합니다."}]

[{"index":"float Distance(Vector4 b)","0":"두 벡터 사이의 거리를 구합니다."}]

[{"index":"float Dot(Vector4 b)","0":"두 벡터의 내적을 구합니다."}]

[{"index":"Vector4 Lerp(Vector4 b, float t)","0":"두 벡터 사이를 t로 선형 보간한 Vector4 객체를 생성해 반환합니다. t는 0부터 1 사이로 고정됩니다."}]

[{"index":"Vector4 LerpUnclamped(Vector4 b, float t)","0":"두 벡터 사이를 t로 선형 보간한 Vector4 객체를 생성해 반환합니다."}]

[{"index":"float Magnitude()","0":"벡터의 크기를 구합니다."}]

[{"index":"Vector4 Normalize()","0":"방향이 같고 크기가 1인 Vector4 객체를 생성해 반환합니다."}]

[{"index":"Vector4 Project(Vector4 b)","0":"벡터를 b에 사영한 Vector4 객체를 생성해 반환합니다."}]

[{"index":"float SqrMagnitude()","0":"벡터 크기의 제곱을 구합니다."}]

[{"index":"float Distance(Vector4 a, Vector4 b) (Static)","0":"두 벡터 사이의 거리를 구합니다."}]

[{"index":"float Dot(Vector4 a, Vector4 b) (Static)","0":"두 벡터의 내적을 구합니다."}]

[{"index":"Vector4 Lerp(Vector4 a, Vector4 b, float t) (Static)","0":"두 벡터 사이를 t로 선형 보간한 Vector4 객체를 생성해 반환합니다. t는 0부터 1 사이로 고정됩니다."}]

[{"index":"Vector4 LerpUnclamped(Vector4 a, Vector4 b, float t) (Static)","0":"두 벡터 사이를 t로 선형 보간한 Vector4 객체를 생성해 반환합니다."}]

[{"index":"float Magnitude(Vector4 a) (Static)","0":"벡터의 크기를 구합니다."}]

[{"index":"Vector4 Normalize(Vector4 a) (Static)","0":"방향이 같고 크기가 1인 Vector4 객체를 생성해 반환합니다."}]

[{"index":"Vector4 Project(Vector4 a, Vector4 b) (Static)","0":"a를 b에 사영한 Vector4 객체를 생성해 반환합니다."}]

[{"index":"float SqrMagnitude(Vector4 a) (Static)","0":"벡터 크기의 제곱을 구합니다."}]

# Operators

[{"index":"Vector4 Addition(Vector4 left, Vector4 right) (Static)","0":"두 벡터를 더한 Vector4 객체를 생성해 반환합니다."}]

[{"index":"Vector4 Division(Vector4 left, float right) (Static)","0":"벡터를 실수로 나눈 Vector4 객체를 생성해 반환합니다."}]

[{"index":"boolean Equality(Vector4 left, Vector4 right) (Static)","0":"두 벡터가 같은지 비교합니다. 같으면 true, 그렇지 않으면 false를 반환합니다."}]

[{"index":"boolean Inequality(Vector4 left, Vector4 right) (Static)","0":"두 벡터가 다른지 비교합니다. 같으면 false, 그렇지 않으면 true를 반환합니다."}]

[{"index":"Vector4 Multiply(float left, Vector4 right) (Static)","0":"벡터를 실수배 한 Vector4 객체를 생성해 반환합니다."}]

[{"index":"Vector4 Multiply(Vector4 left, float right) (Static)","0":"벡터를 실수배 한 Vector4 객체를 생성해 반환합니다."}]

[{"index":"Vector4 Subtraction(Vector4 left, Vector4 right) (Static)","0":"두 벡터를 뺀 Vector4 객체를 생성해 반환합니다."}]

[{"index":"Vector4 UnaryNegation(Vector4 value) (Static)","0":"역벡터를 나타내는 Vector4 객체를 생성해 반환합니다."}]