[task] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | UIManager의 OnBeginPlay에서 실행 공간을 client only로 설정한 이유는 무엇이며, 서버에서 이 컴포넌트를 사용하려고 하면 어떤 문제가 생길 수 있나요? [answer] | UIManager의 `OnBeginPlay()` 메서드에 실행 공간을 `client only`로 설정한 이유는, 이 메서드가 **UI 관련 정보(텍스트 컴포넌트)를 참조하고 갱신하기 때문**입니다. 메이플스토리 월드에서 UI는 기본적으로 클라이언트(사용자 화면)에서만 렌더링되고 조작됩니다. 따라서 `_EntityService:GetEntityByPath()`를 통해 UI 엔티티(예: `/ui/DefaultGroup/UIPower`)를 찾고, 해당 엔티티의 `TextComponent`에 접근하여 `Text` 프로퍼티를 수정하는 로직 [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] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | 클라이언트에서 UI 매니저를 가져올 때 왜 OnBeginPlay 안에 self:IsClient() 조건문을 반드시 체크해야 하나요? [answer] | 참고 문서에 제시된 코드를 분석하면, `OnBeginPlay` 안에서 `self:IsClient()` 조건문을 체크하는 이유는 **UI 매니저(`UiManager`)가 클라이언트 환경에서만 유효한 리소스이기 때문**입니다. 제시된 코드에서 다음과 같이 처리하고 있습니다. ```lua void OnBeginPlay() { if self:IsClient() then self.UiManager = _EntityService:GetEntityByPath("/ui/DefaultGroup").UIManager [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] | `WorkOut()` 메소드에서 `SizeSet()`을 호출하여 캐릭터 크기를 변경하는 로직은 어떻게 작성하나요? [answer] | `WorkOut()` 메소드에서 `SizeSet()`을 호출하는 로직은 다음과 같이 작성합니다. 1. 먼저 **PlayerController** 컴포넌트에 캐릭터의 크기를 조절하는 `SizeSet()` 메소드를 정의합니다. 이 메소드는 현재 힘(`Stats.CurrentPow`)에 따라 캐릭터의 스케일을 계산하여 `Transform.Scale`에 적용합니다. 2. 이후 `WorkOut()` 메소드의 가장 아래 부분에 `self:SizeSet()`을 호출하도록 추가합니다. 구체적인 코드 구성은 다음과 같습니다. ```lua [followup] | `WorkOut()` 내에서 `self:SizeSet()` 호출 전에 현재 캐릭터의 `Stats.CurrentPow` 값이 0일 경우에도 `SizeSet()`이 정상적으로 실행되도록 `if` 조건문을 추가하는 예시 코드를 보여주세요. [followup_answer] | 제공된 참고 문서에는 `WorkOut()` 내에서 `Stats.CurrentPow` 값이 0인지 확인하는 `if` 조건문을 추가하는 내용이 포함되어 있지 않습니다. 문서에는 `WorkOut()` 메소드에서 `self:SizeSet()`을 호출할 때 조건문이 아닌 단순히 가장 아래에 `self:SizeSet()`을 추가하도록 지시하고 있으며, `SizeSet()` 내부에서도 `self.Stats.CurrentPow` 값에 따른 분기 처리나 null/0 체크 로직이 설명되어 있지 않습니다. 따라서 요청하신 조건문 추가 예시 코드는 문 [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] | instruction_following [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅱ [question] | 상점 UI를 제어하기 위해 UIManager 컴포넌트에 추가해야 하는 Property 블록과 OnBeginPlay()에서 ShopGroup을 초기화하는 코드만 출력하고 설명은 주석으로 작성하세요. [answer] | 상점 UI의 표시 여부를 제어하기 위해 `UIManager` 컴포넌트에 `ShopGroup` 프로퍼티를 추가하고, 게임 시작 시 해당 UI 그룹 엔티티를 참조하도록 초기화하는 코드는 다음과 같습니다. ```lua Property: [None] Entity ShopGroup = nil Method: [client only] void OnBeginPlay() { -- "/ui/UIGroup" 경로에 있는 상점 UI 그룹 엔티티를 가져와 ShopGroup 프로퍼티에 할당합니다. self.ShopGroup = _Entit [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] | PlayerStats 컴포넌트에 [client only] 실행 공간의 RenewPow 메서드를 추가하여 self.UiManager:UISetPower()를 호출함으로써 힘 UI를 갱신하는 스크립트를 작성해줘. [answer] | 요청하신 PlayerStats 컴포넌트의 스크립트입니다. ```lua Method: [client only] void RenewPow() { 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] | Maple GYM 만들기 Ⅰ [question] | PlayerController에서 PlayerStats 컴포넌트에 접근하기 위해 self.Entity.PlayerStats를 직접 참조하는 방식과 Component 타입의 Stats 프로퍼티를 별도로 선언하여 할당하는 방식의 차이점이 무엇이며, 어떤 장점이 있나요? [answer] | 제시된 참고 문서와 mLua 스크립트 규칙에 근거하여 두 접근 방식의 차이점과 장점을 설명합니다. ### 1. 접근 방식의 차이 **A. `self.Entity.PlayerStats` 직접 참조 방식** 이 방식은 엔티티에 장착된 특정 컴포넌트(여기서는 `PlayerStats`)를 엔티티 객체를 통해 직접 호출하는 것입니다. * **특징**: 별도의 프로퍼티 선언이 필요 없으며, 코드 내에서 `self.Entity.[컴포넌트이름]` 형태로 즉시 접근합니다. * **문서 근거**: 참고 문서의 2번 단계에서 `OnBegin [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] | 물체의 이동 Ⅱ [question] | 택시와 원숭이의 거리를 계산할 때 단순히 `taxiPos.x > monkeyPos.x - 0.8` 같은 X축 좌표 비교만 사용하고 있는데, Y축 방향의 차이를 고려하지 않아서 원숭이가 위에서 지나가도 밀려나는 오류가 발생하는 이유는 무엇일까요? [answer] | 제시된 참고 문서와 mLua 스크립트 규칙에 근거하여 질문하신 오류의 원인과 해결 방향을 설명드리겠습니다. **1. 오류 발생 원인** 참고 문서에 제시된 `OnUpdate` 로직은 다음과 같습니다. ```lua if taxiPos.x > monkeyPos.x -0.8 then self.MonkeyRigidbody:SetForce(Vector2(8,8)) self.IsHit = true end ``` 이 코드는 **X축 좌표(`.x`)만 비교**하여 택시와 원숭이의 근접 여부를 판단합니다. * `taxiPos [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | RigidbodyComponent를 활용해 질주하는 택시가 원숭이를 밀어낼 수 있도록 만들어 봅시다. 원숭이를 밀어내기 위해서는 원숭이가 택시 위치를 확인하고, 택시가 원숭이게 근접하면 원숭이의 RigidbodyComponent에 힘을 주도록 만들어봅시다. 1. **Workspace - MyDesk - Create Scripts - Create Component**을 선택해 새 스크립트 컴포넌트를 추가하고 이름을 **Monkey**로 변경합니다. 2. **Monkey** 엔티티에 **Monkey 컴포넌트**를 추가합니
[task] | two_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | UI 버튼(UIPower, UIMoney)을 통해 증가하는 힘과 돈을 확인하는 기능을 구현하려면 어떤 절차가 필요한가요? [answer] | 참고 문서에는 **UIPower**와 **UIMoney** 텍스트 UI를 생성하는 단계와, `PlayerController` 컴포넌트에 `SizeSet()` 메서드를 추가하여 캐릭터 크기를 조절하는 코드가 포함되어 있습니다. 하지만, 질문에서 요구하는 **"UI 버튼(UIPower, UIMoney)을 통해 증가하는 힘과 돈을 확인하는 기능"을 구현하는 구체적인 mLua 코드(스탯 값을 UI 텍스트에 연결하는 로직)는 제공된 문서에 없습니다.** 문서에 명시된 내용만으로는 다음과 같은 절차까지만 확인할 수 있습니다: 1. ** [followup] | `UIPower` 텍스트 UI에 `Stats.CurrentPow` 값을 실시간으로 표시하기 위해, 어떤 이벤트 핸들러(예: `HandleUpdateEvent` 또는 커스텀 이벤트)를 사용하여 텍스트 내용을 업데이트하는 mLua 코드 예시를 작성해 주세요. [followup_answer] | 제공된 참고 문서에는 `UIPower` 텍스트 UI에 `Stats.CurrentPow` 값을 실시간으로 표시하는 mLua 코드, 관련 이벤트 핸들러(`HandleUpdateEvent` 또는 커스텀 이벤트), 또는 UI 텍스트를 업데이트하는 API가 포함되어 있지 않습니다. 문서에 명시된 내용은 다음과 같습니다: 1. `DefaultGroup`에 텍스트 UI를 추가하여 이름을 `UIPower`로 변경하는 절차. 2. `PlayerController` 컴포넌트에 `SizeSet()` 메서드를 작성하여 `self.Stats.Curr [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] | two_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | `KinematicMove` 적용 후 캐릭터의 이동 영역 제한이 프레임마다 클라이언트에서 수행되도록 설계된 이유와, 서버-클라이언트 간 동기화 문제(캐릭터가 튀는 현상)를 방지하기 위해 `OnUpdate()`와 `MoveArea()`의 실행 공간 설정이 서로 다른 이유는? [answer] | `KinematicMove` 적용 후 캐릭터의 이동 영역 제한을 프레임마다 클라이언트에서 수행하도록 설계하고, `OnUpdate()`와 `MoveArea()`의 실행 공간을 다르게 설정하는 이유는 다음과 같습니다. **1. `MoveArea()`를 `client only`로 설정한 이유** `KinematicMove`는 물리 엔진이 아닌 스크립트 기반의 이동 방식입니다. 캐릭터가 지정된 지면 영역(예: y좌표 -1.23 ~ -2.6) 밖으로 벗어나지 않도록 위치를 보정하는 로직은 시각적인 정확도와 반응 속도가 중요합니다. 이 보정 [followup] | 만약 `MoveArea()`의 실행 공간을 `server only`로 변경하거나 `OnUpdate()`의 실행 공간을 `server`로 설정하면 어떤 문제가 발생하며, 문서에서 권장하는 '사용하지 않음' 상태에서의 최종 코드 형태는? [followup_answer] | `MoveArea()`의 실행 공간을 `server only`로 변경하거나 `OnUpdate()`의 실행 공간을 `server`로 설정하면, **보정 과정에서 캐릭터가 튀는 것처럼 보이는 시각적 오류**가 발생할 수 있습니다. 이는 서버에서 위치 보정이 수행될 때, 클라이언트와 서버 간의 상태 동기화 차이로 인해 캐릭터 위치가 불일치하거나, 네트워크 지연으로 인해 보정이 늦게 반영되면서 화면 상에서 캐릭터가 순간적으로 다른 위치로 점프하는 현상이 생기기 때문입니다. 따라서 문서에서는 이러한 문제를 방지하기 위해 실제 위치 제한 로 [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 운동할수록 캐릭터가 커지고, 그 힘을 돈으로 바꿀 수 있는 월드, 'Maple GYM'을 만들어봅시다. # 이동 방식 변경 RigidBodyComponent의 **KinematicMove**를 활용해 캐릭터의 이동 방식을 변경해봅시다. **DefaultPlayer - RigidBodyComponent**에서 **KinematicMove**를 선택합니다. #### 이동 영역 제한 캐릭터의 이동 방식을 **KinematicMove**로 변경하면 캐릭터가 자유롭게 상하좌우로 이동하게 됩니다. 캐릭터가 지면 영
[task] | code [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | PlayerStats 컴포넌트에서 OnBeginPlay 생명주기 메서드를 구현하여 IsClient() 조건 하에 _EntityService:GetEntityByPath("/ui/DefaultGroup")을 통해 엔티티를 조회하고 .UIManager 프로퍼티를 self.UiManager에 할당하는 스크립트를 작성해줘. [answer] | PlayerStats 컴포넌트에 OnBeginPlay 메서드를 구현하고, 클라이언트 환경인지 확인한 뒤 /ui/DefaultGroup 경로의 엔티티에서 UIManager를 조회하여 self.UiManager에 저장하는 스크립트는 다음과 같습니다. ```lua Method: void OnBeginPlay() { if self:IsClient() then self.UiManager = _EntityService:GetEntityByPath("/ui/DefaultGroup").UIManager end } [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] | code [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | PlayerStats 컴포넌트에 [client only] 실행 공간의 RenewMoney 메서드를 추가하여 self.UiManager:UISetMoney()를 호출함으로써 돈 UI를 갱신하는 스크립트를 작성해줘. [answer] | PlayerStats 컴포넌트에 [client only] 실행 공간의 RenewMoney 메서드를 추가하여 돈 UI를 갱신하는 스크립트는 다음과 같습니다. ```lua Method: [client only] void RenewMoney() { self.UiManager:UISetMoney() } ``` [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] | 캐릭터의 힘(Stats.CurrentPow)이 증가할 때마다 크기가 0.1씩 커지도록 `SizeSet()` 메소드를 구현하는 방법은? [answer] | `SizeSet()` 메소드를 구현하려면 `PlayerController` 컴포넌트에 해당 메소드를 추가하고, 현재 힘(`Stats.CurrentPow`)에 0.1을 곱한 값에 1을 더한 결과를 스케일로 적용하는 코드를 작성해야 합니다. 구체적인 구현 방법은 다음과 같습니다. 1. **`PlayerController` 컴포넌트에 `SizeSet()` 메소드 생성** 2. **메소드 본문 작성**: * 현재 힘(`self.Stats.CurrentPow`)을 기준으로 스케일 값을 계산합니다. * 계산식은 ` [followup] | `SizeSet()` 메소드에서 `Vector3(size, size, 1)`으로 스케일을 설정할 때, Z축을 1로 고정하는 대신 X, Y, Z 모두 `size` 값을 적용하려면 코드를 어떻게 수정해야 하나요? [followup_answer] | `SizeSet()` 메소드에서 Z축을 1로 고정하는 대신 X, Y, Z 모두에 `size` 값을 적용하려면, `Vector3` 생성 시 Z축 인자도 `size`로 변경하면 됩니다. 수정된 `SizeSet()` 메소드는 다음과 같습니다. ```lua void SizeSet() { local size = 1 + (0.1 * self.Stats.CurrentPow) self.Transform.Scale = Vector3(size, size, size) } ``` 이 코드는 현재 힘(`self.Stats.Current [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] | instruction_following [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅱ [question] | SetTable() 메서드에서 초기화되는 SkillGradeTable의 10단계 등급별 Cost와 WeightBonus 값을 표로 정리해서 출력하세요. [answer] | `SetTable()` 메서드에서 초기화되는 `SkillGradeTable`의 10단계 등급별 정보는 다음과 같습니다. | 단계 (GradeName) | 비용 (Cost) | 힘 보너스 (WeightBonus) | | :--- | :--- | :--- | | 1단계 | 0 | 1 | | 2단계 | 15 | 2 | | 3단계 | 45 | 3 | | 4단계 | 90 | 4 | | 5단계 | 187 | 5 | | 6단계 | 315 | 6 | | 7단계 | 600 | 7 | | 8단계 | 1200 | 8 | | 9단계 | 2150 | 9 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 운동 기술과 DNA는 돈을 사용해 업그레이드 할 수 있습니다. 그러므로 각각의 등급에서 증가하는 힘과 누적 가능한 힘, 필요한 금액 정보를 구성해 봅시다. > **Tip.** > 관리할 데이터가 많아질 경우 스크립트에 직접 입력하는 대신 공식을 사용하거나, 데이터셋을 사용해 효율적으로 관리할 수 있습니다. 1. **PlayerStats** 컴포넌트에 새로운 프로퍼티 2개를 추가합니다. ```lua Property: [None] table SkillGradeTable = {} -- 운동 스킬 관련 테
[task] | instruction_following [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅱ [question] | buttonPaths 테이블에 등록된 5개 버튼의 경로와 OnClickButton 메서드에서 수행하는 동작을 매칭시켜 표로 정리하세요. [answer] | buttonPaths 테이블에 등록된 5개 버튼의 경로와 `OnClickButton` 메서드에서 수행하는 동작은 다음과 같습니다. | 버튼 경로 (Path) | 버튼 이름 (Name) | 수행 동작 | | :--- | :--- | :--- | | `/ui/DefaultGroup/ShopButton` | `ShopButton` | `self.ShopGroup` (상점 UI)의 가시성을 `true`로 설정하여 상점 UI를 표시합니다. | | `/ui/DefaultGroup/SellButton` | `SellButton` | `self [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] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅱ [question] | UI 엔티티가 다른 요소에 가려 보이지 않을 때 해결책으로 언급된 하이어라키 순서 변경은 구체적으로 어떻게 진행해야 하나요? [answer] | 제공된 문서에는 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] | instruction_following [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅱ [question] | 문서에 명시된 `UIManager` 컴포넌트의 4개 신규 프로퍼티 선언 코드를 출력하되, 설명은 주석으로만 작성하고 코드 블록만 포함하세요. [answer] | ```lua Property: [None] Component SkillLevelText = nil [None] Component DnaLevelText = nil [None] Component SkillUpButtonText = nil [None] Component DnaUpButtonText = nil ``` [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 상점에 알맞는 정보가 표시될 수 있도록 만들어봅시다. 1. **UIManager** 컴포넌트에 새로운 프로퍼티를 4개를 추가합니다. 이 프로퍼티들은 **TextComponent** 정보를 가집니다. ```lua Property: [None] Component SkillLevelText = nil [None] Component DnaLevelText = nil [None] Component SkillUpButtonText = nil [None] Componen
[task] | code [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | PlayerStats 컴포넌트의 SetPow 메서드 본문 가장 아래에 self:RenewPow() 호출을 추가하여 힘 증가 시 UI 갱신 로직이 실행되도록 수정하는 스크립트를 작성해줘. [answer] | 참고 문서에 따르면, `PlayerStats` 컴포넌트의 `SetPow()` 메서드 본문 가장 아래에 `self:RenewPow()` 호출을 추가하면 됩니다. `SetPow()` 메서드의 기존 본문 내용은 문서에 제공되지 않아 알 수 없습니다. 따라서 아래 예제는 `SetPow()` 메서드가 존재한다고 가정하고, 그 본문 마지막 줄에 `self:RenewPow()`를 추가하는 형태를 보여줍니다. 실제 적용 시에는 기존 `SetPow()` 메서드 내부 코드를 유지한 채 마지막 줄에만 해당 코드를 추가해야 합니다. ```lua Me [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] | 상점 UI를 닫을 때 SetVisible(false, false)를 호출하는 두 번째 인자 false는 어떤 의미를 가지며, true로 설정하면 어떻게 달라지나요? [answer] | 제공된 참고 문서에는 `SetVisible` 메서드의 두 번째 인자 `false`의 구체적인 의미나, `true`로 설정했을 때의 동작 차이에 대한 설명이 포함되어 있지 않습니다. 문서에는 `ShopCloseButton`을 눌렀을 때 `self.ShopGroup:SetVisible(false, false)`를 호출하여 상점 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] | instruction_following [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅱ [question] | `SetShopInfo()` 메소드 작성 시 참고해야 하는 `PlayerStats` 기반 금액 확인 및 색상 변경 로직의 핵심 처리 흐름을 3문장 이내로 요약하세요. [answer] | `PlayerStats` 컴포넌트에 정의된 테이블 정보를 기반으로 현재 금액을 확인합니다. 확인된 금액을 토대로 UI 텍스트의 색상을 변경합니다. 변경된 금액과 색상 정보를 상점 UI에 표시하여 적절한 정보를 제공합니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 상점에 알맞는 정보가 표시될 수 있도록 만들어봅시다. 1. **UIManager** 컴포넌트에 새로운 프로퍼티를 4개를 추가합니다. 이 프로퍼티들은 **TextComponent** 정보를 가집니다. ```lua Property: [None] Component SkillLevelText = nil [None] Component DnaLevelText = nil [None] Component SkillUpButtonText = nil [None] Componen
[task] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅱ [question] | UIManager에서 PlayerController를 참조하기 위해 [None] 속성을 가진 component 타입의 Controller 프로퍼티를 선언하는 이유는 무엇인가요? [answer] | `[None]` 속성을 가진 `component` 타입의 `Controller` 프로퍼티를 선언하는 이유는 다음과 같습니다. 1. **클라이언트/서버 동기화 불필요**: `[None]` 속성은 해당 프로퍼티가 클라이언트와 서버 간에 동기화되지 않음을 의미합니다. `PlayerController`는 로컬 플레이어의 조작을 담당하는 로컬 전용 컴포넌트이므로, 서버나 다른 클라이언트와 상태 정보를 공유할 필요가 없습니다. 2. **타입 안전성 및 참조 관리**: `component` 타입을 명시함으로써, 이 프로퍼티가 특정 엔티티에 연 [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] | OnClickButton 메서드에서 buttonName을 비교하여 분기 처리하는 방식에서, 버튼 이름이 path의 마지막 부분과 다르면 어떤 오류가 발생하나요? [answer] | 제공된 참고 문서에는 `OnClickButton` 메서드에서 버튼 이름이 path의 마지막 부분과 다를 경우 발생하는 구체적인 오류 유형이나 에러 메시지에 대한 정보가 없습니다. 문서에는 `OnClickButton` 메서드 내에서 `event.Entity.Name`을 `buttonName` 변수에 저장하고, 이를 `"ShopButton"`, `"SellButton"`, `"ShopCloseButton"` 등 특정 문자열과 `==` 연산자로 비교하는 분기 처리 구조만 제시되어 있습니다. 따라서 버튼 이름이 path의 마지막 부분과 [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] | PlayerStats 컴포넌트에 실행 공간이 Multicast인 SetMoney(number currentMoney) 메서드를 추가하여, 전달받은 값으로 CurrentMoney 프로퍼티를 갱신하고 UI의 돈 값을 새로고침하기 위해 RenewMoney() 메서드를 호출하는 스크립트를 작성해줘. [answer] | ```lua Method: [multicast] void SetMoney(number currentMoney) { self.CurrentMoney = currentMoney self:RenewMoney() } ``` [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] | 물체의 이동 Ⅱ [question] | `Property` 블록에서 `MonkeyTransform`, `TaxiTransform` 등을 `Component` 타입으로 선언했는데, `OnBeginPlay()`에서 `TransformComponent`와 `RigidbodyComponent`를 각각 할당하는 이유는 무엇이며, 다른 타입으로 선언하면 어떤 문제가 발생할까요? [answer] | `Property` 블록에서 `MonkeyTransform`, `TaxiTransform`, `MonkeyRigidbody`를 `Component` 타입으로 선언하고 `OnBeginPlay()`에서 각각 `TransformComponent`와 `RigidbodyComponent`를 할당하는 이유는 **mLua에서 특정 컴포넌트(예: Transform, Rigidbody)를 직접 참조하기 위한 표준 접근 방식**을 따르기 위함입니다. 구체적인 이유와 다른 타입으로 선언 시 발생할 수 있는 문제는 다음과 같습니다. ### 1. `C [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] | UISetPower 메서드에서 math.floor를 사용하여 소수점을 버리고 있는데, 만약 Stats.CurrentPow가 음수이거나 nil 값일 경우 스크립트가 정상적으로 동작하지 않을 수 있는 이유는 무엇인가요? [answer] | `UISetPower` 메서드에서 `math.floor(self.Stats.CurrentPow)`를 사용할 때, `Stats.CurrentPow`가 `nil`이거나 음수인 경우 스크립트가 정상적으로 동작하지 않을 수 있는 이유는 다음과 같습니다. ### 1. `nil` 값인 경우 mLua(Lua 5.3) 환경에서 `math.floor()` 함수는 숫자(number) 타입을 인수로 요구합니다. 만약 `self.Stats.CurrentPow`가 `nil`이라면, `math.floor(nil)`을 호출하는 것과 동일해지며 **타입 오류 [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] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅱ [question] | OnClickButton에서 event.Entity.Name을 기준으로 분기 처리할 때, 버튼 이름이 "SellButton"으로 정확히 일치해야만 동작하는 구조인가요? [answer] | 네, 네이티브 문자열 비교 연산자(`==`)를 사용하므로 버튼 이름이 `"SellButton"`과 **완전히 일치**해야만 해당 분기가 실행됩니다. 참고 문서의 `OnClickButton()` 메소드 예시를 보면 다음과 같이 작성되어 있습니다. ```lua void OnClickButton(any event) { local buttonName = event.Entity.Name if buttonName == "ShopButton" then elseif buttonName == "SellButton" th [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] | code [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | TriggerComponent를 확장한 NPCSellPow 컴포넌트에서 OnEnterTriggerBody()를 오버라이드하여, 진입한 엔티티에 PlayerStats 컴포넌트가 존재하는지 확인하고 존재할 경우 해당 컴포넌트의 SellPow() 메서드를 호출하는 스크립트를 작성해줘. [answer] | 문서에 제시된 `NPCSellPow` 컴포넌트 스크립트는 다음과 같습니다. ```lua Method: [server] override void OnEnterTriggerBody(TriggerEnterEvent enterEvent) { local entity = enterEvent.TriggerBodyEntity log(entity) if entity.PlayerStats == nil then return else entity.PlayerStats:SellPow() [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] | instruction_following [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅱ [question] | ShopCloseButton 클릭 시 ShopGroup의 가시성을 변경하는 코드 한 줄을 3문장 이내로 [answer] | ```lua self.ShopGroup:SetVisible(false, false) ``` 이 코드는 ShopCloseButton 클릭 시 ShopGroup의 가시성을 숨기도록 설정합니다. 두 번째 매개변수 false는 가시성 변경 시 애니메이션을 사용하지 않음을 의미합니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | if buttonName == "ShopButton" then self:SetShopInfo() -- 추가 self.ShopGroup:SetVisible(true, false) elseif buttonName == "SellButton" then self.Controller:MoveSellPosition() self:SetShopInfo() -- 추가 elseif buttonName == "ShopCloseButton" then self.ShopGroup:SetVisible(false, false)
[task] | instruction_following [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅱ [question] | SellButton 클릭 시 실행되는 두 가지 메서드 호출 순서를 코드만 출력하고 설명은 주석으로 [answer] | ```lua -- SellButton 클릭 시 실행되는 두 가지 메서드 호출 순서 -- 1. self.Controller:MoveSellPosition() -- 2. self:SetShopInfo() if buttonName == "SellButton" then self.Controller:MoveSellPosition() self:SetShopInfo() end ``` [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | if buttonName == "ShopButton" then self:SetShopInfo() -- 추가 self.ShopGroup:SetVisible(true, false) elseif buttonName == "SellButton" then self.Controller:MoveSellPosition() self:SetShopInfo() -- 추가 elseif buttonName == "ShopCloseButton" then self.ShopGroup:SetVisible(false, false)
[task] | instruction_following [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅱ [question] | SetShopInfo() 함수에서 스킬과 DNA의 버튼 텍스트 및 폰트 색상이 결정되는 조건을 3문장 이내로 요약하세요. [answer] | 각 속성의 현재 등급이 최대 등급에 도달했다면 "최종 등급 달성"이라는 텍스트와 빨간색(Color(1,0,0,1))이 설정됩니다. 최대 등급이 아니라면 다음 등급에 필요한 금액이 표시되며, 보유 금액이 필요 금액보다 크거나 같으면 흰색(Color(1,1,1,1))으로, 부족하면 빨간색(Color(1,0,0,1))으로 색상이 결정됩니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | ```lua void SetShopInfo() { local skillGrade = math.floor(self.Stats.CurrentSkillGrade) local dnaGrade = math.floor(self.Stats.CurrentDnaGrade) self.SkillLevelText.Text = ("기술 레벨: "..skillGrade.."레벨") self.DnaLevelText.Text = ("DNA: "..self.Stats.DnaG
[task] | two_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅱ [question] | NPC 위치로 이동 기능을 구현하기 위해 버튼 클릭 이벤트와 어떤 서비스 API를 조합해서 사용해야 하나요? [answer] | NPC 위치로 이동 기능을 구현하려면, UI 버튼의 클릭 이벤트(`ButtonClickEvent`)를 감지하고 플레이어의 위치를 변경하는 로직을 연결해야 합니다. 참고 문서의 `[실제 mLua 예제]` 블록들을 분석하면, 버튼 클릭 시 특정 동작을 수행하는 패턴은 다음과 같습니다: 1. **UI 버튼 생성 및 이벤트 연결**: `_SpawnService:SpawnByModelId`로 버튼을 생성한 후, `ConnectEvent(ButtonClickEvent, callback)` 메서드를 사용하여 클릭 시 실행될 함수(`call [followup] | `_EntityService`와 `_SpawnService` 중 어떤 것을 주로 사용하여 이동 대상 NPC의 위치를 조회하고, 해당 좌표로 플레이어를 이동시키는 mLua 코드 예시를 보여주세요. [followup_answer] | 참고 문서를 분석한 결과, **NPC 위치를 조회하여 플레이어를 해당 좌표로 이동시키는 구체적인 mLua 코드 예시나 관련 API(예: 플레이어 위치 설정 메서드, NPC TransformComponent 접근 후 이동 처리 로직)는 문서에 포함되어 있지 않습니다.** 문서에 제공된 `[실제 mLua 예제]` 블록들은 다음과 같은 기능만 수행합니다: 1. BGM 재생/정지/일시정지 (`_SoundService`) 2. 사운드 재생/정지 (`_SoundService`) 3. NPC 이름 조회 및 UI 텍스트 표시 (`_Enti [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