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

엔티티의 자식으로 스폰될 Freeform 타입의 광원 정보입니다.

# Properties

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

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

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

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

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

[{"index":"float Lifetime","0":"광원이 표시될 시간입니다. 적혀있는 시간을 경과하면 생성되었던 광원이 자동으로 사라집니다. 단, 0 이하의 값을 입력할 경우에는 아무리 시간이 지나도 사라지지 않습니다."}]

[{"index":"int32 LightOrder","0":"광원이 라이트 텍스처에 렌더링되는 순서를 결정합니다. 낮은 수의 광원이 먼저 렌더링되고, 높은 수의 광원이 그 위에 렌더링됩니다. OverlapOperation이 AlphaBlend일 때 동작합니다. 예외적으로 Global 타입 광원은 LightOrder를 갖지 않습니다."}]

[{"index":"Vector3 LocalPosition","0":"광원이 위치할 부모 엔티티 공간 상의 좌표입니다."}]

[{"index":"Vector3 LocalScale","0":"광원에 적용될 부모 엔티티 공간 상의 스케일입니다."}]

[{"index":"float LocalZRotation","0":"광원에 적용될 부모 엔티티 공간 상의 Z축 기준 회전값입니다."}]

[{"index":"OverlayLightOverlapOperation OverlapOperation","0":"광원의 연산 방식입니다. Global 타입 광원은 OverlapOperation을 갖지 않습니다."}]

[{"index":"Entity ParentEntity","0":"생성된 광원이 추가될 엔티티입니다."}]

# Constructors

[{"index":"AttachedFreeformTypeOverlayLightInfo(Entity parentEntity)","0":"지정한 값으로 AttachedFreeformTypeOverlayLightInfo를 초기화합니다."}]

[{"index":"AttachedFreeformTypeOverlayLightInfo(Entity parentEntity, float lifetime, Vector3 localPosition, float localZRotation, Vector3 localScale, Color color, float intensity, OverlayLightOverlapOperation overlapOperation, int32 lightOrder, List freeformPoints, float falloffDistance, float falloffIntensity)","0":"지정한 값으로 AttachedFreeformTypeOverlayLightInfo를 초기화합니다."}]
ScreenMessageLogic

화면에 알림 메시지를 띄우는 기능을 제공합니다.

# Methods

[{"index":"void PrivateMsg(string msg) (ClientOnly)","0":"화면에 일시적으로 알림 메시지를 띄웁니다."}]

[{"index":"void PublicMsg(string msg) (Client)","0":"모든 클라이언트에게 일시적으로 알림 메시지를 띄웁니다."}]

[{"index":"void PublicMsg(string msg, Entity messageOwnerEntity = nil) (Client)","0":"모든 클라이언트에게 일시적으로 알림 메시지를 띄웁니다."}]

[{"index":"void PublicMsg(string msg, string targetUserId = nil) (Client)","0":"모든 클라이언트에게 일시적으로 알림 메시지를 띄웁니다."}]

##### inherited from Logic:

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

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

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

# Examples

#### PublicMsg

유저가 입장할 때 모든 유저의 화면에 메시지를 띄우는 예제입니다.
    
    
    @Component
    script UserEnterAnnouncer extends Component
        @ExecSpace("ServerOnly")
        @EventSender("Service", "UserService")
        handler HandleUserEnterEvent(UserEnterEvent event)
        -- Parameters
        local UserId = event.UserId
        --------------------------------------------------------
    
        local userEntity = _UserService:GetUserEntityByUserId(UserId)
        local userName = userEntity.NameTagComponent.Name
    
        _ScreenMessageLogic:PublicMsg(userName .. " has entered")
        end
    end
    

#### PrivateMsg

캐릭터가 사망한 이의 화면에만 메시지를 띄우는 예제입니다.
    
    
    @Component
    script DeathScreenNotifier extends Component
        @ExecSpace("ClientOnly")
        @EventSender("Self")
        handler HandleDeadEvent(DeadEvent event)
        -- Parameters
        --------------------------------------------------------
    
        if _UserService.LocalPlayer ~= self.Entity then
        	return
        end
    
        _ScreenMessageLogic:PrivateMsg("YOU DIED")
        end
    end
    

# SeeAlso

  * NameTagComponent
  * DeadEvent
  * UserEnterEvent
  * UserService
AI 스킬 셋 설치

## 사전 준비

AI 스킬 셋을 사용하려면 몇 가지 사전 준비가 필요합니다.

  * 크리에이터의 월드가 LocalWorkspace, ExtendedScriptFormat을 모두 활성화한 상태여야 합니다.
  * , ,  등 크리에이터가 사용할 AI 에이전트가 설치, 구독된 상태여야 합니다.
  * macOS의 경우 Apple Silicon(arm64), Intel(x86_64)에 맞는 메이플스토리 월드 클라이언트가 설치되어야 합니다. macOS 최초 실행 시 Gatekeeper가 미서명 / 외부 다운로드 바이너리 실행을 차단할 수 있는데, 이 경우 시스템 설정 > 개인정보 보호 및 보안에서 해당 항목의 실행을 명시적으로 허용합니다.



##### 참고 가이드

  * [LocalWorkspace](docs/?postId=1165)
  * [AI ToolKit](/docs?postId=1374%7B%22target%22:%22_blank%22%7D)
  * 



### Node.js 설치

AI 스킬 셋을 사용하기 위해서는 [Node.js](https://nodejs.org%7B%22target%22:%22_blank%22%7D)가 반드시 설치되어야 합니다. 크리에이터의 OS 환경에 맞는 방법으로 Node.js를 미리 설치해야 합니다. Windows의 경우 AI 스킬 셋을 연결할 때 Node.js가 자동으로 설치됩니다. macOS의 경우 크리에이터가 직접 다운로드해 설치하거나, `brew install node` 명령어를 사용해 설치해야 합니다.

> 더 알아보기 Windows에서 자동 설치가 되지 않는 경우 `winget install OpenJS.NodeJS.LTS` 명령어를 사용하여 수동으로 설치할 수 있습니다.

## AI 스킬 셋 설치

### 자동 설치

기본적으로 AI ToolKit Settings - AI 스킬 셋에서 [연결] 버튼을 누르면 자동으로 다운로드됩니다. 설치가 완료되면 연결 버튼이 [연결 완료]로 변경됩니다. [png](17794154980639e63d9751e8b4385a037fd2bbd9ad433)

### 수동 설치

AI 스킬 셋에서 [연결]을 눌렀지만 자동으로 설치되지 않거나, 크리에이터의 필요에 따라 직접 AI 스킬 셋을 다운로드 받을 수 있습니다. 수동 설치 시 `.gitignore`를 사용해 형상 관리 대상에서 제외해야 정상적으로 동작합니다.

  1. [msw-ai-coding-plugins-official](https://github.com/MSW-Git/msw-ai-coding-plugins-official%7B%22target%22:%22_blank%22%7D)를 크리에이터의 월드 로컬 워크스페이스로 `clone` 혹은 다운로드합니다.
  2. 월드 프로젝트의 `.gitignore`에 다운로드한 msw-ai-coding-plugins-official의 경로를 추가합니다.
  3. MCP를 재시작하고, 설치가 완료되었는지 확인합니다.
MODTweenLogic

더는 사용하지 않는 Logic입니다. 용도에 맞게 TweenLogic, TweenLineComponent, TweenFloatingComponent, TweenCircularComponent를 사용하세요.

# Methods

[{"index":"float Ease(EaseType type, float from, float totalDelta, float time, float duration) (Deprecated) (Static)","0":"더는 사용하지 않는 함수입니다. TweenLogic의 Ease(float, float, float, EaseType, float) 함수를 사용하세요."}]

[{"index":"Component MoveTo(Entity entity, Vector2 dest, float time, EaseType ease = EaseType.Linear, boolean needSync = true) (Deprecated) (Static)","0":"더는 사용하지 않는 함수입니다. TweenLogic의 MoveTo(Entity, Vector2, float, EaseType) 함수 혹은 TweenLineComponent를 사용하세요."}]

[{"index":"Component MoveToOffset(Entity entity, Vector2 offset, float time, EaseType ease = EaseType.Linear, boolean needSync = true) (Deprecated) (Static)","0":"더는 사용하지 않는 함수입니다. TweenLogic의 MoveOffset(Entity, Vector2, float, EaseType) 함수 혹은 TweenLineComponent를 사용하세요."}]

[{"index":"Component StartFloating(Entity entity, float oneCycleTime, float amplitude, EaseType easeType = EaseType.SineEaseOut, boolean needSync = true) (Deprecated) (Static)","0":"더는 사용하지 않는 함수입니다. TweenFloatingComponent를 사용하세요."}]

[{"index":"Component StartRot(Entity entity, float radius, float speed, boolean lookAtCenter = false, boolean needSync = true) (Deprecated) (Static)","0":"더는 사용하지 않는 함수입니다. TweenLogic의 RotateTo(Entity, float, float, EaseType), RotateAroundOffset(Entity, float, Vector2, boolean, float, EaseType) 함수 혹은 TweenCircularComponent을 사용하세요."}]

[{"index":"void StopFloating(Component floatingComp, boolean reset = true) (Deprecated) (Static)","0":"더는 사용하지 않는 함수입니다. TweenFloatingComponent를 사용하세요."}]

[{"index":"void StopRot(Component rotComp, boolean reset = true) (Deprecated) (Static)","0":"더는 사용하지 않는 함수입니다. TweenLogic의 RotateTo(Entity, float, float, EaseType), RotateAroundOffset(Entity, float, Vector2, boolean, float, EaseType) 함수 혹은 TweenCircularComponent을 사용하세요."}]

##### inherited from Logic:

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

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

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

부드러운 화면 전환 효과 기능을 제공합니다.

# Methods

[{"index":"void DissolveScreen(float time, boolean includeUI, boolean isHighPriorityThanFadeInOut) (ClientOnly)","0":"Dissolve 효과를 실행합니다.time은 효과의 지속 시간을 설정합니다. 초 단위이며 0부터 3까지의 값만 설정할 수 있습니다.includeUI는 UI에 디졸브 효과를 적용할지 여부를 설정합니다.isHighPriorityThanFadeInOut이 ture라면 디졸브 효과 실행 중 Fade In\/Out 실행이 차단됩니다. false라면 디졸브 효과와 Fade In\/Out이 중첩되어 실행됩니다.Fade Out 시작 시, Fade In 시작 전에는 Dissolve를 시작할 수 없습니다."}]

[{"index":"void SetFadeInOutEnable(boolean isEnable) (ClientOnly)","0":"맵 이동 시 Fade In, Fade Out 효과 활성화 여부를 설정합니다."}]

[{"index":"void SetFadeInTime(float time) (ClientOnly)","0":"맵 이동 시 화면이 어두운 상태에서 밝아지기까지 걸리는 시간을 설정합니다. 초 단위이며, 기본값은 1입니다. 0부터 3까지의 값만 설정할 수 있습니다."}]

[{"index":"void SetFadeOutTime(float time) (ClientOnly)","0":"맵 이동 시 화면이 밝은 상태에서 어두워지기까지 걸리는 시간을 설정합니다. 초 단위이며, 기본값은 1입니다. 0부터 3까지의 값만 설정할 수 있습니다."}]

##### 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":"이벤트를 발생시킵니다."}]

# Events

[{"index":"FadeInEndEvent","0":"Fade In 효과가 완료될 때 발생하는 이벤트입니다. Fade In 효과가 중단된 경우 이 이벤트는 발생하지 않습니다."}]

[{"index":"FadeInStartEvent","0":"Fade In 효과가 시작될 때 발생하는 이벤트입니다."}]

[{"index":"FadeOutEndEvent","0":"Fade Out 효과가 완료될 때 발생하는 이벤트입니다."}]

[{"index":"FadeOutStartEvent","0":"Fade Out 효과가 시작될 때 발생하는 이벤트입니다."}]
Warning Level

($API_Metadata_Start)

[{"ID":"<\/a>LWA-1106","이름":"NotRecommendedAssignment","설명":"권장하지 않는 할당문을 작성했습니다."},{"ID":"<\/a>LWA-1109","이름":"IntroduceGlobalVariable","설명":"글로벌 변수를 선언했습니다."},{"ID":"<\/a>LWA-1110","이름":"DeprecatedAPIUsed","설명":"더는 사용하지 않는 API를 사용했습니다. 다른 API 사용을 권장합니다."},{"ID":"<\/a>LWA-1111","이름":"UnbalancedAssignment","설명":"할당문의 왼쪽과 오른쪽의 길이가 다릅니다."},{"ID":"<\/a>LWA-1112","이름":"UnreachableCode","설명":"도달할 수 없는 코드를 작성했습니다."},{"ID":"<\/a>LWA-1122","이름":"ReturnValueExpected","설명":"값을 반환하지 않는 함수를 식으로 사용했습니다."},{"ID":"<\/a>LWA-3008","이름":"AlreadyExist","설명":"이미 있는 상황입니다. 예를 들어 MapLayerName, Collider, ItemGUID, STATE 등이 존재할 때 해당 오류가 발생합니다."},{"ID":"<\/a>LWA-3009","이름":"InvalidValue","설명":"값이 유효하지 않습니다."},{"ID":"<\/a>LWA-3010","이름":"NotSupported","설명":"지원하지 않는 기능을 사용했습니다."},{"ID":"<\/a>LWA-3017","이름":"OutOfRange","설명":"값이 허용된 범위를 벗어났습니다."},{"ID":"<\/a>LWA-3019","이름":"NotRecommendedValue","설명":"권장하지 않는 값을 사용했습니다."},{"ID":"<\/a>LWA-3020","이름":"Obsolete","설명":"더는 사용하지 않는 기능을 사용했습니다."},{"ID":"<\/a>LWA-3026","이름":"DuplicateRequest","설명":"요청이 중복되었습니다."},{"ID":"<\/a>LWA-3029","이름":"FailedSetDefault","설명":"기본 값으로 설정하는데 실패했습니다."},{"ID":"<\/a>LWA-3047","이름":"UnableToChange","설명":"변경이 불가능한 값을 변경했습니다."},{"ID":"<\/a>LWA-3048","이름":"DuplicateComponent","설명":"같은 타입의 컴포넌트가 이미 존재합니다."},{"ID":"<\/a>LWA-3055","이름":"NotInitialized","설명":"초기화되지 않은 상황입니다."},{"ID":"<\/a>LWA-3057","이름":"InvalidOperation","설명":"함수 호출이 객체의 현재 상태에 유효하지 않습니다"},{"ID":"<\/a>LWA-4001","이름":"EntityComponentPropertyValueTypeMismatch","설명":"엔티티에서 컴포넌트 프로퍼티의 값이 올바르지 않습니다."},{"ID":"<\/a>LWA-4011","이름":"ModelPropertyValueTypeMismatch","설명":"모델에서 프로퍼티의 값이 올바르지 않습니다."},{"ID":"<\/a>LWA-4012","이름":"ModelComponentPropertyValueTypeMismatch","설명":"모델에서 컴포넌트 프로퍼티의 값이 올바르지 않습니다."},{"ID":"<\/a>LWA-4013","이름":"ModelDuplicateComponent","설명":"모델에 컴포넌트가 중복됩니다."}]
UserDataStorage에서 GetAsync와 BatchGetAsync 차이점 알아보기

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

# UserDataStorage에서 GetAsync와 BatchGetAsync 차이점 알아보기

> 이 글에서는 `UserDataStorage`의 `GetAsync`와 `BatchGetAsync` 함수의 차이점을 설명하고, 데이터 크레딧 소모에 대한 이해를 돕습니다.

## UserDataStorage의 이해

`UserDataStorage`는 각 사용자에게 고유한 데이터를 저장하고 불러오는 기능을 제공합니다. 이는 `사용자 ID`를 통해 접근할 수 있으며, 사용자별 데이터 관리가 가능합니다. `DefaultPlayer`에 이를 추가하여 사용자 데이터와 상호작용할 수 있습니다.

## GetAsync와 BatchGetAsync의 기능 차이

`GetAsync`와 `BatchGetAsync`는 모두 `UserDataStorage`에서 데이터를 조회하는 데 사용되는 함수입니다. 그러나 이 두 함수는 다음과 같은 차이가 있습니다:

  * GetAsync: 단일 `키`를 입력하여 비동기적으로 데이터를 조회합니다. 작업이 완료되면 콜백 함수가 호출되어 결과를 반환합니다.
        
        void GetAsync(string key, func callbackFunction)
        

  * BatchGetAsync: 여러 개의 `키`를 입력하여 비동기적으로 데이터를 조회합니다. 여러 요청을 일괄적으로 처리하여 효율성을 높이며, 각 요청의 성공 여부를 확인하여 오류 처리가 필요합니다.
        
        void BatchGetAsync(List keys, func, DataStorageItemPages> callbackFunction)
        




## DataStorage 사용 시 크레딧 소모량

`DataStorage`를 사용할 때는 데이터 크기에 따라 크레딧이 소모됩니다. 구체적으로는:

  * 크레딧 소모량: 0에서 4000바이트의 데이터에는 1 크레딧이 소모됩니다. 존재하지 않는 값을 조회해도 크레딧이 소모되므로 주의가 필요합니다.
  * 영향을 주지 않는 요소: `키`, `태그`, `버전`의 크기는 크레딧 소모에 영향을 미치지 않습니다.



## Batch 접두사의 중요성 및 활용 방안

`Batch` 접두사를 사용하면 다수의 데이터를 효율적으로 처리할 수 있습니다. 이는 데이터 저장, 불러오기, 제거 시 빠른 처리를 가능하게 합니다. 그러나 요청 중 일부만 성공할 수 있으므로, 성공하지 않은 작업에 대한 적절한 오류 처리가 필요합니다. 이를 통해 데이터의 일관성을 유지할 수 있습니다.

## 결론 및 추가 자료

이 글에서는 `UserDataStorage`의 `GetAsync`와 `BatchGetAsync`의 차이와 데이터 크레딧 소모에 대해 알아보았습니다. `Batch` 함수를 활용하면 효율적으로 데이터를 관리할 수 있으며, 크레딧 소모를 고려하여 데이터 접근을 최적화할 수 있습니다.

추가로 학습할 수 있는 자료는 다음과 같습니다:

  * 
  * 
  *
Tweener

트윈 동작을 나타냅니다.

# Properties

[{"index":"boolean AutoDestroy","0":"트윈이 완료된 후 자동 파괴 여부를 설정합니다."}]

[{"index":"int32 CurrentLoopCount (ReadOnly)","0":"트윈에 설정된 반복 재생 횟수 중 몇 번째 재생인지를 나타냅니다. 첫 번째 재생 시 값은 1입니다."}]

[{"index":"float Delay","0":"트윈의 총 재생 시간에서 재생 지연 시간을 설정합니다.길이가 5초인 Tweener에 Delay를 2초로 설정하면 3초 동안만 Tween을 재생합니다."}]

[{"index":"EaseType EaseType","0":"현재 Tweener의 운동 타입을 설정합니다."}]

[{"index":"boolean IsPlaying (ReadOnly)","0":"현재 Tweener가 재생 중인지 여부를 확인합니다."}]

[{"index":"int32 LoopCount","0":"트윈의 반복 재생 횟수를 정의합니다. -1인 경우 무한히 반복합니다."}]

[{"index":"TweenLoopType LoopType","0":"현재 Tweener의 반복 타입을 설정합니다.Restart: 트윈의 순차 재생만 반복합니다.PingPong: 트윈의 순차 재생과 역 재생을 반복합니다."}]

[{"index":"float ProgressRate (ReadOnly)","0":"현재 트윈의 재생 진행 상태를 나타냅니다. 0이 재생 시작이며 1이 재생 완료 상태를 의미합니다."}]

# Methods

[{"index":"void Complete()","0":"트윈을 즉시 완료합니다."}]

[{"index":"void Destroy()","0":"트윈을 파괴합니다."}]

[{"index":"void Pause()","0":"트윈을 일시정지합니다."}]

[{"index":"void Play()","0":"트윈을 재생합니다."}]

[{"index":"void Restart()","0":"트윈을 처음부터 재시작합니다."}]

[{"index":"void Resume()","0":"트윈을 재개합니다. 트윈이 시작하지 않았다면 Start()와 동일하게 작동합니다."}]

[{"index":"void Reverse()","0":"시작값과 종료값을 맞바꿉니다."}]

[{"index":"void Rewind()","0":"트윈을 초기 상태로 되돌립니다."}]

[{"index":"void SetAutoDestroy(boolean autoDestroy) (Deprecated)","0":"더는 사용하지 않는 함수입니다. AutoDestroy 프로퍼티를 사용하세요."}]

[{"index":"void SetDelay(float seconds) (Deprecated)","0":"더는 사용하지 않는 함수입니다. Delay 프로퍼티를 사용하세요."}]

[{"index":"void SetEaseType(EaseType type) (Deprecated)","0":"더는 사용하지 않는 함수입니다. EaseType 프로퍼티를 사용하세요."}]

[{"index":"void SetLoopCount(int32 loopCount) (Deprecated)","0":"더는 사용하지 않는 함수입니다. LoopCount 프로퍼티를 사용하세요."}]

[{"index":"void SetLoopType(TweenLoopType type) (Deprecated)","0":"더는 사용하지 않는 함수입니다. LoopType 프로퍼티를 사용하세요."}]

[{"index":"void SetOnEndCallback(func callback)","0":"트윈이 완료된 후 호출될 콜백 함수를 설정합니다."}]

[{"index":"void Stop()","0":"트윈을 중지합니다."}]
해상도 고정 및 변경 알아보기

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

# 해상도 고정 및 변경 알아보기

> 다양한 디바이스 환경에서 게임을 즐기기 위해 해상도 관련 UI 디자인의 중요성과 방법을 알아봅니다.

## 해상도 이해 및 관리의 중요성

해상도는 게임 플레이에 큰 영향을 미치는 요소입니다. 다양한 환경에서 게임을 즐기는 유저들이 불편함을 겪지 않도록 하기 위해, 제작자는 최소 해상도 1280 x 720 및 FHD 해상도 1920 x 1080을 기준으로 작업해야 합니다. 그러나 해상도를 강제로 고정하거나 변경할 수 있는 기능은 제공되지 않으며, 사용자는 창모드에서 해상도를 자유롭게 조절할 수 있습니다.

## UI 디자인 가이드라인

다양한 디바이스에 맞춘 UI 디자인은 필수적입니다. 모바일과 PC 환경에서 각각의 최적화된 UI를 만드는 것이 이상적이지만, 대부분의 경우 공용 UI를 제작하고 필수적인 부분만 기기별로 조정하는 것이 효율적입니다. 기본 UI를 가리지 않도록 UI를 배치하고, 터치 인터페이스를 고려하여 버튼 크기와 간격을 설정해야 합니다.

## 해상도 관련 API 활용하기

`UILogic` 구성 내에서 제공되는 `ScreenHeight` 및 `ScreenWidth` 프로퍼티를 사용하여 현재 화면의 크기를 확인할 수 있습니다. 또한, `ScreenToWorldPosition` 및 `WorldToScreenPosition` 메서드를 활용하면 화면 좌표와 월드 좌표 간의 변환이 가능합니다. 이는 UI 요소의 정확한 위치 조정에 유용합니다.

## UI 디자인의 일관성 유지

UI 디자인의 일관성은 사용자 경험을 향상시키는 데 중요한 역할을 합니다. 색상 팔레트, 아이콘, 텍스트 서식 등을 일관되게 사용하여 유저가 쉽게 인지하고 사용할 수 있도록 해야 합니다. UI 요소의 크기와 배치를 통해 사용자 경험을 더욱 향상시킬 수 있습니다.

## 최적화 및 테스트

UI 리소스를 `Resource Storage`에 최적화하여 등록하고, 필터 모드를 사용하여 이미지 품질을 관리할 수 있습니다. 다양한 해상도와 디바이스에서 UI의 가독성과 사용성을 테스트하여 최적의 사용자 경험을 제공해야 합니다.

## 결론 및 추가 자료

해상도와 UI 디자인의 중요성을 이해하고, 다양한 디바이스 환경에서 일관된 사용자 경험을 제공하기 위한 방법을 알아보았습니다. 더 많은 정보를 원하신다면 아래의 자료를 참고하시기 바랍니다.

  * 
  *
DistanceJointComponent

DistanceJoint를 생성, 삭제할 수 있습니다. 연결된 강체 간 거리를 일정하게 유지합니다.

# Properties

[{"index":"SyncList Joints (Sync) (ReadOnly)","0":"Joint 정보를 설정합니다."}]

##### 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

[{"index":"int32 AddJoint(Entity targetEntity, Vector2 localAnchorA, Vector2 localAnchorB, float length)","0":"DistanceJoint를 추가합니다. 성공 시 index, 실패 시 -1을 반환합니다"}]

[{"index":"void DestroyJoint(int32 index)","0":"순번이 index에 해당하는 Joint를 제거합니다."}]

[{"index":"int32 GetJointsCount()","0":"joint 수를 반환합니다."}]

[{"index":"void SetCollideConnected(int32 index, boolean collideConnected)","0":"순번이 index에 해당하는 Joint의 CollideConnected 값을 설정합니다."}]

[{"index":"void SetLength(int32 index, float length)","0":"순번이 index에 해당하는 Joint의 Length 값을 설정합니다."}]

[{"index":"void SetLocalAnchorA(int32 index, Vector2 localAnchorA)","0":"순번이 index에 해당하는 Joint의 LocalAnchorA 값을 설정합니다."}]

[{"index":"void SetLocalAnchorB(int32 index, Vector2 localAnchorB)","0":"순번이 index에 해당하는 Joint의 LocalAnchorB 값을 설정합니다."}]

##### inherited from Component:

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

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

# Examples

#### AddJoint

R을 눌러 Joint를 추가해 떨어지는 공을 잡는 예제입니다.
    
    
    @Component
    script BallRopeController extends Component
        @ExecSpace("ServerOnly")
        method void Connect()
        local ball = _EntityService:GetEntityByPath("/maps/map01/Ball")
    
        self.Entity.DistanceJointComponent:AddJoint(
        	ball,
        	Vector2.zero,
        	Vector2.zero,
        	Vector2.Distance(ball.TransformComponent.WorldPosition:ToVector2(), self.Entity.TransformComponent.WorldPosition:ToVector2())
        	)
    
        self.Entity.LineRendererComponent.Enable = true
        end
    
        @ExecSpace("ServerOnly")
        method void Disconnect()
        self.Entity.DistanceJointComponent.Joints:Clear()
    
        self.Entity.LineRendererComponent.Enable = false
        end
    
        @EventSender("Service", "InputService")
        handler HandleKeyDownEvent(KeyDownEvent event)
        --------------- Native Event Sender Info ----------------
        -- Sender: InputService
        -- Space: Client
        ---------------------------------------------------------
    
        -- Parameters
        local key = event.key
        ---------------------------------------------------------
        if key == KeyboardKey.R then
        	if self.Entity.DistanceJointComponent:GetJointsCount() == 0 then
        		self:Connect()
        	else
        		self:Disconnect()
        	end
        end
        end
    end
    

# SeeAlso

  * LineRendererComponent
  * TransformComponent
  * KeyDownEvent
  * EntityService
  * InputService
  * [다양한 물리 joint 활용하기](/docs?postId=760)
  * [물리 사용하기](/docs?postId=757)
  * [엔티티에 물리 적용하기 ](/docs?postId=761)
UI에서 Color 데이터를 사용하여 픽셀 단위로 Rendering 하는 법

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

# UI에서 Color 데이터를 사용하여 픽셀 단위로 Rendering 하는 법

> 이 아티클에서는 UI에서 `Color` 데이터를 활용하여 픽셀 단위로 효과적인 렌더링을 구현하는 방법을 설명합니다. PixelGUIRendererComponent를 활용하여 다양한 색상과 크기의 스프라이트를 다룰 수 있는 방법을 배워봅시다.

## PixelGUIRendererComponent 소개 및 설정

픽셀 단위의 렌더링을 구현하기 위해서는 `PixelGUIRendererComponent`를 사용하는 것이 가장 효과적입니다. 이 컴포넌트를 활용하면 원하는 색상을 지정하여 UI에 픽셀 단위로 스프라이트를 그릴 수 있습니다. UI 에디터에서 새로운 UI 그룹을 생성하고, `DefaultShow`를 `True`로 설정하여 UI가 보이도록 해야 합니다.

## PixelGUIRendererComponent 활용 예제

다음은 `PixelGUIRendererComponent`를 빈 UI에 적용하는 방법입니다. 먼저 UI 에디터에서 빈 UI를 생성하고, 여기에 `PixelGUIRendererComponent`를 추가합니다.
    
    
    Method:
    [client only]
    void OnBeginPlay()
    {
        self.Entity.PixelGUIRendererComponent:FillColor(Color.black)
    }
    

위 코드에서 `OnBeginPlay()` 메소드를 통해 실행 공간을 클라이언트 전용으로 설정하고 `FillColor` 메소드를 사용하여 스프라이트 전체의 색을 변경합니다.

## 픽셀 색상 조작 방법

픽셀의 색상을 조작하기 위해서는 `SetPixel` 및 `SetPixels` 메소드를 사용합니다. 특정 위치의 픽셀 색상을 변경하거나, 스프라이트 전체의 픽셀 색상을 일괄 변경할 수 있습니다. 또한, `GetPixel` 및 `GetPixels` 메소드를 사용하여 픽셀의 위치와 색상을 받아올 수 있습니다.

## 스프라이트 크기 및 색상 변경

`ResetWithColor` 및 `ResetWithColors` 메소드를 활용하여 스프라이트의 크기와 전체 색상을 변경할 수 있습니다. 다양한 크기의 스프라이트에 대해 색상을 재설정하는 방법을 통해 더욱 유연한 UI 디자인이 가능합니다.

## 이벤트 핸들러 및 최적화

이벤트 핸들러를 활용하여 UI 상호작용을 통해 픽셀 색상 변경을 트리거할 수 있습니다. 또한, 최적화 기법을 통해 렌더링 성능을 향상시킬 수 있습니다.

## 결론 및 추가 자료

픽셀 단위 렌더링은 UI 디자인의 세밀함을 높이는 데 매우 유용합니다. 이 아티클에서 설명한 방법들을 통해 다양한 색상과 디자인을 구현할 수 있습니다. 추가로 학습할 수 있는 자료는 다음 링크에서 확인할 수 있습니다:

  * 
  *
PortalComponent

포탈 기능을 제공합니다. 포탈의 충돌 속성을 설정하고 목적지 포탈을 연결할 수 있습니다.

# Properties

[{"index":"Vector2 BoxOffset (Sync)","0":"엔티티를 기준으로 충돌체 직사각형의 중심점 위치를 설정합니다."}]

[{"index":"Vector2 BoxSize (Sync)","0":"충돌체 직사각형의 너비와 높이를 지정합니다."}]

[{"index":"CollisionGroup CollisionGroup (ReadOnly) (HideFromInspector)","0":"Portal의 충돌 그룹입니다."}]

[{"index":"boolean IsLegacy (ReadOnly)","0":"이 컴포넌트가 이전의 시스템으로 동작할지를 설정합니다. 신규 시스템은 충돌체가 TransformComponent의 회전과 크기에 영향을 받습니다."}]

[{"index":"EntityRef PortalEntityRef","0":"목적지 포탈을 설정합니다. PortalComponent를 가진 엔티티만 목적지로 설정할 수 있습니다."}]

##### 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":"현재 실행 환경이 서버인지 아닌지의 여부를 반환합니다."}]

# Events

[{"index":"PortalUseEvent","0":"플레이어가 포탈을 이용할 때 발생하는 이벤트입니다."}]

# Examples

맵에 3개 이상의 포탈을 배치합니다. 포탈에 컴포넌트를 추가하면 1초마다 연결된 포탈이 무작위로 변경됩니다.
    
    
    @Component
    script RandomPortalConnector extends Component
        @ExecSpace("ClientOnly")
        method void OnBeginPlay()
        -- 현재 맵의 모든 Entity를 순회하며 PortalComponent를 가진 Entity들의 EntityRef 저장
        self._T.portalRefList = {}
        local function findAndAddPortal(parent)
        	-- 자기 자신은 제외
        	if parent.PortalComponent ~= nil and parent ~= self.Entity then
        		table.insert(self._T.portalRefList, EntityRef(parent))
        	end
        	if parent.Children ~= nil then
        		for i, k in ipairs(parent.Children) do
        			findAndAddPortal(k)
        		end
        	end
        	end
    
        findAndAddPortal(self.Entity.CurrentMap)
    
        -- 자신 외에 포탈이 없다면 Return
        if #self._T.portalRefList < 1 then
        	return
        end
    
        -- 1초마다 연결된 포탈을 랜덤하게 변경하는 타이머 설정
        _TimerService:SetTimerRepeat(function()
        	self.Entity.PortalComponent.PortalEntityRef = self._T.portalRefList[_UtilLogic:RandomIntegerRange(1, #self._T.portalRefList)]
        end, 1)
        end
    end
    

# SeeAlso

  * math
  * table
  * TimerService
  * [다른 위치로 이동하는 포탈 만들기](/docs?postId=90)