[task] | single_turn [pass] | ⏳ 미판정 [title] | 아이템 생성 및 삭제 [question] | 인벤토리 UI를 추가할 때 Preset List에서 선택해야 하는 두 가지 UI 컴포넌트의 정확한 이름은 무엇인가요? [answer] | 인벤토리 UI를 추가할 때 Preset List에서 선택해야 하는 두 가지 UI 컴포넌트의 정확한 이름은 **[인벤토리]** 와 **[버튼모음]** 입니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 이번에는 생성된 아이템을 표시할 인벤토리 UI를 추가합니다. 상단 메뉴에 버튼을 눌러 UI 에디터를 엽니다. **Preset List**에서 **[인벤토리]**, **[버튼모음]** UI를 추가합니다. 만일 **Inventory** 엔티티의 **UIInventory** 컴포넌트에 **InventoryBtnPath**가 비어있으면, 햄버거 메뉴를 열어 **Reset All Properties**를 선택합니다. 그러면 아래와 같이 정상적인 경로가 설정됩니다. # 아이템 엔티티 배치 및 기능 추가 버튼을 눌러 UI 편집모드를
[task] | code [pass] | ⏳ 미판정 [title] | 맵 생성과 관리 [question] | _OnUpdate(number delta) 에서 포탈의 TargetPortal 프로퍼티가 비어 있는지(Reference 팝업에서 선택 안 된 상태)를 매 프레임마다 체크하여 비어 있으면 log() 로 경고를 출력하는 스크립트를 작성해줘 [answer] | 제시된 참고 문서에는 포탈의 `TargetPortal` 프로퍼티가 비어 있는지 여부를 mLua 스크립트에서 직접 확인하거나, 해당 프로퍼티에 접근하기 위한 API가 명시되어 있지 않습니다. 문서에는 포탈 연결을 위한 에디터 조작 방법(Reference 팝업 선택)과 맵 크기 조절에 대한 가이드만 포함되어 있습니다. 따라서 요청하신 "포탈의 TargetPortal 프로퍼티가 비어 있는지 매 프레임마다 체크하는" 로직을 작성할 수 있는 mLua API가 참고 문서에 존재하지 않으므로, 해당 코드를 작성할 수 없습니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 1. 연결하려는 맵에 포탈을 설치합니다. 2. 포탈의 프로퍼티 에디터에서 **TargetPortal**의 **[◉]** 버튼을 클릭합니다. 이후 **Reference** 팝업 창에서 이동할 포탈을 선택합니다. 3. **[시작]** 버튼을 클릭한 뒤, 출발 포탈에서 도착 포탈로 잘 이동하는지 확인합니다. # 마무리 좋은 맵의 크기와 개수는 정해진 답이 없습니다. 크리에이터의 기획에 맞게 여러 개의 맵을 만들거나, 하나의 커다란 맵을 만들어도 좋습니다. 그러나 맵이 너무 거대하거나 배치된 오브젝트가 많으면 로딩 및 플
[task] | code [pass] | ⏳ 미판정 [title] | UI 제작하기 [question] | UIGroupComponent의 DefaultShow를 true로 설정하고 TextComponent의 Text 값을 "Welcome!"로 바꾸며 FontSize를 40으로 조정하는 스크립트를 작성해줘 [answer] | UIGroupComponent의 `DefaultShow`와 TextComponent의 `Text`, `FontSize`는 UI 에디터에서 직접 설정하는 프로퍼티입니다. mLua 스크립트에서 이 값들을 런타임에 변경하는 API는 제공되지 않습니다. 따라서 요청하신 내용은 스크립트로 구현할 수 없으며, **UI 에디터**에서 아래 단계에 따라 직접 설정해야 합니다. 1. **Hierarchy**에서 대상 `UIGroup`을 선택합니다. 2. **프로퍼티 에디터**에서 `UIGroupComponent`의 `DefaultShow`를 [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] | Data DB 저장 및 불러오기 [question] | _DataStorageService:GetGlobalDataStorage는 Server Only 함수라고 하는데, 클라이언트 공간에서 호출하면 어떤 오류가 발생하나요? [answer] | 제공된 참고 문서에는 `_DataStorageService:GetGlobalDataStorage`가 Server Only 함수임을 명시하고, 따라서 데이터 불러오기는 서버 공간에서 하는 것이 좋다고 권장하고 있습니다. 하지만 해당 함수를 **클라이언트 공간에서 호출했을 때 발생하는 구체적인 오류 메시지나 예외 유형에 대한 설명은 문서에 포함되어 있지 않습니다.** 문서에 따르면 이 함수는 서버 전용이며, 클라이언트에서의 사용은 권장되지 않으나, 실제 클라이언트에서 호출 시 나타나는 기술적 오류 상세 내역은 확인이 불가능합니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 게임 중 변경된 데이터 값을 GlobalDataStorage에 저장하고 불러오는 방법에 대해 알아봅니다. # Data 생성 및 불러오기 GlobalDataStorage는 데이터의 저장과 불러오기를 할 수 있는 "보관소"라 할 수 있습니다. 우리는 데이터베이스에서 데이터를 저장하거나 불러올 일이 있을 때 이 "보관소"를 이용하면 됩니다. GlobalDataStorage는 `_DataStorageService:GetGlobalDataStorage`를 통해 생성하거나 불러오기가 가능합니다. GetGlobalDat
[task] | single_turn [pass] | ⏳ 미판정 [title] | Data DB 저장 및 불러오기 [question] | GlobalDataStorage를 생성할 때 name 매개변수로 같은 값을 여러 번 넘겨주면 데이터가 초기화되는 건가요? [answer] | 아니요, 데이터가 초기화되지 않습니다. `_DataStorageService:GetGlobalDataStorage` 함수는 매개변수로 넘겨지는 `name` 값에 따라 동작이 결정됩니다. 이미 해당 `name` 값이 등록되어 있는 경우(즉, 이전에 생성된 GlobalDataStorage가 존재하는 경우), 새로 생성하는 것이 아니라 **이전에 생성했던 동일한 GlobalDataStorage 객체를 반환**합니다. 따라서 같은 `name`으로 여러 번 호출하더라도 기존에 저장된 데이터가 지워지거나 초기화되는 현상은 발생하지 않으며, [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 게임 중 변경된 데이터 값을 GlobalDataStorage에 저장하고 불러오는 방법에 대해 알아봅니다. # Data 생성 및 불러오기 GlobalDataStorage는 데이터의 저장과 불러오기를 할 수 있는 "보관소"라 할 수 있습니다. 우리는 데이터베이스에서 데이터를 저장하거나 불러올 일이 있을 때 이 "보관소"를 이용하면 됩니다. GlobalDataStorage는 `_DataStorageService:GetGlobalDataStorage`를 통해 생성하거나 불러오기가 가능합니다. GetGlobalDat
[task] | single_turn [pass] | ⏳ 미판정 [title] | Data DB 저장 및 불러오기 [question] | GlobalDataStorage에 저장된 데이터를 다른 스크립트 컴포넌트에서 바로 접근할 수 없다면, 데이터를 공유하는 권장 방식이 있나요? [answer] | 제시된 참고 문서에는 `GlobalDataStorage`에 저장된 데이터를 다른 스크립트 컴포넌트에서 직접(직접 참조를 통해) 접근하는 방법이나, 스크립트 컴포넌트 간 데이터 공유를 위한 권장 방식(이벤트 발행/구독, 공용 테이블 공유 등)에 대한 설명이 포함되어 있지 않습니다. 문서에 명시된 내용만으로는 다른 컴포넌트와의 데이터 공유 방식을 답변할 수 없습니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 게임 중 변경된 데이터 값을 GlobalDataStorage에 저장하고 불러오는 방법에 대해 알아봅니다. # Data 생성 및 불러오기 GlobalDataStorage는 데이터의 저장과 불러오기를 할 수 있는 "보관소"라 할 수 있습니다. 우리는 데이터베이스에서 데이터를 저장하거나 불러올 일이 있을 때 이 "보관소"를 이용하면 됩니다. GlobalDataStorage는 `_DataStorageService:GetGlobalDataStorage`를 통해 생성하거나 불러오기가 가능합니다. GetGlobalDat
[task] | single_turn [pass] | ⏳ 미판정 [title] | Data DB 저장 및 불러오기 [question] | name 값이 다른 GlobalDataStorage 여러 개를 동시에 생성하면 서버 성능에 영향을 주나요? [answer] | 제공된 문서에는 `GlobalDataStorage`를 여러 개 생성했을 때 서버 성능에 미치는 영향에 대한 정보가 포함되어 있지 않습니다. 문서에서는 `_DataStorageService:GetGlobalDataStorage`에 다른 `name` 값을 전달하면 각각의 `GlobalDataStorage`가 생성되거나 기존 것이 반환되며, 이를 통해 데이터의 속성이나 용도에 따라 데이터를 구분하여 저장할 수 있다고만 설명하고 있습니다. 성능에 대한 언급은 없으므로, 이 질문에 대한 정확한 답변은 문서 근거로 드릴 수 없습니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 게임 중 변경된 데이터 값을 GlobalDataStorage에 저장하고 불러오는 방법에 대해 알아봅니다. # Data 생성 및 불러오기 GlobalDataStorage는 데이터의 저장과 불러오기를 할 수 있는 "보관소"라 할 수 있습니다. 우리는 데이터베이스에서 데이터를 저장하거나 불러올 일이 있을 때 이 "보관소"를 이용하면 됩니다. GlobalDataStorage는 `_DataStorageService:GetGlobalDataStorage`를 통해 생성하거나 불러오기가 가능합니다. GetGlobalDat
[task] | instruction_following [pass] | ⏳ 미판정 [title] | Data DB 저장 및 불러오기 [question] | `GetAsync` 함수가 비동기식으로 동작하여 콜백 함수 등록이 필요한 이유를 3문장 이내로 설명하세요. [answer] | `GetAsync`는 비동기식으로 동작하여 데이터 조회 요청을 보낸 후 값이 언제 도착할지 보장되지 않기 때문입니다. 따라서 값을 즉시 반환받지 못하고, 데이터가 실제로 도착했을 때 처리하기 위해 콜백 함수를 등록해야 합니다. 이 콜백 함수를 통해 전달된 `key`와 `value`를 받아 저장된 데이터를 안전하게 활용할 수 있습니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `GetAsync`는 데이터를 불러오기 위한 함수로 value 값 저장 시 함께 저장된 key 값을 통해 value 값을 가져옵니다. 이때 GetAsync도 SetAsync와 마찬가지로 key 값에 해당하는 value 값을 요청하게 되는데, 요청한 value 값을 함수 내에서 직접 리턴 받는 것이 아닌 GetAsync에 등록한 콜백 함수의 매개 변수로 key 값과 함께 들어옵니다. 이유는 GetAsync 역시 비동기식으로 동작을 하기 때문에 불러오기 요청을 보냈을 때 value 값을 언제 보내줄지는 보장되지 않기 때문입니다. 따라서
[task] | instruction_following [pass] | ⏳ 미판정 [title] | Data DB 저장 및 불러오기 [question] | 테스트 플레이 중 저장된 데이터의 초기화 방법을 단계별 번호 목록으로 정리하세요. [answer] | 테스트 플레이 중 저장된 데이터는 플레이를 종료해도 사라지지 않고 유지됩니다. 이를 초기화하는 방법은 다음과 같습니다. 1. 설정(Setting) 메뉴로 이동합니다. 2. 만들기(메이킹) 섹션을 선택합니다. 3. 데이터 스토리지 설정으로 진입합니다. 4. 해당 설정 화면에서 데이터 초기화를 수행합니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `GetAsync`는 데이터를 불러오기 위한 함수로 value 값 저장 시 함께 저장된 key 값을 통해 value 값을 가져옵니다. 이때 GetAsync도 SetAsync와 마찬가지로 key 값에 해당하는 value 값을 요청하게 되는데, 요청한 value 값을 함수 내에서 직접 리턴 받는 것이 아닌 GetAsync에 등록한 콜백 함수의 매개 변수로 key 값과 함께 들어옵니다. 이유는 GetAsync 역시 비동기식으로 동작을 하기 때문에 불러오기 요청을 보냈을 때 value 값을 언제 보내줄지는 보장되지 않기 때문입니다. 따라서
[task] | single_turn [pass] | ⏳ 미판정 [title] | 아이템 생성 및 삭제 [question] | 아이템을 생성할 때 _ItemService:CreateItem 메서드의 첫 번째 인자로 전달하는 값은 itemNames 테이블의 어떤 요소를 의미하나요? [answer] | `_ItemService:CreateItem` 메서드의 첫 번째 인자로 전달되는 `getItemName[2]`는 `itemNames` 테이블의 각 요소에서 **두 번째 값**을 의미하며, 이는 **아이템 타입(Item Type)** 입니다. 참고 문서의 `GiftBox` 스크립트 예제를 보면 `itemNames` 테이블은 다음과 같이 구성됩니다. ```lua local itemNames = {{"RedPotion",Potion}, {"BluePotion",Potion}, {"IronSword",Weapon}, [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 이번에는 생성된 아이템을 표시할 인벤토리 UI를 추가합니다. 상단 메뉴에 버튼을 눌러 UI 에디터를 엽니다. **Preset List**에서 **[인벤토리]**, **[버튼모음]** UI를 추가합니다. 만일 **Inventory** 엔티티의 **UIInventory** 컴포넌트에 **InventoryBtnPath**가 비어있으면, 햄버거 메뉴를 열어 **Reset All Properties**를 선택합니다. 그러면 아래와 같이 정상적인 경로가 설정됩니다. # 아이템 엔티티 배치 및 기능 추가 버튼을 눌러 UI 편집모드를
[task] | single_turn [pass] | ⏳ 미판정 [title] | 아이템 생성 및 삭제 [question] | TriggerEnterEvent 핸들러에서 충돌한 엔티티의 인벤토리를 확인하는 과정에서 nil 체크가 실패하면 어떤 동작이 수행되나요? [answer] | `TriggerEnterEvent` 핸들러에서 충돌한 엔티티의 인벤토리를 확인하는 과정에서 nil 체크가 실패하면, 해당 함수의 처리를 즉시 중단하고 리턴(`return`)합니다. 이는 충돌한 엔티티에 `InventoryComponent`가 없거나 접근할 수 없는 경우(즉, `inventory`가 `nil`인 경우)에 수행되는 동작입니다. 이 early return 덕분에, 인벤토리가 없는 엔티티와 충돌했을 때后续的 아이템 생성 로직이 실행되지 않아 에러가 발생하는 것을 방지합니다. 참고 문서의 예제 코드에서 이 로직은 다음과 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 이번에는 생성된 아이템을 표시할 인벤토리 UI를 추가합니다. 상단 메뉴에 버튼을 눌러 UI 에디터를 엽니다. **Preset List**에서 **[인벤토리]**, **[버튼모음]** UI를 추가합니다. 만일 **Inventory** 엔티티의 **UIInventory** 컴포넌트에 **InventoryBtnPath**가 비어있으면, 햄버거 메뉴를 열어 **Reset All Properties**를 선택합니다. 그러면 아래와 같이 정상적인 경로가 설정됩니다. # 아이템 엔티티 배치 및 기능 추가 버튼을 눌러 UI 편집모드를
[task] | code [pass] | ⏳ 미판정 [title] | 아이템 생성 및 삭제 [question] | 맵 위의 특정 아이템을 터치했을 때, 인벤토리에 있는 모든 아이템을 순회하며 삭제하는 로직을 포함하는 스크립트를 작성해줘 [answer] | 맵 위의 특정 아이템을 터치했을 때 인벤토리의 모든 아이템을 삭제하는 로직은 `HandleTriggerEnterEvent` 이벤트 핸들러를 사용하여 구현할 수 있습니다. 참고 문서에 따르면, 인벤토리에 접근하기 위해 `self.Entity.InventoryComponent`를 사용하고, 인벤토리의 아이템 목록을 가져오기 위해 `inventory:GetItemList()` 메서드를 호출해야 합니다. 아이템 목록은 배열(테이블)로 반환되며, 각 아이템은 `_ItemService:RemoveItem(item)` 메서드를 통해 삭제할 수 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 이번 과정에서는 아이템 생성과 삭제 기능을 알아봅니다. 제작할 예제는 다음과 같습니다. * 맵에 놓인 아이템을 먹을 때마다 인벤토리에 랜덤한 아이템이 생성 * 아이템을 먹으면, 5초 뒤 아이템이 놓여있던 자리에 다시 생성 * 맵에 놓인 다른 아이템을 먹을 때마다 인벤토리에 있는 모든 아이템 삭제 # 아이템 테이블 만들기 먼저 개별 아이템을 만들어 봅시다. 개별 아이템은 아이템 테이블에서 정의할 수 있습니다. 아이템 테이블은 **DataSet**으로 만듭니다. **Workspace - MyDesk**에서 콘
[task] | two_turn [pass] | ⏳ 미판정 [title] | 아이템 생성 및 삭제 [question] | 아이템 생성 시 `UserItemDataSet`의 데이터를 아이템 객체에 어떻게 전달하고 초기화하는지? [answer] | 아이템이 생성되면 `OnCreate()` 함수가 자동으로 호출되며, 이 과정에서 `UserItemDataSet`에 정의된 데이터가 아이템 객체로 전달됩니다. 전달된 데이터는 `self.ItemTableData:GetItem("컬럼명")` 형식으로 접근하여 초기화합니다. 아래는 `UserItemDataSet`의 `Name`, `MaxStackCount`, `EffectAmount` 컬럼 데이터를 읽어와 아이템 객체의 프로퍼티에 초기화하는 `OnCreate()` 함수 예시입니다. ```lua void OnCreate() { [followup] | `OnCreate()`에서 `self.ItemTableData:GetItem()`로 컬럼 값을 가져올 때, 숫자 타입 변환(`tonumber`)이 필요한 이유와 예외 처리는 어떻게 하나? [followup_answer] | 참고 문서에 따르면, `UserItemDataSet`의 `MaxStackCount`와 `EffectAmount` 컬럼 값은 `tonumber()` 함수를 사용하여 숫자 타입으로 변환한 뒤 프로퍼티에 할당해야 합니다. 이는 아이템 테이블에서 가져온 데이터가 문자열 형태로 전달될 수 있어, 숫자 연산이나 비교가 가능하도록 명시적으로 변환하기 위한 것입니다. 다만, 제공된 참고 문서에는 `tonumber()` 변환 실패 시의 예외 처리 방법이나 `nil` 값 체크에 대한 구체적인 코드가 포함되어 있지 않습니다. 따라서 문서 범위 내에서 [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 이번 과정에서는 아이템 생성과 삭제 기능을 알아봅니다. 제작할 예제는 다음과 같습니다. * 맵에 놓인 아이템을 먹을 때마다 인벤토리에 랜덤한 아이템이 생성 * 아이템을 먹으면, 5초 뒤 아이템이 놓여있던 자리에 다시 생성 * 맵에 놓인 다른 아이템을 먹을 때마다 인벤토리에 있는 모든 아이템 삭제 # 아이템 테이블 만들기 먼저 개별 아이템을 만들어 봅시다. 개별 아이템은 아이템 테이블에서 정의할 수 있습니다. 아이템 테이블은 **DataSet**으로 만듭니다. **Workspace - MyDesk**에서 콘
[task] | instruction_following [pass] | ⏳ 미판정 [title] | Data DB 저장 및 불러오기 [question] | GlobalDataStorage의 SetAsync 메서드가 비동기적으로 실행되는 이유와 콜백 함수를 통해 저장 완료 시점에 처리를 해야 하는 이유를 3문장 이내로 설명하세요. [answer] | SetAsync는 DB가 요청 순서대로 처리해야 하므로 호출 즉시 저장이 완료되지 않으며, 실제 저장 시점이 보장되지 않기 때문에 비동기식으로 실행됩니다. 따라서 저장 직후 코드를 바로 실행하면 데이터가 아직 DB에 반영되지 않은 상태일 수 있어 오류가 발생할 수 있습니다. 이를 방지하기 위해 콜백 함수를 전달하여 값이 실제로 저장된 시점에 후속 처리가 이루어지도록 해야 합니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 데이터의 저장은 GlobalDataStorage의 SetAsync를 활용해 할 수 있습니다. `SetAsync`는 매개 변수로 key와 value, 그리고 콜백 함수를 받는데, 저장할 데이터가 있으면 key와 value 매개 변수로 값을 넘겨 저장하게 됩니다. key는 매번 변경되어 저장되는 value 값을 불러오기 위한 용도로 사용됩니다. 따라서 key 값으로는 프로퍼티 명이나 혹은 저장된 value 값이 의미하는 것으로 입력해 주는 것이 좋습니다. 예를 들어 power라는 프로퍼티(또는 스탯)의 값을 저장한다면 key에는 "Po
[task] | code [pass] | ⏳ 미판정 [title] | UI 제작하기 [question] | SpriteGUIRendererComponent의 Color 프로퍼티를 R:255, G:255, B:255, A:100%로 설정하고 ImageRUID를 b2efe9b7579bd494baecc7a2ef3으로 변경하는 스크립트를 작성해줘 [answer] | 참고 문서에 포함된 예제와 설명을 기준으로, `SpriteGUIRendererComponent`의 `Color`와 `ImageRUID`를 요청하신 값으로 설정하는 mLua 스크립트를 작성했습니다. 1. **Color 설정**: 문서의 "텍스트 박스의 배경색을 변경합니다" 섹션에서 R:255, G:255, B:255, A:100%는 흰색(White)에 해당하며, mLua 코드 예제에서는 `Color.white` 또는 RGBA 값을 사용해 설정하는 것을 확인할 수 있습니다. 2. **ImageRUID 설정**: 문서에서 지정한 R [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 메이플스토리 월드 메이커에서는 UI를 편집할 수 있는 **UI 에디터**를 제공합니다. UI 에디터를 활용해 캐릭터의 이름이나 스탯 창, 채팅 창 등을 구현할 수 있습니다. 또한 게임의 생동감을 살리는 연출도 만들 수 있습니다. UI 에디터의 기본 기능인 **이미지**와 **텍스트**를 사용해 화면 상단에 환영 메시지 UI를 만들어 봅시다. ##### 참고 가이드 * [UI 에디터](/docs?postId=120) * [기본 UI 컴포넌트](/docs?postId=744) * [UI 엔티티 제어하기](/do
[task] | code [pass] | ⏳ 미판정 [title] | Data DB 저장 및 불러오기 [question] | `_DataStorageService:GetGlobalDataStorage`를 통해 "Data" 스토리지에서 "Power" 키의 값을 `GetAsync`로 비동기적으로 불러오고, 콜백에서 `value`가 `nil`인 경우 기본값 0으로 처리한 후 `self.Power` 프로퍼티에 적용하는 [server only] `OnBeginPlay` 스크립트를 작성해줘. [answer] | `_DataStorageService:GetGlobalDataStorage`로 "Data" 스토리지 객체를 가져오고, `GetAsync`에 "Power" 키와 콜백 함수를 전달하여 값을 비동기적으로 불러옵니다. 콜백 함수의 매개변수로 받은 `value`가 `nil`인지 확인하여 기본값 0을 대입한 뒤, `tonumber`로 변환하여 `self.Power`에 저장합니다. ```lua Property: [Sync] number Power = 0 Method: [server only] void OnBeginPlay() { [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `GetAsync`는 데이터를 불러오기 위한 함수로 value 값 저장 시 함께 저장된 key 값을 통해 value 값을 가져옵니다. 이때 GetAsync도 SetAsync와 마찬가지로 key 값에 해당하는 value 값을 요청하게 되는데, 요청한 value 값을 함수 내에서 직접 리턴 받는 것이 아닌 GetAsync에 등록한 콜백 함수의 매개 변수로 key 값과 함께 들어옵니다. 이유는 GetAsync 역시 비동기식으로 동작을 하기 때문에 불러오기 요청을 보냈을 때 value 값을 언제 보내줄지는 보장되지 않기 때문입니다. 따라서
[task] | code [pass] | ⏳ 미판정 [title] | UI 제작하기 [question] | UITransformComponent의 PosX를 0, PosY를 400, Width를 500, Height를 100으로 설정하여 UI 요소를 화면 상단 중앙에 배치하는 스크립트를 작성해줘 [answer] | 메이플스토리 월드의 UI 에디터에서 UI 요소를 화면 상단 중앙에 배치하려면, 해당 UI 엔티티에 붙은 `UITransformComponent`의 `Position`과 `Size` 프로퍼티를 수정하면 됩니다. 참고 문서에 따르면, UI 에디터의 프로퍼티 에디터에서 `UITransformComponent`의 `PosX`, `PosY`, `Width`, `Height` 값을 직접 입력하는 방식으로 설정합니다. 스크립트로 이 값을 설정하려면, 해당 UI 엔티티를 참조한 후 `UITransformComponent`의 `Position`( [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] | Data DB 저장 및 불러오기 [question] | 테스트 플레이 중에 저장한 데이터가 플레이를 종료해도 지워지지 않는 건 정상이고, 초기화는 어디서 하나요? [answer] | 네, 테스트 플레이 중에 저장한 데이터는 플레이를 종료해도 사라지지 않고 유지되는 것이 정상입니다. 초기화는 **Setting - 만들기 - 데이터 스토리지 설정**에서 수행할 수 있습니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `GetAsync`는 데이터를 불러오기 위한 함수로 value 값 저장 시 함께 저장된 key 값을 통해 value 값을 가져옵니다. 이때 GetAsync도 SetAsync와 마찬가지로 key 값에 해당하는 value 값을 요청하게 되는데, 요청한 value 값을 함수 내에서 직접 리턴 받는 것이 아닌 GetAsync에 등록한 콜백 함수의 매개 변수로 key 값과 함께 들어옵니다. 이유는 GetAsync 역시 비동기식으로 동작을 하기 때문에 불러오기 요청을 보냈을 때 value 값을 언제 보내줄지는 보장되지 않기 때문입니다. 따라서
[task] | instruction_following [pass] | ⏳ 미판정 [title] | Data DB 저장 및 불러오기 [question] | value 값이 nil일 때를 처리하는 로직이 포함된 `OnBeginPlay` 함수 코드를 출력하되, 설명은 주석으로만 작성하세요. [answer] | ```lua Property: [Sync] number Power = 0 Method: [server only] void OnBeginPlay() { -- 전역 데이터 스토리지 "Data" 인스턴스를 가져옵니다. local data = _DataStorageService:GetGlobalDataStorage("Data") -- GetAsync 호출 시 데이터가 도착하면 실행되는 콜백 함수를 정의합니다. local callBack = function(errorcode, key, value) [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `GetAsync`는 데이터를 불러오기 위한 함수로 value 값 저장 시 함께 저장된 key 값을 통해 value 값을 가져옵니다. 이때 GetAsync도 SetAsync와 마찬가지로 key 값에 해당하는 value 값을 요청하게 되는데, 요청한 value 값을 함수 내에서 직접 리턴 받는 것이 아닌 GetAsync에 등록한 콜백 함수의 매개 변수로 key 값과 함께 들어옵니다. 이유는 GetAsync 역시 비동기식으로 동작을 하기 때문에 불러오기 요청을 보냈을 때 value 값을 언제 보내줄지는 보장되지 않기 때문입니다. 따라서
[task] | code [pass] | ⏳ 미판정 [title] | 맵 생성과 관리 [question] | 유저가 포탈을 통해 다른 맵으로 이동할 때 _UserService 의 UserEnterEvent 를 통해 새 맵 진입을 감지하고, _SpawnService 를 사용하여 환영 메시지를 표시하는 UI 엔티티를 생성하는 스크립트를 작성해줘 [answer] | 제공된 참고 문서에는 `_UserService`의 `HandleUserEnterEvent` 처리 방식과 `_SpawnService`의 사용 예제(`SpawnByModelId`)가 포함되어 있습니다. 하지만 **UI 엔티티 생성에 사용할 구체적인 모델 ID**, **환영 메시지에 사용할 텍스트 설정 방법(컴포넌트 프로퍼티 등)**, 그리고 **포탈 이동과 `UserEnterEvent`의 직접적인 연결 메커니즘**에 대한 API 문서가 제공되지 않았습니다. 따라서 요청하신 "UI 엔티티를 생성하여 환영 메시지를 표시"하는 부분은 문서 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 다양한 맵은 월드를 탐험하는 유저들에게 다채로운 재미를 선사합니다. 이번 과정에서는 맵 생성과 관리 방법을 알아봅시다. # 맵 관리 방법 맵 관리 방법에는 2가지가 있습니다. * **Hierarchy - maps** 하위 엔트리의 콘텍스트 메뉴를 통해 관리 * **Window - Map List** 창에서 관리 # 새 맵 만들기 | Hierarchy | Map List | | ----------- | ------- | | **Hierarchy - maps**의 콘텍스트 메뉴에서 **Create New M
[task] | code [pass] | ⏳ 미판정 [title] | 맵 생성과 관리 [question] | 포탈의 TargetPortal 프로퍼티를 참조하여 도착 포탈의 위치를 조회하고, 해당 좌표에서 _EntityService:GetEntityByPath("/maps/map01/obj") 를 이용해 오브젝트를 찾아서 log() 로 출력하는 스크립트를 작성해줘 [answer] | 제시된 참고 문서에는 포탈의 `TargetPortal` 프로퍼티를 참조하여 **도착 포탈의 좌표(Position)** 를 직접 조회하는 API가 언급되어 있지 않습니다. 문서에 명시된 포탈 연결 방법은 `TargetPortal` 프로퍼티의 `[◉]` 버튼을 통해 다른 포탈 엔티티를 **참조(Reference)** 하는 방식이며, 이는 포탈 간의 이동 연결을 위한 설정입니다. 하지만 스크립트(mLua) 코드에서 이 참조된 대상 포탈의 좌표 값을 읽어오는 구체적인 메서드나 프로퍼티 경로(예: `self.PortalComponent.T [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 1. 연결하려는 맵에 포탈을 설치합니다. 2. 포탈의 프로퍼티 에디터에서 **TargetPortal**의 **[◉]** 버튼을 클릭합니다. 이후 **Reference** 팝업 창에서 이동할 포탈을 선택합니다. 3. **[시작]** 버튼을 클릭한 뒤, 출발 포탈에서 도착 포탈로 잘 이동하는지 확인합니다. # 마무리 좋은 맵의 크기와 개수는 정해진 답이 없습니다. 크리에이터의 기획에 맞게 여러 개의 맵을 만들거나, 하나의 커다란 맵을 만들어도 좋습니다. 그러나 맵이 너무 거대하거나 배치된 오브젝트가 많으면 로딩 및 플
[task] | two_turn [pass] | ⏳ 미판정 [title] | 맵 생성과 관리 [question] | 맵 관리 방법(Hierarchy와 Map List 창)의 차이점과 기본 생성 절차는 무엇인가요? [answer] | 맵 관리에는 **Hierarchy - maps** 하위 엔트리의 콘텍스트 메뉴를 이용하는 방법과 **Window - Map List** 창을 이용하는 방법의 2가지가 있습니다. 두 방법의 차이점과 기본 생성 절차는 다음과 같습니다. ### 1. 새 맵 만들기 (기본 생성 절차) * **Hierarchy - maps 사용 시**: `Hierarchy - maps`의 콘텍스트 메뉴에서 **Create New Map**을 클릭합니다. * **Map List 창 사용 시**: 1. `Map List` 창 하단에서 **[ [followup] | 시작 맵과 현재 작업 중인 맵은 삭제할 수 없는 제한 사항이 있는 이유와, '시작 맵'과 '게임 시작 위치'의 개념적 차이를 설명해 주세요. [followup_answer] | ### 1. 시작 맵과 현재 작업 중인 맵의 삭제 불가 이유 참고 문서에는 삭제 불가 제한 사항에 대한 **구체적인 기술적 이유**가 명시되어 있지 않습니다. 다만, 문서에서 확인되는 사실은 다음과 같습니다. * **제한 사항**: **시작 맵**과 **현재 Scene에서 작업 중인 맵**은 삭제할 수 없습니다. * **관련 개념**: * 시작 맵은 출시한 월드를 실행했을 때 플레이어 아바타가 처음 들어가는 맵입니다. * 게임 제작 중에 테스트를 위해 플레이할 경우, 작업 중인 맵에서 바로 시작합니다 [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 다양한 맵은 월드를 탐험하는 유저들에게 다채로운 재미를 선사합니다. 이번 과정에서는 맵 생성과 관리 방법을 알아봅시다. # 맵 관리 방법 맵 관리 방법에는 2가지가 있습니다. * **Hierarchy - maps** 하위 엔트리의 콘텍스트 메뉴를 통해 관리 * **Window - Map List** 창에서 관리 # 새 맵 만들기 | Hierarchy | Map List | | ----------- | ------- | | **Hierarchy - maps**의 콘텍스트 메뉴에서 **Create New M
[task] | instruction_following [pass] | ⏳ 미판정 [title] | Data DB 저장 및 불러오기 [question] | Power 프로퍼티의 값을 "Power"라는 키로 GlobalDataStorage에 비동기 저장하고, 저장 완료 시점에 로그를 출력하는 mLua 스크립트 코드만 출력하되, 설명은 주석으로 작성하세요. [answer] | ```lua Property: [Sync] number Power = 100 Method: [server only] void SavePower() { -- GlobalDataStorage 인스턴스를 가져옵니다. local data = _DataStorageService:GetGlobalDataStorage("data") -- 저장 완료 시점에 호출될 콜백 함수를 정의합니다. -- 매개변수 errorcode와 key를 받습니다. local callback = function(errorcode, [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 데이터의 저장은 GlobalDataStorage의 SetAsync를 활용해 할 수 있습니다. `SetAsync`는 매개 변수로 key와 value, 그리고 콜백 함수를 받는데, 저장할 데이터가 있으면 key와 value 매개 변수로 값을 넘겨 저장하게 됩니다. key는 매번 변경되어 저장되는 value 값을 불러오기 위한 용도로 사용됩니다. 따라서 key 값으로는 프로퍼티 명이나 혹은 저장된 value 값이 의미하는 것으로 입력해 주는 것이 좋습니다. 예를 들어 power라는 프로퍼티(또는 스탯)의 값을 저장한다면 key에는 "Po
[task] | code [pass] | ⏳ 미판정 [title] | UI 제작하기 [question] | UIGroupComponent의 DefaultShow를 활성화하여 UI 그룹이 플레이 화면에서 항상 보이도록 만드는 스크립트를 작성해줘 [answer] | `UIGroupComponent`의 `DefaultShow` 프로퍼티를 `true`로 설정하면 해당 UI 그룹이 플레이 화면에서 기본적으로 항상 보이도록 됩니다. 참고 문서에 제시된 실제 mLua 코드 예제에는 `UIGroupComponent`에 직접 접근하여 `DefaultShow` 값을 변경하는 스크립트가 포함되어 있지 않습니다. 문서에서는 UI 에디터의 프로퍼티 에디터에서 해당 값을 설정하는 방법을 설명하고 있으며, 스크립트 예제는 주로 `_EntityService`, `_SpawnService`, `_SoundService [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] | Data DB 저장 및 불러오기 [question] | SetAsync 메서드의 매개 변수(key, value, 콜백 함수)와 각 매개 변수의 역할을 3열 구조의 표로 정리하세요. [answer] | `SetAsync` 메서드의 매개 변수와 역할을 정리한 표입니다. | 매개 변수 | 역할 | | :--- | :--- | | **key** | 저장할 데이터를 식별하기 위한 고유 키입니다. 데이터를 불러올 때 이 키를 사용하여 해당 값을 찾으며, 같은 키로 다시 저장하면 이전 값을 덮어씁니다. 프로퍼티 이름이나 데이터의 의미를 나타내는 문자열을 사용하는 것이 좋습니다. | | **value** | 실제로 저장할 데이터 값입니다. 문서 예시와 같이 숫자 등 다른 타입의 값은 `tostring` 등을 사용하여 문자열(string)로 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 데이터의 저장은 GlobalDataStorage의 SetAsync를 활용해 할 수 있습니다. `SetAsync`는 매개 변수로 key와 value, 그리고 콜백 함수를 받는데, 저장할 데이터가 있으면 key와 value 매개 변수로 값을 넘겨 저장하게 됩니다. key는 매번 변경되어 저장되는 value 값을 불러오기 위한 용도로 사용됩니다. 따라서 key 값으로는 프로퍼티 명이나 혹은 저장된 value 값이 의미하는 것으로 입력해 주는 것이 좋습니다. 예를 들어 power라는 프로퍼티(또는 스탯)의 값을 저장한다면 key에는 "Po
[task] | two_turn [pass] | ⏳ 미판정 [title] | 아이템 생성 및 삭제 [question] | 인벤토리 UI와 GiftBox 스크립트를 활용해 아이템 생성 및 삭제 기능을 구현하는 기본 절차는 무엇인가요? [answer] | 인벤토리 UI와 GiftBox 스크립트를 활용한 아이템 생성 및 삭제 기능 구현 절차는 다음과 같습니다. **1. 인벤토리 UI 설정** 1. 상단 메뉴에서 UI 에디터를 엽니다. 2. **Preset List**에서 **[인벤토리]** 및 **[버튼모음]** UI를 추가합니다. 3. **Inventory** 엔티티의 **UIInventory** 컴포넌트에서 `InventoryBtnPath`가 비어있다면, 햄버거 메뉴의 **Reset All Properties**를 선택하여 정상적인 경로가 설정되도록 합니다. **2. 아이템 엔 [followup] | InventoryBtnPath가 비어있는 경우 Reset All Properties로 경로 설정을 복구하는 구체적인 방법과, `_ItemService:CreateItem` 호출 시 타입 인자(Potion, Weapon 등)와 이름 인자의 순서 및 의미를 명확히 설명해 주세요. [followup_answer] | **1. InventoryBtnPath 복구 방법** Inventory 엔티티의 UIInventory 컴포넌트에서 `InventoryBtnPath`가 비어있는 경우, 해당 컴포넌트 옆의 햄버거 메뉴를 열어 **Reset All Properties**를 선택하면 정상적인 경로가 자동으로 설정됩니다. **2. `_ItemService:CreateItem` 인자 순서 및 의미** `_ItemService:CreateItem` 함수를 호출할 때의 인자 순서와 의미는 다음과 같습니다. * **1번째 인자 (타입):** 아이템의 타입을 [scores] | [judge_reason] | [source_doc] | 이번에는 생성된 아이템을 표시할 인벤토리 UI를 추가합니다. 상단 메뉴에 버튼을 눌러 UI 에디터를 엽니다. **Preset List**에서 **[인벤토리]**, **[버튼모음]** UI를 추가합니다. 만일 **Inventory** 엔티티의 **UIInventory** 컴포넌트에 **InventoryBtnPath**가 비어있으면, 햄버거 메뉴를 열어 **Reset All Properties**를 선택합니다. 그러면 아래와 같이 정상적인 경로가 설정됩니다. # 아이템 엔티티 배치 및 기능 추가 버튼을 눌러 UI 편집모드를
[task] | single_turn [pass] | ⏳ 미판정 [title] | Data DB 저장 및 불러오기 [question] | GetAsync 함수는 왜 값을 직접 리턴받지 못하고 콜백 함수를 등록해야만 하는 건가요? [answer] | `GetAsync`는 데이터를 비동기적으로 불러오는 함수이기 때문에, 요청을 보낸 시점에 바로 값을 받을 수 없습니다. 데이터가 언제 준비되어 도착할지 보장되지 않으므로, 값을 직접 리턴하는 방식 대신 값을 받았을 때 실행할 콜백 함수를 등록해야 합니다. 콜백 함수는 `errorcode`, `key`, `value` 세 가지 매개 변수를 받으며, 데이터가 도착하면 이 함수가 호출되어 `value`를 처리하게 됩니다. ```lua Property: [Sync] number Power = 0 Method: [server on [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `GetAsync`는 데이터를 불러오기 위한 함수로 value 값 저장 시 함께 저장된 key 값을 통해 value 값을 가져옵니다. 이때 GetAsync도 SetAsync와 마찬가지로 key 값에 해당하는 value 값을 요청하게 되는데, 요청한 value 값을 함수 내에서 직접 리턴 받는 것이 아닌 GetAsync에 등록한 콜백 함수의 매개 변수로 key 값과 함께 들어옵니다. 이유는 GetAsync 역시 비동기식으로 동작을 하기 때문에 불러오기 요청을 보냈을 때 value 값을 언제 보내줄지는 보장되지 않기 때문입니다. 따라서
[task] | code [pass] | ⏳ 미판정 [title] | 아이템 생성 및 삭제 [question] | _TouchEvent 를 통해 맵 위의 아이템을 터치했을 때 해당 아이템을 삭제하고, _TimerService:SetTimerOnce() 로 5초 후 _SpawnService:SpawnByModelId() 를 이용해 같은 위치에 아이템을 다시 생성하는 스크립트를 작성해줘 [answer] | 요청하신 기능을 구현하기 위해, 아이템을 터치하면 삭제되고 5초 후 원래 위치에 다시 생성되는 로직을 작성했습니다. 1. **`HandleTouchEvent`**: 아이템을 터치한 감지를 위해 사용하며, 터치한 대상이 아이템인지 확인 후 삭제 위치를 저장하고 아이템을 삭제합니다. 2. **`_TimerService:SetTimerOnce`**: 5초 후 실행될 함수를 등록합니다. 3. **`_SpawnService:SpawnByModelId`**: 저장된 위치에 아이템을 다시 생성합니다. 참고로, `_SpawnService [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 이번 과정에서는 아이템 생성과 삭제 기능을 알아봅니다. 제작할 예제는 다음과 같습니다. * 맵에 놓인 아이템을 먹을 때마다 인벤토리에 랜덤한 아이템이 생성 * 아이템을 먹으면, 5초 뒤 아이템이 놓여있던 자리에 다시 생성 * 맵에 놓인 다른 아이템을 먹을 때마다 인벤토리에 있는 모든 아이템 삭제 # 아이템 테이블 만들기 먼저 개별 아이템을 만들어 봅시다. 개별 아이템은 아이템 테이블에서 정의할 수 있습니다. 아이템 테이블은 **DataSet**으로 만듭니다. **Workspace - MyDesk**에서 콘
[task] | instruction_following [pass] | ⏳ 미판정 [title] | 데이터 편집 [question] | 데이터 에디터에서 행과 열의 번호가 시작되는 위치와 `GetCell` 함수의 매개 변수 의미를 2문장 이내로 설명하세요. [answer] | 행과 열의 번호는 모두 1부터 시작하며, `GetCell` 함수의 매개 변수로는 셀이 위치한 행 번호와 열 번호를 입력해야 합니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 데이터 셋을 이용해 데이터를 추가하거나 수정할 수 있습니다. 이번 가이드에서는 데이터의 생성 및 편집 방법, 스크립트로 데이터를 불러오는 방법에 대해 알아봅니다. # 데이터 셋 생성 및 데이터 에디터 열기 1. **Workspace - MyDesk**의 콘텍스트 메뉴에서 **Create DataSet**을 클릭합니다. 2. 생성된 데이터를 더블클릭하여 데이터 에디터를 엽니다. # 데이터 에디터 | 번호 | 설명 | | --- | --- | | | **컬럼 셀** 각 열의 데이터명, 즉 컬럼 명을 정의합
[task] | code [pass] | ⏳ 미판정 [title] | 맵 생성과 관리 [question] | 현재 Scene 에서 작업 중인 맵의 특정 좌표에 유저가 터치(Touch)하면 _TimerService 의 SetTimerOnce 를 사용하여 2초 후 해당 위치의 오브젝트를 _EntityService 로 삭제하는 스크립트를 작성해줘 [answer] | 사용자가 요청한 기능은 "현재 Scene에서 작업 중인 맵의 특정 좌표"에서 터치 이벤트를 감지하는 것입니다. 하지만 제공된 참고 문서에는 **좌표 기반 터치 감지** 또는 **지형(테레인) 터치 이벤트**에 대한 API나 설명이 포함되어 있지 않습니다. 문서에 명시된 터치 관련 정보는 `TouchEvent`와 `HandleTouchEvent` 이벤트 핸들러의 존재만 언급되어 있으며(참고: `[self] HandleTouchEvent(TouchEvent event)` 예시), 이는 **엔티티(Entity) 자체**가 터치 대상일 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 다양한 맵은 월드를 탐험하는 유저들에게 다채로운 재미를 선사합니다. 이번 과정에서는 맵 생성과 관리 방법을 알아봅시다. # 맵 관리 방법 맵 관리 방법에는 2가지가 있습니다. * **Hierarchy - maps** 하위 엔트리의 콘텍스트 메뉴를 통해 관리 * **Window - Map List** 창에서 관리 # 새 맵 만들기 | Hierarchy | Map List | | ----------- | ------- | | **Hierarchy - maps**의 콘텍스트 메뉴에서 **Create New M