[task] | instruction_following [pass] | ⏳ 미판정 [title] | 맵 생성과 관리 [question] | 포탈 연결 설정 3단계를 단계별 번호 목록으로 나열하세요. [answer] | 포탈 연결 설정은 다음 3단계로 진행합니다. 1. 연결하려는 맵에 포탈을 설치합니다. 2. 포탈의 프로퍼티 에디터에서 **TargetPortal**의 **[◉]** 버튼을 클릭한 뒤, **Reference** 팝업 창에서 이동할 포탈을 선택합니다. 3. **[시작]** 버튼을 클릭한 뒤, 출발 포탈에서 도착 포탈로 잘 이동하는지 확인합니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 1. 연결하려는 맵에 포탈을 설치합니다. 2. 포탈의 프로퍼티 에디터에서 **TargetPortal**의 **[◉]** 버튼을 클릭합니다. 이후 **Reference** 팝업 창에서 이동할 포탈을 선택합니다. 3. **[시작]** 버튼을 클릭한 뒤, 출발 포탈에서 도착 포탈로 잘 이동하는지 확인합니다. # 마무리 좋은 맵의 크기와 개수는 정해진 답이 없습니다. 크리에이터의 기획에 맞게 여러 개의 맵을 만들거나, 하나의 커다란 맵을 만들어도 좋습니다. 그러나 맵이 너무 거대하거나 배치된 오브젝트가 많으면 로딩 및 플
[task] | code [pass] | ⏳ 미판정 [title] | 유저 엔티티를 찾아주는 UserService [question] | UserService.Users를 이용해 새 유저가 입장할 때 전체 유저 수와 각 유저의 UserId, Nickname, ProfileCode 정보를 문자열로 조합하여 로그로 출력하는 스크립트를 작성해줘. [answer] | UserService의 `Users` 프로퍼티는 게임에 참여 중인 모든 유저의 `UserId`, `Nickname`, `ProfileCode` 정보를 제공합니다. 이를 이용하여 새 유저가 입장할 때 전체 유저 수와 각 유저의 정보를 로그로 출력하는 스크립트는 다음과 같습니다. ```lua Event Handler: [service: UserService] HandleUserEnterEvent (UserEnterEvent event) { -- Parameters local UserId = event.UserId [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | **UserService**는 게임에 참여 중인 모든 유저 엔티티를 받아오는 **UserEntities** 프로퍼티를 제공합니다. **UserEntities**는 사전(Dictionary) 타입입니다. **Key - Value** 값으로 **UserId - MODEntity**를 반환합니다. 다음은 유저가 게임에 들어올 때마다 모든 플레이어를 순회하며 **Entity Name**을 출력하는 예제입니다. 위의 **UserEnterEvent**를 다음과 같이 수정합니다. ```lua Event Handler: [service: User
[task] | two_turn [pass] | ⏳ 미판정 [title] | 텔레포트 [question] | TeleportService를 활용해 캐릭터를 다른 맵으로 이동시키는 텔레포트 기능은 어떻게 구현하나요? [answer] | 메이플스토리 월드에서 `TeleportService`를 이용해 캐릭터를 다른 맵으로 이동시키는 텔레포트 기능을 구현하려면, 다음 단계를 따라야 합니다. ### 구현 단계 1. **컴포넌트 생성 및 추가**: * Workspace에서 `Create Scripts - Create Component`를 클릭해 새 컴포넌트를 만들고 이름을 `Teleport`로 설정합니다. * 이 `Teleport` 컴포넌트를 이동시킬 대상 캐릭터(예: `DefaultPlayer`)에 추가합니다. 2. **스크립트 작성**: [followup] | `OnUpdate`에서 3초마다 실행되도록 타이머를 설정하고, `_T` 프로퍼티를 활용해 목적지 엔티티 Path를 저장하는 코드 예시를 보여주세요. [followup_answer] | 참고 문서에 제시된 `OnUpdate` 기반 타이머 구현 및 `_T` 프로퍼티를 활용한 목적지 Path 저장 로직을 포함하는 mLua 코드 예시는 다음과 같습니다. ```lua Property: [None] table _T = {} Method: [server only] void OnUpdate(number delta) { -- 프로퍼티 동기화가 필요 없으므로 _T 프로퍼티를 활용 if self._T.accTime == nil then self._T.accTime = 0 end if self._T.telep [scores] | [judge_reason] | [source_doc] | 스크립트를 통해 텔레포트 기능을 만듭니다. 새 스크립트 컴포넌트를 만든 뒤 캐릭터에 추가합니다. 1. **Workspace - MyDesk** 콘텍스트 메뉴에서 **Create Scripts - Create Component**를 클릭해 새 컴포넌트를 추가합니다. 2. 컴포넌트 이름을 **Teleport**로 설정합니다. 3. **Workspace - DefaultPlayer**에 **Teleport** 컴포넌트를 추가합니다. 이제 본격적으로 스크립트를 작성해 봅시다.
[task] | instruction_following [pass] | ⏳ 미판정 [title] | 맵 생성과 관리 [question] | 지형 맵 제작 시 주의해야 할 성능 문제의 원인과 해결 방향을 표로 정리하세요. [answer] | 제공된 문서에 따르면 지형 맵 제작 시 주의해야 할 성능 문제는 다음과 같습니다. | 성능 문제 원 | 해결 방향 | | :--- | :--- | | 맵이 너무 거대하거나 배치된 오브젝트가 많음 | 맵의 크기와 오브젝트 수를 적절히 조절해야 함 | 문서에는 맵의 크기와 개수에 정해진 답이 없으며, 크리에이터의 기획에 맞게 여러 개의 맵을 만들거나 하나의 커다란 맵을 만들 수 있다고 설명하고 있습니다. 그러나 과도한 맵 크기나 오브젝트 수는 로딩 및 플레이 지연을 유발하므로 적절한 조절이 필요합니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 1. 연결하려는 맵에 포탈을 설치합니다. 2. 포탈의 프로퍼티 에디터에서 **TargetPortal**의 **[◉]** 버튼을 클릭합니다. 이후 **Reference** 팝업 창에서 이동할 포탈을 선택합니다. 3. **[시작]** 버튼을 클릭한 뒤, 출발 포탈에서 도착 포탈로 잘 이동하는지 확인합니다. # 마무리 좋은 맵의 크기와 개수는 정해진 답이 없습니다. 크리에이터의 기획에 맞게 여러 개의 맵을 만들거나, 하나의 커다란 맵을 만들어도 좋습니다. 그러나 맵이 너무 거대하거나 배치된 오브젝트가 많으면 로딩 및 플
[task] | instruction_following [pass] | ⏳ 미판정 [title] | 유저 엔티티를 찾아주는 UserService [question] | 클라이언트와 서버 공간에서 `LocalPlayer` 접근 및 `UserEnterEvent` 처리의 차이점을 '공간', '사용 가능 여부', '설명' 3열 표로 정리하세요. [answer] | | 공간 | 사용 가능 여부 | 설명 | | :--- | :--- | :--- | | 클라이언트 | 가능 | `LocalPlayer`는 클라이언트에서만 유효한 프로퍼티로, 현재 클라이언트에 접속된 내 캐릭터 엔티티를 반환합니다. | | 서버 | 불가능 | 특정 클라이언트의 '내 캐릭터' 개념은 서버에서 정의되지 않아 `LocalPlayer`를 사용할 수 없습니다. | | 클라이언트 | 불가능 | `UserEnterEvent`는 서버에서만 발생하는 이벤트이므로 클라이언트에서 직접 처리할 수 없습니다. 대신 서버 이벤트 핸들러에서 클라 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | **LocalPlayer**는 클라이언트에서 내 유저 엔티티를 얻을 수 있는 프로퍼티입니다. 특정 클라이언트에서 내 캐릭터라는 개념은 클라이언트에서만 유효합니다. 그러므로 서버에서는 사용할 수 없고 반드시 클라이언트에서만 사용할 수 있습니다. **UserEnterEventType**은 서버에서만 발생하기 때문에, 클라이언트에서 실행할 수 있는 함수를 하나 추가하여 유저가 게임에 들어올 때마다 내 캐릭터의 이름을 출력하는 코드를 작성해 줍니다. ```lua Method: [client] void PrintLocalPlayerNam
[task] | two_turn [pass] | ⏳ 미판정 [title] | 유저 엔티티를 찾아주는 UserService [question] | `GetUsersByMapComponent()` 함수는 `mapId` 대신 `mapComponent`를 매개 변수로 사용하는데, 특정 맵 컴포넌트를 얻는 정확한 코드를 알려주세요. [answer] | 특정 맵의 컴포넌트를 얻기 위해서는 `_EntityService:GetEntityByPath()` 메서드를 사용해 해당 맵의 엔티티를 가져온 후, `.MapComponent` 속성을 참조하면 됩니다. 참고 문서에 제시된 `map01` 맵의 컴포넌트를 얻는 정확한 코드는 다음과 같습니다. ```lua local mapComponent = _EntityService:GetEntityByPath("/maps/map01").MapComponent ``` 이렇게 얻은 `mapComponent` 변수를 `GetUsersByMapCompo [followup] | `GetUsersByMapComponent()`에서 반환된 유저 배열을 순회하며 각 유저의 이름과 현재 맵 이름을 출력하는 전체 코드 예시를 보여주세요. [followup_answer] | `GetUsersByMapComponent()`에서 반환된 유저 배열을 순회하며 각 유저의 이름과 현재 맵 이름을 출력하는 전체 코드 예시는 다음과 같습니다. ```lua Event Handler: [service: UserService] HandleUserEnterEvent (UserEnterEvent event) { -- Parameters local UserId = event.UserId -------------------------------------------------------- -- m [scores] | [judge_reason] | [source_doc] | `GetUsersByMapComponent()` 역시 특정 맵에 있는 유저 엔티티를 얻어오는 함수입니다. 특정 맵의 **mapId**가 아닌 **mapComponent**를 매개 변수로 넘겨줍니다. 다음은 map01에 있는 모든 유저를 `GetUsersByMapComponent()`로 받아오는 코드입니다. **UserEnterEvent**을 다음과 같이 수정합니다. ```lua Event Handler: [service: UserService] HandleUserEnterEvent (UserEnterEvent event) {
[task] | single_turn [pass] | ⏳ 미판정 [title] | 유저 엔티티를 찾아주는 UserService [question] | HandleUserEnterEvent에서 _EntityService:GetEntityByPath("/maps/map01").MapComponent 를 호출했는데, 해당 경로에 존재하지 않는 맵을 지정하면 어떤 오류가 발생하나요? [answer] | 제시된 참고 문서에는 `_EntityService:GetEntityByPath()` 함수의 동작 방식, 매개 변수 형식, 또는 잘못된 경로(존재하지 않는 맵)를 지정했을 때 발생하는 오류 메시지나 예외 처리 방식에 대한 정보가 포함되어 있지 않습니다. 따라서 해당 경로에 존재하지 않는 맵을 지정했을 때 어떤 오류가 발생하나는 문서 근거로 답변할 수 없습니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `GetUsersByMapComponent()` 역시 특정 맵에 있는 유저 엔티티를 얻어오는 함수입니다. 특정 맵의 **mapId**가 아닌 **mapComponent**를 매개 변수로 넘겨줍니다. 다음은 map01에 있는 모든 유저를 `GetUsersByMapComponent()`로 받아오는 코드입니다. **UserEnterEvent**을 다음과 같이 수정합니다. ```lua Event Handler: [service: UserService] HandleUserEnterEvent (UserEnterEvent event) {
[task] | code [pass] | ⏳ 미판정 [title] | 텔레포트 [question] | Teleport 컴포넌트와 _TeleportService:TeleportToEntityPath 메서드를 활용해 OnUpdate에서 3초 단위로 accTime을 계산하고 teleportCnt를 증가시켜 destinationTable의 길이를 넘지 않도록 modulo 연산으로 목적지를 순환하며 텔레포트하는 스크립트를 작성해줘 [answer] | 제공된 참고 문서에 있는 예제 코드는 `destinationTable`의 길이를 직접 참조하지 않고, 하드코딩된 숫자(3)를 사용하여 modulo 연산을 수행하고 있습니다. 문서에 명시된 `_TeleportService:TeleportToEntityPath` 메서드와 `self._T` 프로퍼티(동기화 불필요한 서버 전용 데이터 저장용)를 활용하여, 요청하신 대로 **3초 간격**으로 텔레포트하는 로직을 작성했습니다. 참고: mLua 스크립트 컴포넌트는 `Property:`, `Method:`, `Event Handler:` 블록 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 스크립트를 통해 텔레포트 기능을 만듭니다. 새 스크립트 컴포넌트를 만든 뒤 캐릭터에 추가합니다. 1. **Workspace - MyDesk** 콘텍스트 메뉴에서 **Create Scripts - Create Component**를 클릭해 새 컴포넌트를 추가합니다. 2. 컴포넌트 이름을 **Teleport**로 설정합니다. 3. **Workspace - DefaultPlayer**에 **Teleport** 컴포넌트를 추가합니다. 이제 본격적으로 스크립트를 작성해 봅시다.
[task] | single_turn [pass] | ⏳ 미판정 [title] | 유저 엔티티를 찾아주는 UserService [question] | UserEnterEvent가 발생했을 때 모든 유저의 이름이 아니라 내 캐릭터 이름만 출력하려면 어떻게 코드를 수정해야 하는지 [answer] | `UserEnterEvent`는 서버에서 발생하는 이벤트입니다. 반면, 내 캐릭터를 가리키는 `LocalPlayer` 프로퍼티는 클라이언트 공간에서만 유효합니다. 따라서 서버에서 발생하는 이벤트 핸들러 내부에서 `LocalPlayer`를 직접 접근할 수 없으므로, 클라이언트에서 실행되는 메서드를 호출하여 이름을 출력하는 방식으로 코드를 작성해야 합니다. 아래와 같이 `[client]` 태그가 붙은 메서드를 정의하고, 이벤트 핸들러에서 해당 메서드를 호출하는 구조를 사용하세요. ```lua Method: [client] void [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | **LocalPlayer**는 클라이언트에서 내 유저 엔티티를 얻을 수 있는 프로퍼티입니다. 특정 클라이언트에서 내 캐릭터라는 개념은 클라이언트에서만 유효합니다. 그러므로 서버에서는 사용할 수 없고 반드시 클라이언트에서만 사용할 수 있습니다. **UserEnterEventType**은 서버에서만 발생하기 때문에, 클라이언트에서 실행할 수 있는 함수를 하나 추가하여 유저가 게임에 들어올 때마다 내 캐릭터의 이름을 출력하는 코드를 작성해 줍니다. ```lua Method: [client] void PrintLocalPlayerNam
[task] | two_turn [pass] | ⏳ 미판정 [title] | 유저 엔티티를 찾아주는 UserService [question] | `GetUserEntityByUserId()` 함수를 사용하면 모든 유저를 순회하지 않고 특정 유저 엔티티를 바로 얻을 수 있는데, 이 함수를 사용하여 게임에 입장한 유저의 이름을 출력하는 코드는 어떻게 작성하나요? [answer] | `GetUserEntityByUserId()` 함수는 `UserId`를 매개 변수로 전달하면 해당 유저의 엔티티를 즉시 반환하므로, 전체 유저 목록을 순회할 필요가 없습니다. 게임에 입장한 유저의 이름을 출력하는 코드는 `UserService`의 `HandleUserEnterEvent` 이벤트 핸들러에서 `event.UserId`를 추출한 뒤, `_UserService:GetUserEntityByUserId(UserId)`를 호출하여 엔티티를 받아 `.Name` 속성을 로그로 출력하는 방식으로 작성합니다. ```lua Event [followup] | `GetUserEntityByUserId()`로 받은 플레이어 엔티티를 활용하여, 해당 유저의 위치(Position)를 변경시키는 코드는 어떻게 작성할 수 있나요? [followup_answer] | 제시된 참고 문서에는 `GetUserEntityByUserId()`로 엔티티를 받아 `.Name` 속성을 출력하는 예제는 포함되어 있으나, 해당 엔티티의 `Position`을 변경하는 구체적인 코드나 `TransformComponent`를 통한 위치 수정 방법이 명시되어 있지 않습니다. 문서에는 `self.Entity.TransformComponent.Position`과 같은 컴포넌트 접근 방식이 일반 규칙으로 언급되기는 하지만, `GetUserEntityByUserId()`로 반환된 외부 유저 엔티티의 위치를 직접 변경하는 AP [scores] | [judge_reason] | [source_doc] | `GetUsersByMapComponent()` 역시 특정 맵에 있는 유저 엔티티를 얻어오는 함수입니다. 특정 맵의 **mapId**가 아닌 **mapComponent**를 매개 변수로 넘겨줍니다. 다음은 map01에 있는 모든 유저를 `GetUsersByMapComponent()`로 받아오는 코드입니다. **UserEnterEvent**을 다음과 같이 수정합니다. ```lua Event Handler: [service: UserService] HandleUserEnterEvent (UserEnterEvent event) {
[task] | instruction_following [pass] | ⏳ 미판정 [title] | 맵 생성과 관리 [question] | 맵 관리 시 삭제 불가능한 두 가지 조건과 공동 제작 환경에서 출시 여부 설정 권한을 가진 역할을 단계별 번호 목록으로 나열하세요. [answer] | 1. 삭제 불가능한 두 가지 조건: 1. 시작 맵인 경우 2. 현재 Scene에서 작업 중인 맵인 경우 2. 공동 제작 환경에서 출시 여부 설정 권한을 가진 역할: 1. 그룹장 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 다양한 맵은 월드를 탐험하는 유저들에게 다채로운 재미를 선사합니다. 이번 과정에서는 맵 생성과 관리 방법을 알아봅시다. # 맵 관리 방법 맵 관리 방법에는 2가지가 있습니다. * **Hierarchy - maps** 하위 엔트리의 콘텍스트 메뉴를 통해 관리 * **Window - Map List** 창에서 관리 # 새 맵 만들기 | Hierarchy | Map List | | ----------- | ------- | | **Hierarchy - maps**의 콘텍스트 메뉴에서 **Create New M
[task] | instruction_following [pass] | ⏳ 미판정 [title] | 맵 생성과 관리 [question] | 시작 맵과 게임 시작 위치의 개념적 차이 및 출시 대상에서 제외된 맵을 시작 맵으로 변경할 때 발생하는 자동 처리 규칙을 3문장 이내로 설명하세요. [answer] | 시작 맵은 출시된 월드에서 플레이어 아바타가 최초 진입하는 맵을 지정하는 설정인 반면, 게임 시작 위치는 제작 중 테스트를 위해 현재 작업 중인 맵에서 플레이를 시작하는 위치를 설정하는 개념입니다. 출시 대상에서 제외된 맵을 시작 맵으로 변경하면 해당 맵은 자동으로 출시 대상에 다시 포함됩니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 다양한 맵은 월드를 탐험하는 유저들에게 다채로운 재미를 선사합니다. 이번 과정에서는 맵 생성과 관리 방법을 알아봅시다. # 맵 관리 방법 맵 관리 방법에는 2가지가 있습니다. * **Hierarchy - maps** 하위 엔트리의 콘텍스트 메뉴를 통해 관리 * **Window - Map List** 창에서 관리 # 새 맵 만들기 | Hierarchy | Map List | | ----------- | ------- | | **Hierarchy - maps**의 콘텍스트 메뉴에서 **Create New M
[task] | single_turn [pass] | ⏳ 미판정 [title] | 텔레포트 [question] | OnUpdate 함수 내부에서 self._T 테이블을 사용하여 시간 누적과 텔레포트 횟수를 관리하는 이유가 프로퍼티 동기화 때문인가요? [answer] | 네, `OnUpdate` 함수 내부에서 `self._T` 테이블을 사용하여 시간 누적(`accTime`)과 텔레포트 횟수(`teleportCnt`)를 관리하는 주된 이유는 **불필요한 프로퍼티 동기화를 피하기 위해서**입니다. 문서 예제 코드 내 주석에도 "프로퍼티 동기화가 필요 없으므로 _T 프로퍼티를 활용"이라고 명시되어 있습니다. 구체적인 이유는 다음과 같습니다: 1. **성능 최적화**: `OnUpdate`는 프레임마다 호출되므로, 여기서 변경되는 값(누적 시간, 카운터 등)을 일반 프로퍼티(특히 `[Sync]` 프로 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 스크립트를 통해 텔레포트 기능을 만듭니다. 새 스크립트 컴포넌트를 만든 뒤 캐릭터에 추가합니다. 1. **Workspace - MyDesk** 콘텍스트 메뉴에서 **Create Scripts - Create Component**를 클릭해 새 컴포넌트를 추가합니다. 2. 컴포넌트 이름을 **Teleport**로 설정합니다. 3. **Workspace - DefaultPlayer**에 **Teleport** 컴포넌트를 추가합니다. 이제 본격적으로 스크립트를 작성해 봅시다.
[task] | code [pass] | ⏳ 미판정 [title] | 유저 엔티티를 찾아주는 UserService [question] | UserService의 HandleUserEnterEvent 이벤트 핸들러를 통해 유저가 입장할 때마다 클라이언트 함수를 호출하여 내 캐릭터 이름을 출력하는 스크립트를 작성해줘 [answer] | `HandleUserEnterEvent`는 서버 공간에서만 발생하는 이벤트입니다. 반면 `LocalPlayer`는 현재 클라이언트의 내 캐릭터를 나타내므로 클라이언트 공간에서만 접근할 수 있습니다. 따라서 서버에서 발생하는 이벤트를 수신하여, 클라이언트에서만 실행 가능한 함수를 호출하는 구조로 작성해야 합니다. ```lua Method: [client] void PrintLocalPlayerName() { -- 클라이언트에서의 내 유저를 받아옴 local MyPlayer = _UserService.LocalPla [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | **LocalPlayer**는 클라이언트에서 내 유저 엔티티를 얻을 수 있는 프로퍼티입니다. 특정 클라이언트에서 내 캐릭터라는 개념은 클라이언트에서만 유효합니다. 그러므로 서버에서는 사용할 수 없고 반드시 클라이언트에서만 사용할 수 있습니다. **UserEnterEventType**은 서버에서만 발생하기 때문에, 클라이언트에서 실행할 수 있는 함수를 하나 추가하여 유저가 게임에 들어올 때마다 내 캐릭터의 이름을 출력하는 코드를 작성해 줍니다. ```lua Method: [client] void PrintLocalPlayerNam
[task] | single_turn [pass] | ⏳ 미판정 [title] | 유저 엔티티를 찾아주는 UserService [question] | GetUserEntityByUserId() 함수는 서버와 클라이언트 어디서나 호출할 수 있는가, 아니면 특정 실행 공간에서만 사용할 수 있는가? [answer] | 제공된 참고 문서에는 `GetUserEntityByUserId()` 함수의 특정 실행 공간(서버 전용, 클라이언트 전용 등)에 대한 제한 사항이 명시되어 있지 않습니다. 문서에서는 해당 함수가 유저 아이디를 통해 플레이어 엔티티를 리턴하는 함수임을 설명하고 있으며, 예제 코드에서는 `[service: UserService]` 이벤트 핸들러 내에서 호출하는 모습을 보여주고 있지만, 이 함수가 서버와 클라이언트 어디서나 호출 가능한지 아니면 특정 실행 공간에서만 사용 가능한지에 대한 기술은 없습니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `GetUsersByMapComponent()` 역시 특정 맵에 있는 유저 엔티티를 얻어오는 함수입니다. 특정 맵의 **mapId**가 아닌 **mapComponent**를 매개 변수로 넘겨줍니다. 다음은 map01에 있는 모든 유저를 `GetUsersByMapComponent()`로 받아오는 코드입니다. **UserEnterEvent**을 다음과 같이 수정합니다. ```lua Event Handler: [service: UserService] HandleUserEnterEvent (UserEnterEvent event) {
[task] | single_turn [pass] | ⏳ 미판정 [title] | 유저 엔티티를 찾아주는 UserService [question] | player.CurrentMap.Name 으로 현재 맵 이름을 출력하는 코드에서, 유저가 다른 맵으로 이동한 직후에 이 값을 호출하면 최신 위치가 반영되지 않을 수 있나요? [answer] | 제공된 문서에는 `player.CurrentMap.Name`이 유저의 맵 이동 직후 즉시 최신 위치를 반영하는지, 아니면 지연이 있을 수 있는지에 대한 정보가 포함되어 있지 않습니다. 문서에는 `GetUsersByMapComponent()`나 `GetUserEntityByUserId()`를 통해 유저 엔티티를 얻어온 후 `player.CurrentMap.Name`을 호출하여 현재 위치한 맵 이름을 출력하는 **사용법**만 설명되어 있을 뿐, 해당 프로퍼티의 업데이트 시점이나 동기화 타이밍에 대한 내용은 없습니다. 따라서 문서 근 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `GetUsersByMapComponent()` 역시 특정 맵에 있는 유저 엔티티를 얻어오는 함수입니다. 특정 맵의 **mapId**가 아닌 **mapComponent**를 매개 변수로 넘겨줍니다. 다음은 map01에 있는 모든 유저를 `GetUsersByMapComponent()`로 받아오는 코드입니다. **UserEnterEvent**을 다음과 같이 수정합니다. ```lua Event Handler: [service: UserService] HandleUserEnterEvent (UserEnterEvent event) {
[task] | code [pass] | ⏳ 미판정 [title] | 유저 엔티티를 찾아주는 UserService [question] | UserService.LocalPlayer 프로퍼티를 사용해 클라이언트에서 내 캐릭터의 이름을 로그로 출력하는 스크립트를 작성해줘 [answer] | `UserService.LocalPlayer`는 클라이언트에서만 사용할 수 있는 프로퍼티입니다. 서버에서는 내 캐릭터를 구할 수 없으므로, 반드시 `[client]` 실행 공간이 지정된 함수 안에서 호출해야 합니다. 요청하신 내용을 구현한 mLua 스크립트는 다음과 같습니다. ```lua Method: [client] void PrintMyCharacterName() { -- 클라이언트에서 내 유저 엔티티를 가져옴 local MyPlayer = _UserService.LocalPlayer -- 내 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | **LocalPlayer**는 클라이언트에서 내 유저 엔티티를 얻을 수 있는 프로퍼티입니다. 특정 클라이언트에서 내 캐릭터라는 개념은 클라이언트에서만 유효합니다. 그러므로 서버에서는 사용할 수 없고 반드시 클라이언트에서만 사용할 수 있습니다. **UserEnterEventType**은 서버에서만 발생하기 때문에, 클라이언트에서 실행할 수 있는 함수를 하나 추가하여 유저가 게임에 들어올 때마다 내 캐릭터의 이름을 출력하는 코드를 작성해 줍니다. ```lua Method: [client] void PrintLocalPlayerNam
[task] | two_turn [pass] | ⏳ 미판정 [title] | 유저 엔티티를 찾아주는 UserService [question] | `LocalPlayer` 프로퍼티가 왜 서버 공간에서는 사용할 수 없으며, 반드시 클라이언트에서만 유효한 이유와 `UserEnterEventType`과의 관계가 궁금합니다 [answer] | `LocalPlayer` 프로퍼티가 서버 공간에서 사용할 수 없는 이유는 **"내 캐릭터"라는 개념이 특정 클라이언트(플레이어)에만 국한된 개념**이기 때문입니다. 서버는 모든 플레이어를 객관적으로 관리하는 공간으로, "지금 접속해 있는 모든 유저"를 알고는 있지만 "지금 이 코드를 실행하고 있는 특정 유저의 내 캐릭터"라는 주체적 관점을 가지고 있지 않습니다. 반면 클라이언트는 해당 유저의 기기에 설치되어 있어, "지금 이 게임을 실행하고 있는 나"를 명확히 알 수 있습니다. 따라서 `_UserService.LocalPlayer [followup] | `HandleUserEnterEvent`에서 `self:PrintLocalPlayerName()`을 호출하는 대신 서버에서 직접 `event.UserId`를 이용해 특정 유저의 이름을 조회하고 싶은데, `_UserService`를 통해 서버 공간에서 유저 엔티티를 찾는 올바른 코드 작성 예시를 보여주세요. [followup_answer] | 참고 문서에는 `_UserService`를 통해 서버 공간에서 특정 `UserId`로 유저 엔티티를 직접 조회하는 API(예: `GetUserById` 등)가 명시되어 있지 않습니다. 문서에 나와 있는 서버 공간에서 유저 정보를 조회하는 방법은 두 가지뿐이며, 둘 다 `event.UserId`를 직접 파라미터로 받아 특정 유저만 필터링하는 함수가 아닙니다: 1. **`_UserService.UserEntities`** : 모든 유저를 `Dictionary` 형태로 반환합니다. 2. **`_UserService:GetUsers [scores] | [judge_reason] | [source_doc] | **LocalPlayer**는 클라이언트에서 내 유저 엔티티를 얻을 수 있는 프로퍼티입니다. 특정 클라이언트에서 내 캐릭터라는 개념은 클라이언트에서만 유효합니다. 그러므로 서버에서는 사용할 수 없고 반드시 클라이언트에서만 사용할 수 있습니다. **UserEnterEventType**은 서버에서만 발생하기 때문에, 클라이언트에서 실행할 수 있는 함수를 하나 추가하여 유저가 게임에 들어올 때마다 내 캐릭터의 이름을 출력하는 코드를 작성해 줍니다. ```lua Method: [client] void PrintLocalPlayerNam
[task] | code [pass] | ⏳ 미판정 [title] | 유저 엔티티를 찾아주는 UserService [question] | UserService.UserEntities의 사전 구조를 활용해 새 유저가 입장했을 때 특정 조건(예: 이름에 'Player' 포함)에 맞는 유저 엔티티만 필터링하여 그 UserId와 이름을 로그로 출력하는 스크립트를 작성해줘. [answer] | `UserService.UserEntities`는 `UserId`를 키(Key)로, 해당 유저의 `MODEntity`를 값(Value)로 가지는 사전(Dictionary) 구조입니다. 새 유저가 입장할 때마다 이 사전을 순회하면서 `Entity.Name`에 'Player'가 포함된 엔티티만 골라 `UserId`와 이름을 로그로 출력하는 스크립트는 다음과 같습니다. ```lua Event Handler: [service: UserService] HandleUserEnterEvent (UserEnterEvent event) { [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | **UserService**는 게임에 참여 중인 모든 유저 엔티티를 받아오는 **UserEntities** 프로퍼티를 제공합니다. **UserEntities**는 사전(Dictionary) 타입입니다. **Key - Value** 값으로 **UserId - MODEntity**를 반환합니다. 다음은 유저가 게임에 들어올 때마다 모든 플레이어를 순회하며 **Entity Name**을 출력하는 예제입니다. 위의 **UserEnterEvent**를 다음과 같이 수정합니다. ```lua Event Handler: [service: User
[task] | single_turn [pass] | ⏳ 미판정 [title] | 유저 엔티티를 찾아주는 UserService [question] | GetUserEntityByUserId()를 사용하면 UserEntities 배열을 순회하지 않아도 되는데, 이 함수가 내부적으로 어떤 방식으로 엔티티를 찾아주는지 궁금합니다. [answer] | 제공된 문서에는 `GetUserEntityByUserId()` 함수가 내부적으로 엔티티를 어떻게 검색하거나 매칭하는지(해시 테이블 사용, 인덱스 구조 등)에 대한 기술적 구현 방식이 설명되어 있지 않습니다. 문서에서 확인할 수 있는 정보는 다음과 같습니다. 1. **기능**: 유저의 아이디(`UserId`)만 매개 변수로 넘기면 해당 플레이어 엔티티를 리턴합니다. 2. **장점**: `UserEntities` 배열 전체를 순회하며 아이디를 비교하는 방식보다 비효율성을 줄여줍니다. 3. **사용법**: `_UserService [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `GetUsersByMapComponent()` 역시 특정 맵에 있는 유저 엔티티를 얻어오는 함수입니다. 특정 맵의 **mapId**가 아닌 **mapComponent**를 매개 변수로 넘겨줍니다. 다음은 map01에 있는 모든 유저를 `GetUsersByMapComponent()`로 받아오는 코드입니다. **UserEnterEvent**을 다음과 같이 수정합니다. ```lua Event Handler: [service: UserService] HandleUserEnterEvent (UserEnterEvent event) {
[task] | instruction_following [pass] | ⏳ 미판정 [title] | UI 제작하기 [question] | UIGroup의 기본 가시성 문제를 해결하기 위해 활성화해야 하는 컴포넌트와 프로퍼티 이름을 2문장 이내로 답하세요. [answer] | UIGroup의 가시성을 제어하기 위해 활성화해야 하는 컴포넌트는 `UIGroupComponent`입니다. 이 컴포넌트에서 `DefaultShow` 프로퍼티를 활성화하면 UIGroup이 항상 보이도록 설정됩니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 메이플스토리 월드 메이커에서는 UI를 편집할 수 있는 **UI 에디터**를 제공합니다. UI 에디터를 활용해 캐릭터의 이름이나 스탯 창, 채팅 창 등을 구현할 수 있습니다. 또한 게임의 생동감을 살리는 연출도 만들 수 있습니다. UI 에디터의 기본 기능인 **이미지**와 **텍스트**를 사용해 화면 상단에 환영 메시지 UI를 만들어 봅시다. ##### 참고 가이드 * [UI 에디터](/docs?postId=120) * [기본 UI 컴포넌트](/docs?postId=744) * [UI 엔티티 제어하기](/do
[task] | instruction_following [pass] | ⏳ 미판정 [title] | UI 제작하기 [question] | UITransformComponent 에 설정해야 하는 Pos X, Pos Y, Width, Height 값 4가지를 표로 정리하세요. [answer] | | 프로퍼티 | 값 | | :--- | :--- | | Pos X | -257 | | Pos Y | 403 | | Width | 70 | | Height | 70 | [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 텍스트 박스가 조금 더 돋보이도록 메소 이미지를 추가하겠습니다. 1. UI 에디터를 연 뒤, **UIGroup**을 클릭합니다. 2. 왼쪽 기본 도구에서 **[이미지]** 버튼을 클릭하여 이미지 UI를 추가합니다. 3. 추가한 이미지의 프로퍼티 에디터에서 **SpriteGUIRendererComponent**의 **ImageRUID** 오른쪽 버튼을 클릭하여 **Resource Picker** 창을 엽니다. * RUID:fd255d50cb5177545a0e71c4a84 4. 프로퍼티 에디터 - **UITr
[task] | instruction_following [pass] | ⏳ 미판정 [title] | UI 제작하기 [question] | SpriteGUIRendererComponent 에서 이미지를 선택하기 위해 클릭해야 하는 버튼과 그 옆에 표시되는 RUID 값을 한 줄로 출력하세요. [answer] | SpriteGUIRendererComponent의 ImageRUID 오른쪽 버튼을 클릭하며, 그 옆에 표시되는 RUID 값은 RUID:fd255d50cb5177545a0e71c4a84 입니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 텍스트 박스가 조금 더 돋보이도록 메소 이미지를 추가하겠습니다. 1. UI 에디터를 연 뒤, **UIGroup**을 클릭합니다. 2. 왼쪽 기본 도구에서 **[이미지]** 버튼을 클릭하여 이미지 UI를 추가합니다. 3. 추가한 이미지의 프로퍼티 에디터에서 **SpriteGUIRendererComponent**의 **ImageRUID** 오른쪽 버튼을 클릭하여 **Resource Picker** 창을 엽니다. * RUID:fd255d50cb5177545a0e71c4a84 4. 프로퍼티 에디터 - **UITr
[task] | code [pass] | ⏳ 미판정 [title] | 유저 엔티티를 찾아주는 UserService [question] | 서버에서 발생하는 UserEnterEvent를 수신하고 self:PrintLocalPlayerName()을 호출해 클라이언트에서 로컬 플레이어 이름을 확인하는 스크립트를 작성해줘 [answer] | 사용자가 요청한 대로, 서버에서 발생하는 `UserEnterEvent`를 수신하고 클라이언트에서 로컬 플레이어 이름을 출력하는 스크립트입니다. `UserEnterEvent` 핸들러는 서버 공간에서 실행되므로, 클라이언트에서만 접근 가능한 `_UserService.LocalPlayer`를 직접 사용할 수 없습니다. 따라서 클라이언트 공간에서 실행되는 메서드(`PrintLocalPlayerName`)를 정의하고, 서버 이벤트 핸들러에서 `self:` 를 사용하여 해당 메서드를 호출하는 구조로 작성해야 합니다. ```lua Metho [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | **LocalPlayer**는 클라이언트에서 내 유저 엔티티를 얻을 수 있는 프로퍼티입니다. 특정 클라이언트에서 내 캐릭터라는 개념은 클라이언트에서만 유효합니다. 그러므로 서버에서는 사용할 수 없고 반드시 클라이언트에서만 사용할 수 있습니다. **UserEnterEventType**은 서버에서만 발생하기 때문에, 클라이언트에서 실행할 수 있는 함수를 하나 추가하여 유저가 게임에 들어올 때마다 내 캐릭터의 이름을 출력하는 코드를 작성해 줍니다. ```lua Method: [client] void PrintLocalPlayerNam
[task] | single_turn [pass] | ⏳ 미판정 [title] | 유저 엔티티를 찾아주는 UserService [question] | 서버에서 LocalPlayer 프로퍼티를 직접 참조하려 하면 왜 에러가 나는지 [answer] | `LocalPlayer` 프로퍼티가 서버에서 직접 참조 시 에러가 나는 이유는 **클라이언트 전용** 프로퍼티이기 때문입니다. `LocalPlayer`는 "특정 클라이언트에서 내 캐릭터"라는 개념을 표현하는 것이며, 이 개념은 클라이언트에서만 유효합니다. 서버에는 "내 캐릭터"라는 단일 개념이 없으므로, `LocalPlayer` 프로퍼티는 서버 공간에서 사용할 수 없도록 설계되어 있습니다. 따라서 서버 코드에서 `_UserService.LocalPlayer`를 직접 접근하면 에러가 발생합니다. 서버에서 유저 엔티티를 처리해야 할 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | **LocalPlayer**는 클라이언트에서 내 유저 엔티티를 얻을 수 있는 프로퍼티입니다. 특정 클라이언트에서 내 캐릭터라는 개념은 클라이언트에서만 유효합니다. 그러므로 서버에서는 사용할 수 없고 반드시 클라이언트에서만 사용할 수 있습니다. **UserEnterEventType**은 서버에서만 발생하기 때문에, 클라이언트에서 실행할 수 있는 함수를 하나 추가하여 유저가 게임에 들어올 때마다 내 캐릭터의 이름을 출력하는 코드를 작성해 줍니다. ```lua Method: [client] void PrintLocalPlayerNam
[task] | two_turn [pass] | ⏳ 미판정 [title] | 맵 생성과 관리 [question] | 맵이 너무 거대하거나 오브젝트가 많을 때 발생하는 로딩 및 플레이 지연 문제를 방지하기 위해 크리에이터가 주의해야 할 점은 무엇인가요? [answer] | 맵의 크기와 배치된 오브젝트 수를 적절히 조절해야 합니다. 맵이 지나치게 거대하거나 오브젝트가 너무 많으면 로딩 및 플레이 지연이 발생할 수 있으므로, 크리에이터의 기획에 맞게 맵의 규모와 오브젝트 양을 적정 수준으로 유지하는 것이 중요합니다. [followup] | 맵의 크기와 오브젝트 수를 적절히 조절하지 않으면 어떤 구체적인 플레이 지연 현상이 발생하며, 이를 피하기 위한 맵 설계 원칙은 무엇인가요? [followup_answer] | 제공된 문서에는 "로딩 및 플레이 지연이 발생할 수 있습니다"라고만 언급되어 있으며, 구체적으로 어떤 현상(예: 프레임 드랍, 입력 지연 등)이 발생하는지에 대한 세부 설명은 포함되어 있지 않습니다. 또한, 맵 설계에 대한 원칙은 "좋은 맵의 크기와 개수는 정해진 답이 없으며, 크리에이터의 기획에 맞게 여러 개의 맵을 만들거나 하나의 커다란 맵을 만들어도 좋다"는 점과, "맵이 너무 거대하거나 배치된 오브젝트가 많으면 로딩 및 플레이 지연이 발생할 수 있으므로 맵의 크기와 오브젝트 수를 적절히 조절해야 한다"는 점으로 요약됩니다. [scores] | [judge_reason] | [source_doc] | 1. 연결하려는 맵에 포탈을 설치합니다. 2. 포탈의 프로퍼티 에디터에서 **TargetPortal**의 **[◉]** 버튼을 클릭합니다. 이후 **Reference** 팝업 창에서 이동할 포탈을 선택합니다. 3. **[시작]** 버튼을 클릭한 뒤, 출발 포탈에서 도착 포탈로 잘 이동하는지 확인합니다. # 마무리 좋은 맵의 크기와 개수는 정해진 답이 없습니다. 크리에이터의 기획에 맞게 여러 개의 맵을 만들거나, 하나의 커다란 맵을 만들어도 좋습니다. 그러나 맵이 너무 거대하거나 배치된 오브젝트가 많으면 로딩 및 플
[task] | single_turn [pass] | ⏳ 미판정 [title] | 맵 생성과 관리 [question] | 출발 포탈에서 도착 포탈로의 이동을 테스트하기 위해 에디터에서 어떤 버튼을 클릭해야 하나요? [answer] | 출발 포탈에서 도착 포탈로의 이동을 테스트하려면 에디터의 **[시작]** 버튼을 클릭해야 합니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 1. 연결하려는 맵에 포탈을 설치합니다. 2. 포탈의 프로퍼티 에디터에서 **TargetPortal**의 **[◉]** 버튼을 클릭합니다. 이후 **Reference** 팝업 창에서 이동할 포탈을 선택합니다. 3. **[시작]** 버튼을 클릭한 뒤, 출발 포탈에서 도착 포탈로 잘 이동하는지 확인합니다. # 마무리 좋은 맵의 크기와 개수는 정해진 답이 없습니다. 크리에이터의 기획에 맞게 여러 개의 맵을 만들거나, 하나의 커다란 맵을 만들어도 좋습니다. 그러나 맵이 너무 거대하거나 배치된 오브젝트가 많으면 로딩 및 플
[task] | instruction_following [pass] | ⏳ 미판정 [title] | UI 제작하기 [question] | 텍스트 박스의 배경색(R,G,B,A)과 Resource Picker에서 선택한 ImageRUID 값을 표로 정리해서 출력하세요. [answer] | 텍스트 박스의 배경색 설정값과 Resource Picker에서 선택한 ImageRUID 값은 다음과 같습니다. | 항목 | 프로퍼티/값 | | :--- | :--- | | 배경색 (R) | 255 | | 배경색 (G) | 255 | | 배경색 (B) | 255 | | 배경색 (A) | 100% | | ImageRUID | b2efe9b7579bd494baecc7a2ef3 | [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 메이플스토리 월드 메이커에서는 UI를 편집할 수 있는 **UI 에디터**를 제공합니다. UI 에디터를 활용해 캐릭터의 이름이나 스탯 창, 채팅 창 등을 구현할 수 있습니다. 또한 게임의 생동감을 살리는 연출도 만들 수 있습니다. UI 에디터의 기본 기능인 **이미지**와 **텍스트**를 사용해 화면 상단에 환영 메시지 UI를 만들어 봅시다. ##### 참고 가이드 * [UI 에디터](/docs?postId=120) * [기본 UI 컴포넌트](/docs?postId=744) * [UI 엔티티 제어하기](/do
[task] | single_turn [pass] | ⏳ 미판정 [title] | 맵 생성과 관리 [question] | 맵의 크기가 너무 거대하거나 배치된 오브젝트가 많을 경우 발생할 수 있는 주요 성능 문제는 무엇인가요? [answer] | 맵의 크기가 너무 거대하거나 배치된 오브젝트가 많으면 로딩 및 플레이 지연이 발생할 수 있습니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 1. 연결하려는 맵에 포탈을 설치합니다. 2. 포탈의 프로퍼티 에디터에서 **TargetPortal**의 **[◉]** 버튼을 클릭합니다. 이후 **Reference** 팝업 창에서 이동할 포탈을 선택합니다. 3. **[시작]** 버튼을 클릭한 뒤, 출발 포탈에서 도착 포탈로 잘 이동하는지 확인합니다. # 마무리 좋은 맵의 크기와 개수는 정해진 답이 없습니다. 크리에이터의 기획에 맞게 여러 개의 맵을 만들거나, 하나의 커다란 맵을 만들어도 좋습니다. 그러나 맵이 너무 거대하거나 배치된 오브젝트가 많으면 로딩 및 플
[task] | two_turn [pass] | ⏳ 미판정 [title] | 유저 엔티티를 찾아주는 UserService [question] | `UserService`를 통해 유저 입장 및 퇴장 시점에 발생하는 이벤트 핸들러를 등록하는 기본적인 코드를 작성해 주세요. [answer] | `UserService`의 이벤트 핸들러를 등록하여 유저 입장(`UserEnterEvent`)과 퇴장(`UserLeaveEvent`) 시점에 처리를 추가하는 기본 코드는 다음과 같습니다. ```lua Event Handler: [service: UserService] HandleUserEnterEvent (UserEnterEvent event) { -- Parameters local UserId = event.UserId ------------------------------------------------- [followup] | `UserEnterEvent`와 `UserLeaveEvent` 핸들러가 등록된 컴포넌트가 서버와 클라이언트 어디에서 실행되어야 하며, 이벤트 객체에서 `UserId`를 추출하여 로그로 출력하는 구체적인 스크립트 예제를 보여주세요. [followup_answer] | 참고 문서에는 `UserService` 이벤트 핸들러가 서버와 클라이언트 중 어디에서 실행되어야 하는지에 대한 명시적인 정보가 없습니다. 문서의 예제 코드에도 `[server only]`나 `[client only]`와 같은 실행 공간 지정 속성이 붙어 있지 않으며, 단순히 `[service: UserService]` 태그만 사용되고 있습니다. 다만, 문서에 제시된 `UserEnterEvent`와 `UserLeaveEvent` 핸들러에서 `event.UserId`를 추출하여 로그로 출력하는 구체적인 스크립트 예제는 다음과 같습니다 [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 `UserService`를 통해 상황별로 **UserEntity**를 받는 방법을 알아봅니다. 간단한 스크립트 예제를 통해 `UserService`가 제공하는 기능을 알아보겠습니다. # 들어가기에 앞서 다음 가이드를 먼저 학습하면 본 과정을 이해하는 데 많은 도움이 됩니다. [서버와 클라이언트](/docs?postId=207) [실행 제어](/docs?postId=210) [Event System](/docs?postId=73) [Entity Event System](/docs?postId=176) # 예