[task] | instruction_following [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅱ [question] | OnBeginPlay() 내의 코드 블록만 출력하되, buttonPaths 정의부터 Controller 할당까지의 순서대로 주석 없이 나열하세요. [answer] | ```lua local buttonPaths = { "/ui/DefaultGroup/ShopButton", "/ui/DefaultGroup/SellButton", } for i, path in pairs(buttonPaths) do self:SetButtonHandler(path) end local localPlayer = _UserService.LocalPlayer self.Controller = localPlayer.PlayerController ``` [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | SELL 버튼을 클릭하면 캐릭터가 NPC가 배치된 위치로 이동할 수 있도록 만들어봅시다. 1. **UIManager**에서 `PlayerController`를 참조할 수 있도록 새로운 **Controller** 프로퍼티를 추가합니다. ```lua Property: [None] component Controller = nil ``` 2. **UIManager** 컴포넌트에 새로운 `SetButtonHandler()` 메소드를 추가하고, **string** 타입의 **buttonPath** 매개
[task] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | TriggerComponent를 확장해 NPCSellPow를 만들 때 기존 __base:OnEnterTriggerBody 구문을 삭제해야 하는 이유는 무엇인가요? [answer] | NPCSellPow 컴포넌트에서 기존 `__base:OnEnterTriggerBody(enterEvent)` 구문을 삭제해야 하는 이유는, 이 구문이 TriggerComponent의 기본 동작을 호출하기 때문입니다. 문서에 따르면, NPCSellPow 컴포넌트는 NPC에게 다가온 유저를 감지하여 **PlayerStats** 컴포넌트가 있는 엔티티인지 확인하고, 해당 엔티티의 `SellPow()` 메서드를 호출하는 특정 로직을 수행하도록 설계되었습니다. 만약 `__base:OnEnterTriggerBody(enterEvent)`를 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 힘 판매하기 환전을 담당하고 있는 NPC에게 다가가면 모든 힘 값을 0으로 변경하고, 감소한 힘만큼 돈이 증가하도록 만들어봅시다. 1. 판매를 담당할 NPC를 배치하고, 이름을 **SellNPC**로 변경합니다. > **Tip** > 만약 배치한 NPC가 다른 오브젝트들의 뒤에 배치될 경우 NPC의 SpriteRendererComponent의 SortingLayer 값을 변경합니다. 2. NPC의 **RigidBodComponent**의 **Gravity** 프로퍼티의 값을 0으로 변경합니다. NPC
[task] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | Stats.CurrentPow 값이 증가할 때마다 SizeSet 함수에서 계산된 Scale이 제대로 반영되지 않는 원인은 무엇일까요? [answer] | 제시된 문서 내용만으로는 `SizeSet()` 함수에서 계산된 Scale이 제대로 반영되지 않는 **구체적인 원인(버그, 오류 메시지, 실행 환경 문제 등)을 확인할 수 없습니다.** 문서에는 다음과 같은 구현 정보만 포함되어 있습니다. 1. `SizeSet()` 메서드 내부에서 `self.Stats.CurrentPow` 값을 사용하여 `size` 변수를 계산하고, `self.Transform.Scale`에 `Vector3(size, size, 1)`을 대입하는 코드 예제만 제공됩니다. 2. `WorkOut()` 메서드 마지 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 커지는 몸 구현 증가하는 힘의 크기만큼 캐릭터의 크기가 증가하는 기능을 구현하겠습니다. 1. **PlayerController** 컴포넌트에 새로운 `SizeSet()` 메소드를 생성합니다. 2. `SizeSet()` 메소드에 캐릭터의 크기가 **0.1**씩 커질 수 있도록 아래와 같이 작성합니다. ```lua void SizeSet() { local size = 1 + (0.1 * self.Stats.CurrentPow) self.Transform.Scale = Vecto
[task] | single_turn [pass] | ⏳ 미판정 [title] | 물체의 이동 Ⅱ [question] | `RigidbodyComponent`의 `SetForce` 메서드를 사용할 때, 매 프레임마다 반복적으로 호출하면 원숭이가 계속 밀려나는데 `IsHit` 플래그를 어떻게 활용해서 한 번만 힘을 가하도록 제어하는지 궁금합니다. [answer] | `RigidbodyComponent`의 `SetForce` 메서드가 매 프레임마다 반복적으로 호출되면 물체에 지속적인 힘이 가해져 원숭이가 계속 밀려나는 현상이 발생합니다. 이를 방지하기 위해 `boolean` 타입의 `IsHit` 프로퍼티를 플래그로 활용하여 힘 가하기 조건을 제어합니다. 구체적인 제어 로직은 다음과 같습니다. 1. **초기화**: `IsHit` 프로퍼티의 기본값은 `false`로 설정합니다. 2. **조건부 실행**: `OnUpdate` 함수 내에서 `self.IsHit == false`일 때만 택시와 원 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | RigidbodyComponent를 활용해 질주하는 택시가 원숭이를 밀어낼 수 있도록 만들어 봅시다. 원숭이를 밀어내기 위해서는 원숭이가 택시 위치를 확인하고, 택시가 원숭이게 근접하면 원숭이의 RigidbodyComponent에 힘을 주도록 만들어봅시다. 1. **Workspace - MyDesk - Create Scripts - Create Component**을 선택해 새 스크립트 컴포넌트를 추가하고 이름을 **Monkey**로 변경합니다. 2. **Monkey** 엔티티에 **Monkey 컴포넌트**를 추가합니
[task] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | SetMoney 메소드의 실행 공간을 [multicast]로 설정해야 하는 이유는 무엇인가요? [answer] | `SetMoney` 메소드의 실행 공간을 `[multicast]`로 설정해야 하는 이유는 서버에서 돈을 갱신할 때, 그 변경 사항이 클라이언트(유저의 화면)에도 즉시 반영되어야 하기 때문입니다. `SetMoney` 메소드 내부에서는 `self.CurrentMoney` 값을 변경한 후, UI 값을 갱신하는 `RenewMoney()` 메소드를 호출합니다. 만약 이 메소드가 서버에서만 실행된다면, 서버의 데이터만 바뀌고 유저가 보는 화면의 돈 표시는 갱신되지 않을 수 있습니다. `[multicast]` 속성을 붙이면 서버에서 메소드를 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 힘 판매하기 환전을 담당하고 있는 NPC에게 다가가면 모든 힘 값을 0으로 변경하고, 감소한 힘만큼 돈이 증가하도록 만들어봅시다. 1. 판매를 담당할 NPC를 배치하고, 이름을 **SellNPC**로 변경합니다. > **Tip** > 만약 배치한 NPC가 다른 오브젝트들의 뒤에 배치될 경우 NPC의 SpriteRendererComponent의 SortingLayer 값을 변경합니다. 2. NPC의 **RigidBodComponent**의 **Gravity** 프로퍼티의 값을 0으로 변경합니다. NPC
[task] | code [pass] | ⏳ 미판정 [title] | 물체의 이동 Ⅱ [question] | EntityService를 통해 'Monkey' 경로로 원숭이 엔티티를 참조하고, TransformComponent와 RigidbodyComponent를 조합하여 택시 이동 및 원숭이 밀어내기 동작을 제어하는 스크립트를 작성해줘. [answer] | 제공된 참고 문서에는 `_EntityService:GetEntityByPath`를 사용하여 특정 경로(예: `/maps/map01/monster-1`)의 엔티티를 참조하는 방법과, `TransformComponent:Translate` 및 `RigidbodyComponent:Translate`를 사용하여 물체를 이동·밀어내는 개념만 설명되어 있습니다. 그러나 **참고 문서에는 'Monkey' 엔티티의 정확한 경로 정보, 택시 엔티티의 경로, `RigidbodyComponent:Translate`의 정확한 매개변수 시그니처, 그리고 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 이번 가이드는 [물체의 이동 Ⅰ](/docs?postId=123)을 따라 만든 월드에서 이어서 제작해야 정상적으로 동작합니다. 택시가 아잘린을 태우러 가야하는데 원숭이가 길을 가로 막고 있습니다. `TransformComponent`의 `Translate`를 이용하여 택시를 이동시키고 `RigidbodyComponent`의 `Translate` 함수를 사용하여 원숭이를 밀어내봅시다. ![[object Object]](https://mod-file.dn.nexoncdn.co.kr/bbs/174790801778
[task] | instruction_following [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅱ [question] | 상점 버튼과 판매 버튼 제작 시 각각 추가해야 하는 컴포넌트와 최종 이름 변경 사항을 표로 정리하세요. [answer] | 상점 버튼과 판매 버튼 제작 시 필요한 컴포넌트와 이름 변경 사항은 다음과 같습니다. | 구분 | 추가해야 하는 컴포넌트 | 최종 이름 | | :--- | :--- | :--- | | **상점 버튼** | `TextComponent` | `ShopButton` | | **판매 버튼** | 없음 (상점 버튼 복제) | `SellButton` | **세부 제작 과정:** 1. **상점 버튼**: `DefaultGroup`에 UI 버튼을 추가한 뒤, 이름을 **ShopButton**으로 변경하고 **TextComponent**를 추가 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 버튼 UI 제작 #### 상점 버튼 제작 1. **DefaultGroup**에 UI 버튼을 추가하고, 자유롭게 버튼 형태를 수정합니다. ![[object Object]](https://mod-file.dn.nexoncdn.co.kr/bbs/17695121955247cf8228045bc45d49b963f35fcf1855b.png "shop") 2. 버튼의 이름을 **ShopButton**으로 변경하고,**TextComponent**를 추가합니다. ![[object Object]](https://mod-file.dn.nexonc
[task] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅱ [question] | UI 버튼의 이름을 ShopButton으로 변경하지 않으면 스크립트에서 참조할 때 어떤 오류가 발생하나요? [answer] | 제공된 참고 문서에는 UI 버튼의 이름을 `ShopButton`으로 변경하지 않았을 때 발생하는 구체적인 오류 메시지나 동작에 대한 설명이 없습니다. 문서에서는 상점 버튼 제작 단계에서 "버튼의 이름을 **ShopButton**으로 변경하고, **TextComponent**를 추가한다"는 지시만 하고 있을 뿐, 이름을 변경하지 않으면 어떤 예외가 발생하거나 어떤 오류가 나타나는지에 대한 정보는 포함되어 있지 않습니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 버튼 UI 제작 #### 상점 버튼 제작 1. **DefaultGroup**에 UI 버튼을 추가하고, 자유롭게 버튼 형태를 수정합니다. ![[object Object]](https://mod-file.dn.nexoncdn.co.kr/bbs/17695121955247cf8228045bc45d49b963f35fcf1855b.png "shop") 2. 버튼의 이름을 **ShopButton**으로 변경하고,**TextComponent**를 추가합니다. ![[object Object]](https://mod-file.dn.nexonc
[task] | two_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | PlayerActionEvent 핸들러에서 ActionName이 "Attack"일 때 WorkOut()이 호출되는 과정에서, 클라이언트와 서버 양측에서 이벤트가 발생하지만 WorkOut()은 server only로 실행되는 이유와, 이 구조가 동기화(Sync)에 미치는 영향은 무엇인가요? [answer] | `PlayerActionEvent` 핸들러에서 `ActionName`이 "Attack"일 때 `WorkOut()`이 호출되는 구조와 동기화(Sync)에 미치는 영향은 다음과 같습니다. **1. `WorkOut()`이 server only로 실행되는 이유** `HandlePlayerActionEvent`는 캐릭터의 상태 변화가 발생할 때 클라이언트와 서버 양쪽 공간에서 모두 호출됩니다. 하지만 `WorkOut()` 메서드 자체는 실행 공간이 `[server only]`로 설정되어 있습니다. 이 구조를 취하는 이유는 **게임 로직 [followup] | SetPow() 메서드가 WorkOut()에서 호출될 때, 왜 실행 공간을 Multicast로 설정해야 하는지, 그리고 이 메서드 내에서 CurrentPow 프로퍼티에 값을 할당하고 로그를 출력하는 정확한 코드 예시를 보여주세요. [followup_answer] | **1. `SetPow()` 메서드가 Multicast로 설정되어야 하는 이유** `SetPow()` 메서드가 `[Multicast]` 실행 공간으로 설정되어야 하는 주된 이유는 **UI 갱신** 때문입니다. 참고 문서에 따르면, `SetPow()` 메서드 호출 시 UI를 갱신하는 메서드도 함께 호출해야 합니다. UI 갱신은 클라이언트(사용자 화면)에서 수행되어야 하므로, 이 메서드는 서버와 클라이언트 양쪽 공간에서 모두 실행될 수 있어야 합니다. * **서버 측:** `WorkOut()`이 서버에서 실행되어 힘 값을 계산 [scores] | [judge_reason] | [source_doc] | `Ctrl`키를 눌러 Attack 상태가 되면 운동을 하고, 힘이 증가하도록 만듭니다. 1. **PlayerController**에 **Component** 타입의 **Stats** 프로퍼티를 추가합니다. 이 프로퍼티는 **PlayerStats** 컴포넌트를 참고하게 됩니다. ```lua Property: [Sync] Component Stats = nil ``` 2. `OnBeginPlay()` 메소드에 **PlayerStats** 컴포넌트를 받아오도록 아래와 같이 작성합니다.**Playe
[task] | two_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | UIManager 컴포넌트를 통해 PlayerStats와 UI를 연동하는 기본 구조와 OnBeginPlay 초기화 방식이 어떻게 구성되어 있나요? [answer] | UIManager 컴포넌트는 플레이어의 상태(PlayerStats)와 화면에 표시되는 UI 요소(텍스트)를 연결하는 역할을 합니다. 이 구조는 UIManager가 UI 엔티티와 플레이어 상태 정보를 참조하고, 초기화 시점에 UI 값을 갱신하는 방식으로 이루어집니다. ### 1. UIManager 컴포넌트 구조 UIManager 컴포넌트에는 UI 갱신에 필요한 정보를 저장하기 위한 프로퍼티와, 실제 UI 텍스트를 변경하는 메서드가 정의됩니다. **Property:** * `UiPowerText`: `UIPower` 엔티티의 [followup] | OnBeginPlay에서 _EntityService:GetEntityByPath로 TextComponent를 가져올 때 경로를 잘못 찾으면 어떤 오류가 발생하며, PlayerStats의 CurrentPow 값이 0.5처럼 소수점 이하가 있을 때 math.floor 처리 없이 UI에 표시하면 어떻게 되나요? [followup_answer] | 제공된 참고 문서에는 `_EntityService:GetEntityByPath` 호출 시 경로가 잘못되었을 때 발생하는 구체적인 오류 유형(예: nil index error 등)에 대한 설명이 없습니다. 문서의 예제 코드에서는 경로가 잘못될 경우를 처리하는 방어적 코드(예: `if entity == nil then return end`)가 포함되어 있지 않으므로, 문서 근거만으로 오류 내용을 단정할 수 없습니다. `CurrentPow` 값이 0.5와 같은 소수점 이하의 값을 가질 때 `math.floor` 처리 없이 UI에 표시하 [scores] | [judge_reason] | [source_doc] | 전반적인 UI 관리를 위한 UIManager 스크립트 컴포넌트를 만들어 봅시다. **PlayerStats** 컴포넌트에서 힘을 증가시킬 때마다 **UIManager**에서 UI를 갱신하는 방식으로 구현하겠습니다. 1. 새로운 **UIManager** 컴포넌트를 생성합니다. 2. **Hierarchy - ui - DefaultGroup**에 생성한 **UIManager** 컴포넌트를 추가합니다. ![[object Object]](https://mod-file.dn.nexoncdn.co.kr/bbs/176951343509088f9e
[task] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅱ [question] | ShopButton을 복제해서 SellButton을 만들 때 Duplicate 기능을 사용하는 이유가 무엇인가요? [answer] | 상점 버튼(ShopButton)을 복제하여 판매 버튼(SellButton)을 만들 때 Duplicate 기능을 사용하는 주된 이유는 **일관된 UI 스타일 유지**와 **제작 시간 단축**입니다. 문서에 따르면, ShopButton은 이미 원하는 형태로 자유롭게 수정된 상태입니다. 이 상태에서 Duplicate 기능을 사용하면 동일한 모양, 크기, 색상, 텍스트 컴포넌트 설정 등이 그대로 복사된 SellButton을 즉시 생성할 수 있습니다. 이후에는 버튼의 이름만 `SellButton`으로 변경하고 필요한 텍스트나 동작만 수정하 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 버튼 UI 제작 #### 상점 버튼 제작 1. **DefaultGroup**에 UI 버튼을 추가하고, 자유롭게 버튼 형태를 수정합니다. ![[object Object]](https://mod-file.dn.nexoncdn.co.kr/bbs/17695121955247cf8228045bc45d49b963f35fcf1855b.png "shop") 2. 버튼의 이름을 **ShopButton**으로 변경하고,**TextComponent**를 추가합니다. ![[object Object]](https://mod-file.dn.nexonc
[task] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅱ [question] | DefaultGroup에 추가한 UI 버튼의 형태를 수정하려면 어떤 작업 순서를 따라야 하나요? [answer] | DefaultGroup에 UI 버튼의 형태를 수정하려면 다음과 같은 순서로 작업을 진행합니다. 1. **DefaultGroup**에 UI 버튼을 추가합니다. 2. 추가한 버튼을 자유롭게 선택하여 버튼 형태를 수정합니다. 3. (추가 작업이 필요한 경우) 버튼의 이름을 원하는 이름(예: ShopButton)으로 변경합니다. 4. (추가 작업이 필요한 경우) 버튼에 TextComponent를 추가합니다. 참고로, 상점 버튼(ShopButton) 제작 시에는 1단계에서 추가한 버튼의 이름을 ShopButton으로 변경하고 TextCo [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 버튼 UI 제작 #### 상점 버튼 제작 1. **DefaultGroup**에 UI 버튼을 추가하고, 자유롭게 버튼 형태를 수정합니다. ![[object Object]](https://mod-file.dn.nexoncdn.co.kr/bbs/17695121955247cf8228045bc45d49b963f35fcf1855b.png "shop") 2. 버튼의 이름을 **ShopButton**으로 변경하고,**TextComponent**를 추가합니다. ![[object Object]](https://mod-file.dn.nexonc
[task] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅱ [question] | NPC 위치로 이동하는 기능을 구현할 때 버튼 클릭 이벤트 핸들러에서 어떤 서비스를 호출해야 하나요? [answer] | 참고 문서에 제공된 mLua 예제 코드에는 NPC 위치로 이동하는 실제 구현 코드가 포함되어 있지 않습니다. 문서에 포함된 예제들은 다음과 같은 기능만 수행합니다: 1. **BGM 토글 버튼**: `_SoundService`를 사용하여 배경음악을 재생/일시정지/재개합니다. 2. **불꽃놀이 소리 정지 버튼**: `_SoundService`를 사용하여 루프 소리를 정지합니다. 3. **트리거 엔터 이벤트**: `_LocalizationService`와 `_EntityService`를 사용하여 NPC 이름으로 텍스트 박스 내용을 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 버튼 UI 제작 #### 상점 버튼 제작 1. **DefaultGroup**에 UI 버튼을 추가하고, 자유롭게 버튼 형태를 수정합니다. ![[object Object]](https://mod-file.dn.nexoncdn.co.kr/bbs/17695121955247cf8228045bc45d49b963f35fcf1855b.png "shop") 2. 버튼의 이름을 **ShopButton**으로 변경하고,**TextComponent**를 추가합니다. ![[object Object]](https://mod-file.dn.nexonc
[task] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | EntityService:GetEntityByPath로 UI 컴포넌트를 가져올 때 경로를 잘못 적으면 어떤 오류가 발생하며, Hierarchy에서 정확한 경로를 확인하는 방법이 무엇인가요? [answer] | 제공된 참고 문서에는 `_EntityService:GetEntityByPath` 호출 시 경로를 잘못 적었을 때 발생하는 구체적인 오류 메시지나 예외 처리 방식, 그리고 Hierarchy에서 정확한 경로를 확인하는 방법에 대한 설명이 포함되어 있지 않습니다. 문서에는 `_EntityService:GetEntityByPath("/ui/DefaultGroup/UIPower")`와 같이 경로를 문자열로 전달하여 엔티티를 가져오는 사용 예시와, `_EntityService:GetEntityByPath("/ui/DefaultGroup")` [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 전반적인 UI 관리를 위한 UIManager 스크립트 컴포넌트를 만들어 봅시다. **PlayerStats** 컴포넌트에서 힘을 증가시킬 때마다 **UIManager**에서 UI를 갱신하는 방식으로 구현하겠습니다. 1. 새로운 **UIManager** 컴포넌트를 생성합니다. 2. **Hierarchy - ui - DefaultGroup**에 생성한 **UIManager** 컴포넌트를 추가합니다. ![[object Object]](https://mod-file.dn.nexoncdn.co.kr/bbs/176951343509088f9e
[task] | code [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | DefaultGroup 하위에 UIPower와 UIMoney라는 이름의 텍스트 UI 컴포넌트를 생성하고, PlayerController의 Stats.CurrentPow와 돈 금액을 각각 해당 UI의 텍스트로 동기화하여 표시하는 스크립트를 작성해줘 [answer] | 제공된 참고 문서에는 `UIPower`와 `UIMoney`라는 이름의 UI 컴포넌트를 생성하는 **방법(프로시저)**만 설명되어 있으며, 실제 mLua 코드에서 해당 UI 컴포넌트의 **텍스트 프로퍼티에 접근하는 API(예: `.Text`, `.SetText()` 등)는 명시되어 있지 않습니다.** 따라서 문서에 근거하여 "UI 컴포넌트를 생성하고"라는 부분만 설명할 수 있으며, "텍스트로 동기화하여 표시하는" 구체적인 코드 작성은 문서에 해당 API가 없어 불가능합니다. 참고 문서에 포함된 UI 관련 내용과 mLua 코드 형식 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 커지는 몸 구현 증가하는 힘의 크기만큼 캐릭터의 크기가 증가하는 기능을 구현하겠습니다. 1. **PlayerController** 컴포넌트에 새로운 `SizeSet()` 메소드를 생성합니다. 2. `SizeSet()` 메소드에 캐릭터의 크기가 **0.1**씩 커질 수 있도록 아래와 같이 작성합니다. ```lua void SizeSet() { local size = 1 + (0.1 * self.Stats.CurrentPow) self.Transform.Scale = Vecto
[task] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | WorkOut 메소드를 server only로 설정했는데, 이벤트 핸들러에서 호출할 때 클라이언트에서 발생하는 PlayerActionEvent를 서버로 전달하는 메커니즘은 어떻게 작동하나요? [answer] | mLua에서 `PlayerActionEvent`와 `server only` 메서드 호출의 상호작용은 다음과 같이 작동합니다. **1. 이벤트 발생 위치** `PlayerActionEvent`는 클라이언트와 서버 양쪽 공간 모두에서 발생하고 핸들러(`HandlePlayerActionEvent`)가 호출됩니다. 즉, 사용자가 키를 누르면 클라이언트에서 먼저 이벤트가 감지되며, 동시에 서버에서도 해당 이벤트가 감지됩니다. **2. 서버에서만 실행되는 메서드 호출** `WorkOut()` 메서드의 실행 공간이 `[server only] [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `Ctrl`키를 눌러 Attack 상태가 되면 운동을 하고, 힘이 증가하도록 만듭니다. 1. **PlayerController**에 **Component** 타입의 **Stats** 프로퍼티를 추가합니다. 이 프로퍼티는 **PlayerStats** 컴포넌트를 참고하게 됩니다. ```lua Property: [Sync] Component Stats = nil ``` 2. `OnBeginPlay()` 메소드에 **PlayerStats** 컴포넌트를 받아오도록 아래와 같이 작성합니다.**Playe
[task] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅱ [question] | 상점 버튼에 TextComponent를 추가할 때 이름 변경과 컴포넌트 추가 순서가 중요할까요? [answer] | 상점 버튼에 TextComponent를 추가할 때 이름 변경과 컴포넌트 추가의 순서는 중요하지 않습니다. 참고 문서의 '상점 버튼 제작' 단계를 보면, 1단계에서 UI 버튼을 추가하고 형태를 수정한 후, 2단계에서 "버튼의 이름을 **ShopButton**으로 변경하고, **TextComponent**를 추가합니다"라고 설명하고 있습니다. 여기서 두 작업이 하나의 단계(2단계) 안에서 함께 수행되도록 안내하고 있으므로, 편집기 상에서 이름을 먼저 바꾸고 컴포넌트를 추가하든, 컴포넌트를 추가하고 이름을 바꾸든 최종 결과물은 동일합니 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 버튼 UI 제작 #### 상점 버튼 제작 1. **DefaultGroup**에 UI 버튼을 추가하고, 자유롭게 버튼 형태를 수정합니다. ![[object Object]](https://mod-file.dn.nexoncdn.co.kr/bbs/17695121955247cf8228045bc45d49b963f35fcf1855b.png "shop") 2. 버튼의 이름을 **ShopButton**으로 변경하고,**TextComponent**를 추가합니다. ![[object Object]](https://mod-file.dn.nexonc
[task] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | PlayerStats 컴포넌트에서 힘을 갱신하는 RenewPow() 메소드를 client only로 설정해야 하는 이유와, 서버에서 호출했을 때 발생하는 오류 원인이 궁금합니다. [answer] | 참고 문서에 `RenewPow()` 메소드를 `[client only]`로 설정해야 하는 구체적인 이유나, 서버에서 호출했을 때 발생하는 오류의 원인에 대한 설명이 포함되어 있지 않습니다. 문서에는 단순히 **PlayerStats** 컴포넌트에 `RenewPow()` 메소드를 생성할 때 실행 공간을 **client only**로 설정하고, 내부에서 `self.UiManager:UISetPower()`를 호출하도록 하라는 지침만 제시되어 있습니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | ```lua void OnBeginPlay() { if self:IsClient() then self.UiManager = _EntityService:GetEntityByPath("/ui/DefaultGroup").UIManager end } ``` 9. **PlayerStats** 컴포넌트에 `RenewPow()` 메소드를 생성하고 아래 내용을 추가합니다. ```lua [client only] void
[task] | single_turn [pass] | ⏳ 미판정 [title] | 물체의 이동 Ⅱ [question] | `Monkey` 컴포넌트의 `OnUpdate`에서 `self.IsHit`가 `true`로 변경된 이후에는 더 이상 택시와 원숭이의 거리를 검사하지 않는 구조인데, 만약 원숭이가 다시 택시 근처로 돌아와야 밀려나도록 만들려면 어떤 로직을 추가해야 하나요? [answer] | 원숭이가 밀려난 후(`IsHit`가 `true`가 된 상태) 다시 택시 근처로 돌아와야 밀려나도록 하려면, 현재 `IsHit`가 `true`일 때의 거리를 역으로 확인하는 로직을 추가해야 합니다. 기존 로직은 택시가 원숭이보다 **앞**에 있을 때(`taxiPos.x > monkeyPos.x - 0.8`)에만 힘을 주고 `IsHit`를 `true`로 고정합니다. 따라서 원숭이가 밀려나간 후 다시 택시 근처로 돌아오는 상황은 **택시가 원숭이보다 뒤에 있는 상태**(`taxiPos.x < monkeyPos.x + 0.8` 등)가 됩 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | RigidbodyComponent를 활용해 질주하는 택시가 원숭이를 밀어낼 수 있도록 만들어 봅시다. 원숭이를 밀어내기 위해서는 원숭이가 택시 위치를 확인하고, 택시가 원숭이게 근접하면 원숭이의 RigidbodyComponent에 힘을 주도록 만들어봅시다. 1. **Workspace - MyDesk - Create Scripts - Create Component**을 선택해 새 스크립트 컴포넌트를 추가하고 이름을 **Monkey**로 변경합니다. 2. **Monkey** 엔티티에 **Monkey 컴포넌트**를 추가합니
[task] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | SetPow() 메소드 내부에서 self:RenewPow()를 호출할 때, RenewPow()가 client only인데도 서버에서 SetPow()가 실행되면 문제가 되는지 어떻게 처리해야 하나요? [answer] | 제공된 문서에는 `SetPow()` 메소드 내부의 구현 코드나 실행 공간(Execution Space)이 명시되어 있지 않습니다. 또한, `SetPow()`가 서버에서 실행될 때 `client only` 메소드를 호출하면 발생하는 구체적인 오류나 이를 위한 예외 처리 패턴에 대한 설명도 문서에 포함되어 있지 않습니다. 따라서 제공된 참고 문서 범위 내에서 이 질문에 대한 답변은 할 수 없습니다. 문서에는 `SetPow()` 메소드의 가장 아래에 `self:RenewPow()`를 추가하라는 지시만 있을 뿐, `SetPow()` 자체 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | ```lua void OnBeginPlay() { if self:IsClient() then self.UiManager = _EntityService:GetEntityByPath("/ui/DefaultGroup").UIManager end } ``` 9. **PlayerStats** 컴포넌트에 `RenewPow()` 메소드를 생성하고 아래 내용을 추가합니다. ```lua [client only] void
[task] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | _UIManager를 OnBeginPlay에서 초기화했는데, 스크립트가 실행된 후 특정 시점에 self.UiManager가 nil이라고 뜨는 경우가 있나요? [answer] | 제공된 참고 문서에는 `self.UiManager`가 `nil`이 되는 구체적인 시나리오나 원인에 대한 정보가 포함되어 있지 않습니다. 문서에서 확인할 수 있는 내용은 `OnBeginPlay`에서 `_EntityService:GetEntityByPath("/ui/DefaultGroup").UIManager`를 통해 초기화하는 코드 예시와, 초기화 후 `RenewPow()`, `RenewMoney()` 메서드에서 `self.UiManager:UISetPower()` 등을 호출하는 부분뿐입니다. 따라서 주어진 문서 범위 내에서 `s [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | ```lua void OnBeginPlay() { if self:IsClient() then self.UiManager = _EntityService:GetEntityByPath("/ui/DefaultGroup").UIManager end } ``` 9. **PlayerStats** 컴포넌트에 `RenewPow()` 메소드를 생성하고 아래 내용을 추가합니다. ```lua [client only] void
[task] | two_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅱ [question] | 상점 버튼과 판매 버튼을 UI에 추가하고 이름을 변경하는 구체적인 과정이 어떻게 다른가요? [answer] | 상점 버튼(ShopButton)과 판매 버튼(SellButton)을 UI에 추가하고 이름을 변경하는 과정은 버튼의 생성 방식에서 차이가 있습니다. **상점 버튼(ShopButton) 제작 과정** 1. `DefaultGroup`에 UI 버튼을 직접 추가합니다. 2. 자유롭게 버튼 형태를 수정합니다. 3. 버튼의 이름을 **ShopButton**으로 변경합니다. 4. **TextComponent**를 추가합니다. **판매 버튼(SellButton) 제작 과정** 1. 앞서 제작한 SHOP 버튼을 선택합니다. 2. 콘텍스트 메뉴에서 [followup] | 버튼 이름 변경 시 TextComponent의 텍스트 내용도 함께 수정해야 하는지, 아니면 이름 속성만 변경하면 되는지 알려주세요. [followup_answer] | 제공된 문서에는 버튼의 이름 속성을 변경할 때 `TextComponent`의 텍스트 내용도 함께 수정해야 하는지에 대한 설명이 없습니다. 문서에는 상점 버튼 제작 시 `TextComponent`를 추가하는 단계와, 버튼의 이름을 `ShopButton` 또는 `SellButton`으로 변경하는 단계만 언급되어 있을 뿐, 이름 변경과 텍스트 내용 수정 간의 연관성이나 필수 여부를 설명하지 않습니다. [scores] | [judge_reason] | [source_doc] | # 버튼 UI 제작 #### 상점 버튼 제작 1. **DefaultGroup**에 UI 버튼을 추가하고, 자유롭게 버튼 형태를 수정합니다. ![[object Object]](https://mod-file.dn.nexoncdn.co.kr/bbs/17695121955247cf8228045bc45d49b963f35fcf1855b.png "shop") 2. 버튼의 이름을 **ShopButton**으로 변경하고,**TextComponent**를 추가합니다. ![[object Object]](https://mod-file.dn.nexonc
[task] | instruction_following [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅱ [question] | UI Group의 DefaultShow 값을 설정하는 과정과 상점 UI를 열기 위한 OnClickButton 메서드 내 ShopButton 분기문 코드를 포함하여 3문장 이내로 설명하세요. [answer] | UI Group을 추가한 뒤 DefaultShow 값을 true로 설정하여 초기 표시 상태를 제어합니다. OnClickButton 메서드 내에서 버튼 이름이 "ShopButton"인 경우를 분기하여 self.ShopGroup:SetVisible(true, false)를 호출합니다. 이 코드를 실행하면 Shop 버튼을 누를 때 상점 UI가 열립니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 상점 UI 제작 1. 새로운 **UI Group**을 추가하고, **DefaultShow** 값을 **true**로 설정합니다. 2. 아래와 같이 UI엔티티를 추가하고 배치합니다. UI엔티티의 이름은 이미지와 동일해야 합니다. ![[object Object]](https://mod-file.dn.nexoncdn.co.kr/bbs/1769512144899182516b8ee4d4248a16af41cc5d72f56.png "1") > **Tip.** > 이미지나 텍스트가 다른 UI엔티티에 가릴 경우 하이어라키 순서를 변경합니다.
[task] | code [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | UIManager 컴포넌트의 OnBeginPlay()에서 _EntityService:GetEntityByPath()로 UIPower 및 UIMoney 엔티티의 TextComponent와 _UserService.LocalPlayer.PlayerStats를 프로퍼티에 할당하고 초기 UI 갱신을 수행하는 코드를 작성해줘 [answer] | `UIManager` 컴포넌트의 `OnBeginPlay()` 메서드 코드는 다음과 같습니다. 실행 공간은 클라이언트에서만 UI를 참조할 수 있으므로 `[client only]`로 설정해야 합니다. ```lua [client only] void OnBeginPlay() { self.UiPowerText = _EntityService:GetEntityByPath("/ui/DefaultGroup/UIPower").TextComponent self.UiMoneyText = _EntityService:GetEntityByPa [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 전반적인 UI 관리를 위한 UIManager 스크립트 컴포넌트를 만들어 봅시다. **PlayerStats** 컴포넌트에서 힘을 증가시킬 때마다 **UIManager**에서 UI를 갱신하는 방식으로 구현하겠습니다. 1. 새로운 **UIManager** 컴포넌트를 생성합니다. 2. **Hierarchy - ui - DefaultGroup**에 생성한 **UIManager** 컴포넌트를 추가합니다. ![[object Object]](https://mod-file.dn.nexoncdn.co.kr/bbs/176951343509088f9e
[task] | two_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | `PlayerController` 컴포넌트에서 `TransformComponent`와 `MovementComponent`를 프로퍼티로 지정하고 사용하는 이유는 무엇이며, `OnBeginPlay()`에서 이들을 초기화하는 과정은 어떻게 되나? [answer] | `PlayerController` 컴포넌트에서 `TransformComponent`와 `MovementComponent`를 프로퍼티로 지정하고 사용하는 주된 이유는 **메서드 내부에서 이 컴포넌트들에 대한 접근을 간결하게 하기 위함**입니다. 매 프레임마다 실행되는 `OnUpdate` 같은 함수에서 `self.Entity.TransformComponent` 또는 `self.Entity.MovementComponent`를 반복적으로 참조하는 대신, 미리 저장된 프로퍼티(예: `self.Transform`, `self.Movement [followup] | `MoveArea()` 메서드 내에서 `self.Movement:SetPosition()`을 호출할 때, 현재 위치 `pos`의 x 좌표를 유지하면서 y 좌표만 특정 범위(-1.23, -2.6)로 고정하는 로직의 정확한 코드 구조는? [followup_answer] | `MoveArea()` 메서드에서 현재 위치의 x 좌표를 유지하고 y 좌표만 특정 범위로 고정하는 로직은 `Vector2` 생성자를 통해 새로운 위치 벡터를 구성하여 `SetPosition`에 전달하는 방식으로 구현됩니다. 구체적인 코드 구조는 다음과 같습니다: ```lua [client only] void MoveArea() { local pos = self.Transform.Position if pos.y > -1.23 then self.Movement:SetPosition(Vector2(pos [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 운동할수록 캐릭터가 커지고, 그 힘을 돈으로 바꿀 수 있는 월드, 'Maple GYM'을 만들어봅시다. # 이동 방식 변경 RigidBodyComponent의 **KinematicMove**를 활용해 캐릭터의 이동 방식을 변경해봅시다. **DefaultPlayer - RigidBodyComponent**에서 **KinematicMove**를 선택합니다. #### 이동 영역 제한 캐릭터의 이동 방식을 **KinematicMove**로 변경하면 캐릭터가 자유롭게 상하좌우로 이동하게 됩니다. 캐릭터가 지면 영
[task] | two_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | Maple GYM에서 KinematicMove로 이동 방식을 변경했을 때, 캐릭터가 지면 영역 내에서만 이동하도록 제한하는 구체적인 구현 방법은? [answer] | `KinematicMove` 이동 방식에서는 캐릭터가 중력 없이 상하좌우로 자유롭게 움직일 수 있으므로, 지면 영역(특정 Y좌표 범위)으로만 제한하기 위해 `PlayerController` 컴포넌트를 사용하여 위치를 매 프레임마다 보정하는 로직을 구현해야 합니다. 구체적인 구현 방법은 다음과 같습니다. 1. **컴포넌트 생성 및 연결**: `DefaultPlayer`에 `PlayerController` 컴포넌트를 추가하고, `TransformComponent`와 `MovementComponent`를 참조할 프로퍼티를 선언합니다 [followup] | `OnUpdate()`의 실행 공간을 '사용하지 않음'으로 설정해야 하는 이유와, `MoveArea()`에서 상하 위치 보정을 위해 사용하는 `Vector2` 좌표 값은 어떻게 정해야 하는가? [followup_answer] | `OnUpdate()`의 실행 공간을 '사용하지 않음'으로 설정해야 하는 이유는, 실행 공간이 `server only`로 설정될 경우 네트워크 보정 과정에서 캐릭터가 튀는 것처럼 보이는 현상이 발생할 수 있기 때문입니다. 이를 방지하기 위해 서버와 클라이언트 모두에서 로직이 실행되도록 실행 공간을 지정하지 않는 것입니다. `MoveArea()`에서 상하 위치 보정을 위해 사용하는 `Vector2` 좌표 값은 실제 맵의 지형(지면) 높이에 따라 직접 지정해야 합니다. 참고 문서의 예제에서는 상한 Y좌표가 `-1.23`을 초과하면 ` [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 운동할수록 캐릭터가 커지고, 그 힘을 돈으로 바꿀 수 있는 월드, 'Maple GYM'을 만들어봅시다. # 이동 방식 변경 RigidBodyComponent의 **KinematicMove**를 활용해 캐릭터의 이동 방식을 변경해봅시다. **DefaultPlayer - RigidBodyComponent**에서 **KinematicMove**를 선택합니다. #### 이동 영역 제한 캐릭터의 이동 방식을 **KinematicMove**로 변경하면 캐릭터가 자유롭게 상하좌우로 이동하게 됩니다. 캐릭터가 지면 영
[task] | instruction_following [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅱ [question] | PlayerStats 컴포넌트에 추가해야 하는 프로퍼티 2개의 이름과 초기값을 코드 블록으로만 출력하세요. [answer] | ```lua Property: [None] table SkillGradeTable = {} [None] table DnaGradeTable = {} ``` [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 운동 기술과 DNA는 돈을 사용해 업그레이드 할 수 있습니다. 그러므로 각각의 등급에서 증가하는 힘과 누적 가능한 힘, 필요한 금액 정보를 구성해 봅시다. > **Tip.** > 관리할 데이터가 많아질 경우 스크립트에 직접 입력하는 대신 공식을 사용하거나, 데이터셋을 사용해 효율적으로 관리할 수 있습니다. 1. **PlayerStats** 컴포넌트에 새로운 프로퍼티 2개를 추가합니다. ```lua Property: [None] table SkillGradeTable = {} -- 운동 스킬 관련 테
[task] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | PlayerStats의 RenewMoney()와 RenewPow() 모두 client only로 설정되어 있는데, 이 두 메소드를 동시에 호출할 때 UI 갱신 순서나 충돌 문제가 생길 수 있나요? [answer] | 제시된 참고 문서에는 `RenewMoney()`와 `RenewPow()` 메소드가 동시에 호출될 경우의 **UI 갱신 순서**나 **충돌 문제**에 대한 기술적 설명이 없습니다. 문서에서 확인 가능한 사실은 다음과 같습니다. 1. 두 메소드 모두 `[client only]` 실행 공간으로 설정되어 있습니다. 2. `RenewPow()`는 `self.UiManager:UISetPower()`를 호출합니다. 3. `RenewMoney()`는 `self.UiManager:UISetMoney()`를 호출합니다. 4. `SetPo [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | ```lua void OnBeginPlay() { if self:IsClient() then self.UiManager = _EntityService:GetEntityByPath("/ui/DefaultGroup").UIManager end } ``` 9. **PlayerStats** 컴포넌트에 `RenewPow()` 메소드를 생성하고 아래 내용을 추가합니다. ```lua [client only] void
[task] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | PlayerStats 컴포넌트에 UiManager 프로퍼티를 추가하고 실행 공간을 사용하지 않음으로 설정한 후, 클라이언트와 서버 양쪽에서 동시에 UI 갱신을 시도하면 충돌이나 비정상 동작이 일어나나요? [answer] | 제시된 참고 문서에 따르면, `PlayerStats` 컴포넌트의 `OnBeginPlay()` 메서드 실행 공간을 **사용하지 않음(미설정)** 으로 설정하는 것은 클라이언트와 서버 양쪽에서 해당 메서드가 실행되도록 하기 위함입니다. 하지만 질문하신 "클라이언트와 서버 양쪽에서 동시에 UI 갱신을 시도할 때 충돌이나 비정상 동작이 일어나는지"에 대해서는 문서에 명시된 내용이 없습니다. 문서에서 확인 가능한 사실은 다음과 같습니다: 1. `UIManager` 컴포넌트의 `OnBeginPlay()`는 **client only** 실 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 전반적인 UI 관리를 위한 UIManager 스크립트 컴포넌트를 만들어 봅시다. **PlayerStats** 컴포넌트에서 힘을 증가시킬 때마다 **UIManager**에서 UI를 갱신하는 방식으로 구현하겠습니다. 1. 새로운 **UIManager** 컴포넌트를 생성합니다. 2. **Hierarchy - ui - DefaultGroup**에 생성한 **UIManager** 컴포넌트를 추가합니다. ![[object Object]](https://mod-file.dn.nexoncdn.co.kr/bbs/176951343509088f9e
[task] | instruction_following [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅱ [question] | DnaGradeTable에서 MaxPow 값이 1200인 등급의 GradeName을 한 줄로만 출력하세요. [answer] | 모험가 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 운동 기술과 DNA는 돈을 사용해 업그레이드 할 수 있습니다. 그러므로 각각의 등급에서 증가하는 힘과 누적 가능한 힘, 필요한 금액 정보를 구성해 봅시다. > **Tip.** > 관리할 데이터가 많아질 경우 스크립트에 직접 입력하는 대신 공식을 사용하거나, 데이터셋을 사용해 효율적으로 관리할 수 있습니다. 1. **PlayerStats** 컴포넌트에 새로운 프로퍼티 2개를 추가합니다. ```lua Property: [None] table SkillGradeTable = {} -- 운동 스킬 관련 테