[task] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | SetPow 메서드에 [multicast] 태그를 붙이는 것과 붙이지 않을 때 동작 방식이 어떻게 다른가요? [answer] | 제공된 참고 문서에는 `SetPow` 메서드에 `[multicast]` 태그가 붙어 있는 코드가 예시로 제시되어 있습니다. ```lua [multicast] void SetPow (number currentPow) { self.CurrentPow = currentPow log(self.CurrentPow) } ``` 그러나 제공된 문서에는 **`[multicast]` 태그를 붙일 때와 붙이지 않을 때의 구체적인 동작 방식 차이(예: 서버/클라이언트 실행 범위, 동기화 방식 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | ```lua [multicast] void SetPow (number currentPow) { self.CurrentPow = currentPow log(self.CurrentPow) } ``` 8. `WorkOut()` 메소드에 `SetPow()` 메소드를 호출할 수 있도록 가장 하단에 아래 내용을 추가 작성합니다. ```lua self.Stats:SetPow(calePow) ``` 9. `Ctrl`키를 누를 때마다 숫자가 증가하는
[task] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | self.Stats:SetPow(calePow) 문장에서 calePow 변수가 WorkOut 메서드 외부에서 정의된 경우에도 정상적으로 전달되나요? [answer] | 제시된 참고 문서에는 `WorkOut()` 메서드 내부에서 `calePow` 변수가 어떻게 정의되는지, 또는 `SetPow()` 메서드에 전달되는 구체적인 코드 전체가 포함되어 있지 않습니다. 문서에는 `self.Stats:SetPow(calePow)`라는 호출 문구만 제시되어 있으며, `calePow` 변수의 범위(scope)나 `WorkOut()` 메서드 외부에서의 정의 여부에 대한 정보는 찾을 수 없습니다. 따라서 제공된 문서만을 근거로 할 때, `calePow` 변수가 `WorkOut()` 메서드 외부에서 정의된 경우에도 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | ```lua [multicast] void SetPow (number currentPow) { self.CurrentPow = currentPow log(self.CurrentPow) } ``` 8. `WorkOut()` 메소드에 `SetPow()` 메소드를 호출할 수 있도록 가장 하단에 아래 내용을 추가 작성합니다. ```lua self.Stats:SetPow(calePow) ``` 9. `Ctrl`키를 누를 때마다 숫자가 증가하는
[task] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | 이동 영역 제한 로직에서 self.Movement:SetPosition을 호출할 때 X좌표는 그대로 유지하고 Y좌표만 변경하는 Vector2 구조를 사용하는 이유는 무엇인가요? [answer] | KinematicMove 이동 방식을 사용했을 때 캐릭터는 지면 영역 외에도 상하좌우로 자유롭게 이동할 수 있습니다. 이 문제를 해결하기 위해 캐릭터가 특정 지면 영역(예: y축 -1.23에서 -2.6 사이)에만 머물 수 있도록 위치를 보정해야 합니다. 이때 `Vector2(pos.x, -1.23)`와 같이 X좌표는 현재 값(`pos.x`)을 그대로 유지하고 Y좌표만 제한된 값으로 변경하는 이유는 다음과 같습니다. 1. **수평 이동(좌우)은 허용, 수직 이동(상하)만 제한:** 게임의 목적상 캐릭터가 좌우로 자유롭게 이동 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 운동할수록 캐릭터가 커지고, 그 힘을 돈으로 바꿀 수 있는 월드, 'Maple GYM'을 만들어봅시다. # 이동 방식 변경 RigidBodyComponent의 **KinematicMove**를 활용해 캐릭터의 이동 방식을 변경해봅시다. **DefaultPlayer - RigidBodyComponent**에서 **KinematicMove**를 선택합니다. #### 이동 영역 제한 캐릭터의 이동 방식을 **KinematicMove**로 변경하면 캐릭터가 자유롭게 상하좌우로 이동하게 됩니다. 캐릭터가 지면 영
[task] | instruction_following [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | UIManager 컴포넌트의 Property 블록을 포함하여 UISetPower()와 UISetMoney() 메소드 본문만 코드 블록으로 출력하세요. [answer] | ```lua Property: [None] Component UiPowerText = nil -- UIPower 엔티티의 Text 컴포넌트 정보 [None] Component UiMoneyText = nil-- UIMoney 엔티티의 Text 컴포넌트 정보 [None] Component Stats = nil -- 캐릭터의 PlayerStats 컴포넌트 정보 Method: void UISetPower() { self.UiPowerText.Text = "힘: "..math.floor(self.Stats.CurrentPow). [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] | PlayerController에서 TransformComponent와 MovementComponent를 직접 참조하기 위해 OnBeginPlay에서 self.Entity를 통해 가져오는 이유는 무엇인가요? [answer] | mLua 스크립트에서 `OnBeginPlay()` 메서드 안에서 `self.Entity.TransformComponent`와 `self.Entity.MovementComponent`를 통해 컴포넌트를 직접 참조하여 프로퍼티(`self.Transform`, `self.Movement`)에 저장하는 이유는 다음과 같습니다. 1. **성능 최적화 (메모리 접근 최소화)**: `OnUpdate()`처럼 매 프레임마다 호출되는 함수에서 `self.Entity.TransformComponent.Position`과 같은 방식으로 접근 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 운동할수록 캐릭터가 커지고, 그 힘을 돈으로 바꿀 수 있는 월드, 'Maple GYM'을 만들어봅시다. # 이동 방식 변경 RigidBodyComponent의 **KinematicMove**를 활용해 캐릭터의 이동 방식을 변경해봅시다. **DefaultPlayer - RigidBodyComponent**에서 **KinematicMove**를 선택합니다. #### 이동 영역 제한 캐릭터의 이동 방식을 **KinematicMove**로 변경하면 캐릭터가 자유롭게 상하좌우로 이동하게 됩니다. 캐릭터가 지면 영
[task] | single_turn [pass] | ⏳ 미판정 [title] | 물체의 이동 Ⅰ [question] | 택시가 아잘린의 정확한 위치까지 도달한 후에도 계속 미세하게 움직이거나 멈추지 않을 때, OnUpdate의 조건문에서 어떤 부등호나 로직을 수정해야 하는지 조언해 주실 수 있나요? [answer] | 제공된 참고 문서에는 택시가 아잘린의 위치(`targetPos.x`)에 도달하거나 가까워질 때 **멈추는 로직(조건문)이 포함되어 있지 않습니다.** 문서의 `OnUpdate()` 예제 코드는 단순히 `pos.x < targetPos.x`일 때만 `pos.x`를 증가시키는 내용이며, `else` 블록이나 거리가 일정 범위 내일 때 `Position` 변경을 중단하는 조건이 명시되어 있지 않습니다. 따라서, "아잘린의 위치까지 도달한 후에도 계속 미세하게 움직이거나 멈추지 않을 때"의 해결책에 대한 구체적인 API나 수정 방법은 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 만든 택시는 멈추지 않고 계속 이동하고 있습니다. 택시는 아잘린이 서 있는 곳에서 멈춰야 하므로, 아잘린의 위치 정보를 이용해야 합니다. 택시가 이동하다 아잘린과의 거리가 가까워지면, 멈추도록 조건을 추가해봅시다. 1. **Taxi**컴포넌트에 새로운 **AzallinTransform** 프로퍼티를 추가하고, 타입을 **Component**로 변경합니다. ```lua Property: [Sync] Component AzallinTransform = nil ``` 2. `OnBeginP
[task] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | KinematicMove 모드에서 캐릭터의 Y좌표가 특정 범위를 벗어나지 않도록 제한하는 로직을 클라이언트에서 처리해야 하는 이유를 설명해 주세요. [answer] | KinematicMove 모드에서 캐릭터의 Y좌표 범위를 제한하는 로직을 클라이언트에서 처리해야 하는 주된 이유는 **시각적 안정성(보정 과정에서의 튀는 현상 방지)** 때문입니다. 서버와 클라이언트 모두에서 위치 보정이 일어나도록 하면(`OnUpdate` 실행 공간을 설정하지 않음), 서버의 처리와 클라이언트의 처리 사이에 미세한 차이나 지연이 발생할 수 있습니다. 이로 인해 캐릭터가 정해진 경계를 넘는 순간에 위치가 순간적으로 원래 자리로 되돌아오는 것처럼 보이거나, 경계선 근처에서 캐릭터가 떨리거나 튀는 현상이 발생하여 플레 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 운동할수록 캐릭터가 커지고, 그 힘을 돈으로 바꿀 수 있는 월드, 'Maple GYM'을 만들어봅시다. # 이동 방식 변경 RigidBodyComponent의 **KinematicMove**를 활용해 캐릭터의 이동 방식을 변경해봅시다. **DefaultPlayer - RigidBodyComponent**에서 **KinematicMove**를 선택합니다. #### 이동 영역 제한 캐릭터의 이동 방식을 **KinematicMove**로 변경하면 캐릭터가 자유롭게 상하좌우로 이동하게 됩니다. 캐릭터가 지면 영
[task] | code [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | PlayerStats 컴포넌트의 CurrentMoney 프로퍼티를 통해 현재 캐릭터의 돈을 관리하고, 특정 액수만큼 돈을 추가하거나 차감할 때 음수값이 되지 않도록 처리하는 스크립트를 작성해줘 [answer] | `PlayerStats` 컴포넌트의 `CurrentMoney` 프로퍼티를 활용하여 돈을 관리하고, 차감 시 음수값이 발생하지 않도록 처리하는 스크립트입니다. ```lua Property: [Sync] number CurrentMoney = 0 Method: [server only] void AddMoney(number amount) { self.CurrentMoney = self.CurrentMoney + amount } Method: [server only] void SubtractMoney(number amount) [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | Maple Gym에는 힘과 최대 누적 가능한 힘, 돈, 등급 등 다양한 스탯 정보가 필요합니다. 다양한 정보를 저장하고 관리할 수 있는 컴포넌트를 만들어 봅시다. 1. 새로운 **PlayerStats** 컴포넌트를 생성합니다. 2. **PlayerStats**컴포넌트를 **DefaultPlayer**에 추가합니다. 3. PlayerStats에 스탯 정보로 사용할 프로퍼티를 추가합니다. ```lua Property: [Sync] number CurrentPower = 0 --현재 캐릭터의 힘
[task] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | 로그에 self.CurrentPow 값이 중복으로 출력되면 multicast 호출 방식에 문제가 있다는 뜻인가요? [answer] | 아니요, `log`에 `self.CurrentPow` 값이 중복으로 출력된다고 해서 반드시 `multicast` 호출 방식에 문제가 있다고 단정할 수 없습니다. `[multicast]` 메서드는 서버와 클라이언트 양쪽에서 동시에 실행되는 실행 공간입니다. 따라서 `SetPow` 메서드 내부의 `log(self.CurrentPow)` 문장이 서버에서 한 번, 클라이언트에서 한 번 각각 실행되면 로그 창에는 같은 값이 두 줄로 출력됩니다. 이는 `multicast`의 동작 방식상 자연스러운 현상일 수 있으며, 오류나 중복 호출 문제라 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | ```lua [multicast] void SetPow (number currentPow) { self.CurrentPow = currentPow log(self.CurrentPow) } ``` 8. `WorkOut()` 메소드에 `SetPow()` 메소드를 호출할 수 있도록 가장 하단에 아래 내용을 추가 작성합니다. ```lua self.Stats:SetPow(calePow) ``` 9. `Ctrl`키를 누를 때마다 숫자가 증가하는
[task] | single_turn [pass] | ⏳ 미판정 [title] | 물체의 이동 Ⅰ [question] | OnUpdate 함수에서 현재 위치와 타겟 위치를 비교할 때, 단순히 pos.x < targetPos.x 조건만 사용하는 것이 항상 올바른 방향으로 이동하게 만드는 건지, 좌표가 반대일 경우 오류가 나는지 궁금합니다. [answer] | 제시된 가이드 문서의 예시 코드(`pos.x < targetPos.x`)는 **택시가 아잘린보다 왼쪽(x 좌표가 더 작은)에 있을 때만 오른쪽으로 이동**하도록 설계되어 있습니다. 따라서 이 조건만으로는 항상 올바른 방향으로 이동하지 않으며, 좌표가 반대인 경우(택시가 아잘린 오른쪽에 있는 경우)에는 택시가 움직이지 않고 멈춰 있게 됩니다. 구체적인 동작은 다음과 같습니다: 1. **택시 위치 < 아잘린 위치 (`pos.x < targetPos.x`)**: * 조건이 `true`가 되어 `pos.x`가 증가합니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 만든 택시는 멈추지 않고 계속 이동하고 있습니다. 택시는 아잘린이 서 있는 곳에서 멈춰야 하므로, 아잘린의 위치 정보를 이용해야 합니다. 택시가 이동하다 아잘린과의 거리가 가까워지면, 멈추도록 조건을 추가해봅시다. 1. **Taxi**컴포넌트에 새로운 **AzallinTransform** 프로퍼티를 추가하고, 타입을 **Component**로 변경합니다. ```lua Property: [Sync] Component AzallinTransform = nil ``` 2. `OnBeginP
[task] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | OnUpdate 메서드의 실행 공간을 '사용하지 않음'으로 설정하면 서버와 클라이언트 모두에서 호출되는데, 이때 내부에서 호출하는 MoveArea 메서드의 실행 공간이 client only인 경우 어떤 동작이 발생하나요? [answer] | `OnUpdate` 메서드의 실행 공간이 '사용하지 않음'으로 설정되어 서버와 클라이언트 양쪽에서 호출되더라도, 내부에서 호출하는 `MoveArea` 메서드의 실행 공간이 `client only`로 지정되어 있기 때문에 실제 위치 보정 로직은 **클라이언트에서만 실행**됩니다. 구체적인 동작은 다음과 같습니다: 1. **서버 측 동작:** 서버의 `OnUpdate`가 실행되어 `self:MoveArea()`를 호출하게 되지만, `MoveArea` 함수 내부의 코드(위치가 범위를 벗어나는지 확인하고 `SetPosition`으로 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 운동할수록 캐릭터가 커지고, 그 힘을 돈으로 바꿀 수 있는 월드, 'Maple GYM'을 만들어봅시다. # 이동 방식 변경 RigidBodyComponent의 **KinematicMove**를 활용해 캐릭터의 이동 방식을 변경해봅시다. **DefaultPlayer - RigidBodyComponent**에서 **KinematicMove**를 선택합니다. #### 이동 영역 제한 캐릭터의 이동 방식을 **KinematicMove**로 변경하면 캐릭터가 자유롭게 상하좌우로 이동하게 됩니다. 캐릭터가 지면 영
[task] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | Ctrl 키를 눌렀을 때 로그에 숫자가 안 올라오면, WorkOut 함수 내부에서 self.Stats:SetPow 호출 누락 외에 어떤 원인이 있을까요? [answer] | 참고 문서에 제공된 정보만으로는 `Ctrl` 키 입력 이벤트 처리 자체나 `WorkOut()` 함수의 트리거 조건에 대한 코드가 포함되어 있지 않습니다. 문서에는 `WorkOut()` 메소드 내부에서 `self.Stats:SetPow(calePow)`를 호출하는 마지막 단계와, `SetPow` 메소드가 `multicast` 실행 공간에서 `self.CurrentPow`를 업데이트하고 `log`를 출력하는 부분, 그리고 `Ctrl` 키를 누르면 숫자가 증가하는 로그가 출력되어야 한다는 결과 확인 사항만 명시되어 있습니다. 따라서 ` [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | ```lua [multicast] void SetPow (number currentPow) { self.CurrentPow = currentPow log(self.CurrentPow) } ``` 8. `WorkOut()` 메소드에 `SetPow()` 메소드를 호출할 수 있도록 가장 하단에 아래 내용을 추가 작성합니다. ```lua self.Stats:SetPow(calePow) ``` 9. `Ctrl`키를 누를 때마다 숫자가 증가하는
[task] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | WeightBonus 프로퍼티의 초기값이 1로 설정되어 있는데, 운동 시 힘 증가량이 0이 되려면 어떤 값을 지정해야 하나요? [answer] | WeightBonus 프로퍼티의 초기값이 1인 상태에서 운동 시 힘 증가량이 0이 되려면, WeightBonus 값 자체를 0으로 지정해야 합니다. 참고 문서에 제공된 mLua 예제에서는 WeightBonus 프로퍼티의 선언과 초기값 설정(`number WeightBonus = 1`)만 언급되어 있으며, 운동 시 힘을 실제로 증가시키는 로직(예: `CurrentPower = CurrentPower + WeightBonus`)에 대한 구체적인 코드 예제는 포함되어 있지 않습니다. 따라서 일반적인 수학적 원리에 따라, 증가할 값(` [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | Maple Gym에는 힘과 최대 누적 가능한 힘, 돈, 등급 등 다양한 스탯 정보가 필요합니다. 다양한 정보를 저장하고 관리할 수 있는 컴포넌트를 만들어 봅시다. 1. 새로운 **PlayerStats** 컴포넌트를 생성합니다. 2. **PlayerStats**컴포넌트를 **DefaultPlayer**에 추가합니다. 3. PlayerStats에 스탯 정보로 사용할 프로퍼티를 추가합니다. ```lua Property: [Sync] number CurrentPower = 0 --현재 캐릭터의 힘
[task] | single_turn [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | PlayerStats 컴포넌트의 프로퍼티에 [Sync] 태그를 붙여야 하는 구체적인 이유는 무엇인가요? [answer] | 메이플스토리 월드(mLua)에서 `[Sync]` 태그는 서버와 클라이언트 간의 데이터 동기화를 제어하는 핵심 메커니즘입니다. `PlayerStats` 컴포넌트의 프로퍼티에 `[Sync]`를 붙여야 하는 구체적인 이유는 다음과 같습니다. 1. **클라이언트(플레이어 화면)에 실시간 반영**: `PlayerStats`의 `CurrentPower`, `CurrentMoney`, `CurrentSkillGrade` 등은 플레이어의 상태(힘, 돈, 등급)를 나타내는 값입니다. 이 값들이 서버에서 변경되었을 때, 플레이어가 자신의 화면 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | Maple Gym에는 힘과 최대 누적 가능한 힘, 돈, 등급 등 다양한 스탯 정보가 필요합니다. 다양한 정보를 저장하고 관리할 수 있는 컴포넌트를 만들어 봅시다. 1. 새로운 **PlayerStats** 컴포넌트를 생성합니다. 2. **PlayerStats**컴포넌트를 **DefaultPlayer**에 추가합니다. 3. PlayerStats에 스탯 정보로 사용할 프로퍼티를 추가합니다. ```lua Property: [Sync] number CurrentPower = 0 --현재 캐릭터의 힘
[task] | two_turn [pass] | ⏳ 미판정 [title] | 물체의 이동 Ⅰ [question] | OnUpdate() 함수에서 택시의 현재 위치와 아잘린의 위치를 비교하여 이동 중단 조건을 구현하려면 어떤 프로퍼티와 메서드를 사용해야 하나요? [answer] | 택시의 현재 위치와 아잘린의 위치를 비교하여 이동 중단 조건을 구현하기 위해 필요한 프로퍼티와 메서드는 다음과 같습니다. **1. 필요한 프로퍼티** * `AzallinTransform`: 아잘린 엔티티의 Transform 컴포넌트를 저장하기 위한 프로퍼티입니다. 타입은 `Component`로 설정해야 하며, `[Sync]` 속성을 부여합니다. * `TaxiTransform`: 택시 엔티티 자체의 Transform 컴포넌트입니다. (참고 문서의 `OnUpdate` 함수에서 `self.TaxiTransform`으로 접근하는 [followup] | self.TaxiTransform.Position과 self.AzallinTransform.Position을 사용하여 x 좌표 비교 및 위치 수정 로직을 포함하는 OnUpdate() 전체 코드 블록을 작성해 주세요. [followup_answer] | 참고 문서에 제시된 `OnUpdate()` 함수의 전체 코드 블록은 다음과 같습니다. ```lua [server only] void OnUpdate() { local pos = self.TaxiTransform.Position local targetPos = self.AzallinTransform.Position if pos.x < targetPos.x then pos.x = pos.x + 0.02 self.TaxiTransform.Position = pos end } ` [scores] | [judge_reason] | [source_doc] | 만든 택시는 멈추지 않고 계속 이동하고 있습니다. 택시는 아잘린이 서 있는 곳에서 멈춰야 하므로, 아잘린의 위치 정보를 이용해야 합니다. 택시가 이동하다 아잘린과의 거리가 가까워지면, 멈추도록 조건을 추가해봅시다. 1. **Taxi**컴포넌트에 새로운 **AzallinTransform** 프로퍼티를 추가하고, 타입을 **Component**로 변경합니다. ```lua Property: [Sync] Component AzallinTransform = nil ``` 2. `OnBeginP
[task] | code [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | DefaultPlayer에 PlayerController 컴포넌트를 추가하여 OnBeginPlay()에서 self.Transform과 self.Movement를 각각 Entity.TransformComponent와 Entity.MovementComponent로 초기화하는 스크립트를 작성해줘 [answer] | 요청하신 `PlayerController` 컴포넌트 스크립트입니다. `OnBeginPlay()`에서 `TransformComponent`와 `MovementComponent`를 프로퍼티에 연결하는 내용만 포함하고 있습니다. ```lua Property: [Sync] Component Transform = nil [Sync] Component Movement = nil Method: void OnBeginPlay() { self.Transform = self.Entity.TransformComponent self.M [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 운동할수록 캐릭터가 커지고, 그 힘을 돈으로 바꿀 수 있는 월드, 'Maple GYM'을 만들어봅시다. # 이동 방식 변경 RigidBodyComponent의 **KinematicMove**를 활용해 캐릭터의 이동 방식을 변경해봅시다. **DefaultPlayer - RigidBodyComponent**에서 **KinematicMove**를 선택합니다. #### 이동 영역 제한 캐릭터의 이동 방식을 **KinematicMove**로 변경하면 캐릭터가 자유롭게 상하좌우로 이동하게 됩니다. 캐릭터가 지면 영
[task] | code [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | PlayerController 컴포넌트에 Stats 프로퍼티를 추가하고 OnBeginPlay()에서 Entity.PlayerStats를 할당하여 초기화하는 스크립트를 작성해줘 [answer] | PlayerController 컴포넌트에 `Stats` 프로퍼티를 추가하고 `OnBeginPlay()`에서 초기화하는 스크립트는 다음과 같습니다. ```lua Property: [Sync] Component Stats = nil Method: void OnBeginPlay() { self.Stats = self.Entity.PlayerStats } ``` [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] | code [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | PlayerController 컴포넌트에 [Sync] 타입의 Component 타입 Transform과 Movement 프로퍼티를 선언하여 서버와 클라이언트 간 동기화를 활성화하는 스크립트를 작성해줘 [answer] | 요청하신 `PlayerController` 컴포넌트의 스크립트는 `Transform`과 `Movement` 프로퍼티를 `[Sync]`로 선언하고, `OnBeginPlay()`에서 해당 컴포넌트 참조를 초기화하는 방식으로 작성됩니다. ```lua Property: [Sync] Component Transform = nil [Sync] Component Movement = nil Method: void OnBeginPlay() { self.Transform = self.Entity.TransformComponent s [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 운동할수록 캐릭터가 커지고, 그 힘을 돈으로 바꿀 수 있는 월드, 'Maple GYM'을 만들어봅시다. # 이동 방식 변경 RigidBodyComponent의 **KinematicMove**를 활용해 캐릭터의 이동 방식을 변경해봅시다. **DefaultPlayer - RigidBodyComponent**에서 **KinematicMove**를 선택합니다. #### 이동 영역 제한 캐릭터의 이동 방식을 **KinematicMove**로 변경하면 캐릭터가 자유롭게 상하좌우로 이동하게 됩니다. 캐릭터가 지면 영
[task] | code [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | DefaultPlayer에 PlayerStats 컴포넌트를 추가하고, CurrentPower가 MaxPower를 초과하지 않도록 하되 WeightBonus만큼 증가하며, 모든 값이 [Sync] 프로퍼티로 설정되어 있는 스크립트를 작성해줘 [answer] | 요청하신 Maple GYM의 `PlayerStats` 컴포넌트 스크립트입니다. `DefaultPlayer`에 이 컴포넌트를 추가하여 사용할 수 있으며, `CurrentPower`가 `MaxPower`를 초과하지 않도록 제한하는 `AddPower` 메서드를 포함합니다. 모든 스탯 정보는 `[Sync]` 프로퍼티로 설정되어 클라이언트와 서버 간에 동기화됩니다. ```lua Property: [Sync] number CurrentPower = 0 --현재 캐릭터의 힘 [Sync] number MaxPower = 15 --최대 누적 가 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | Maple Gym에는 힘과 최대 누적 가능한 힘, 돈, 등급 등 다양한 스탯 정보가 필요합니다. 다양한 정보를 저장하고 관리할 수 있는 컴포넌트를 만들어 봅시다. 1. 새로운 **PlayerStats** 컴포넌트를 생성합니다. 2. **PlayerStats**컴포넌트를 **DefaultPlayer**에 추가합니다. 3. PlayerStats에 스탯 정보로 사용할 프로퍼티를 추가합니다. ```lua Property: [Sync] number CurrentPower = 0 --현재 캐릭터의 힘
[task] | code [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | PlayerController 컴포넌트에 server only 실행 공간의 WorkOut() 메소드를 추가하여 Stats.CurrentPow와 Stats.WeightBonus를 더한 값이 Stats.MaxPow를 초과하지 않도록 제한 후 Stats.SetPow()에 전달하는 스크립트를 작성해줘 [answer] | ```lua Method: [server only] void WorkOut() { local calePow = self.Stats.CurrentPow + self.Stats.WeightBonus if calePow > self.Stats.MaxPow then calePow = self.Stats.MaxPow end self.Stats:SetPow(calePow) } ``` [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] | instruction_following [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | PlayerStats와 UIManager 간 통신 구조를 3단으로 나누어 표로 정리하세요. [answer] | 참고 문서에 제시된 `PlayerStats`와 `UIManager` 간의 통신 구조는 다음과 같은 3단계로 구성됩니다. | 단계 | 구성 요소 | 역할 및 내용 | | :--- | :--- | :--- | | **1. 참조 초기화** | `UIManager.OnBeginPlay()` (client only) | `UIManager`가 실행될 때 `_EntityService`와 `_UserService`를 통해 UI 텍스트 컴포넌트(`UiPowerText`, `UiMoneyText`)와 플레이어의 `PlayerStats` 컴포넌트( [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] | 엔티티 구간 이동시키기 [question] | TweenLineComponent의 StopType을 RepeatRoundTrip로 설정하고 Duration을 1초, ReturnDuration을 1.5초, ReturnTweenType을 Linear로 지정하여 X 50, Y 50 지점까지 왕복 운동을 반복하는 스크립트를 작성해줘 [answer] | 요청하신 설정을 `TweenLineComponent`에 적용하는 스크립트입니다. 참고: * `StopType`, `Duration`, `ReturnDuration`, `ReturnTweenType`, `DestinationCoordinateType`, `Positions`는 문서에 명시된 `TweenLineComponent`의 프로퍼티입니다. * `Positions`는 테이블 형식으로 목적지 좌표를 입력합니다. `Size`는 목적지 개수를 의미하며, `[1]`부터 시작하는 인덱스에 좌표를 넣습니다. * `Destinat [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 원점을 기준으로 목적지까지 선형 운동을 하게 만들 때 사용합니다. 목적지까지 편도, 왕복 운동 여부와 더불어 가·감속, 도달 시 튕김 등 운동 방식을 설정할 수 있습니다. **TweenLineComponent**의 프로퍼티를 살펴봅시다. | 프로퍼티 명 | 설명 | | ------ | --- | | TweenType | 기본값은 Linear입니다. 다른 모양의 운동 방식을 선택할 수 있습니다. 선형운동 종류별 설명은 하단의 참고자료를 참고하세요. | | Duration | 목적지까지 도달하는 데 걸리는 시간을 의미합니다. | |
[task] | code [pass] | ⏳ 미판정 [title] | 물체의 이동 Ⅰ [question] | Taxi 컴포넌트에 [Sync] 타입의 Component AzallinTransform 프로퍼티를 추가하고, OnBeginPlay()에서 _EntityService:GetEntityByPath("/maps/map01/Azallin")으로 엔티티를 조회하여 TransformComponent를 할당한 뒤, OnUpdate()에서 self.TaxiTransform.Position.x가 self.AzallinTransform.Position.x보다 작을 경우에만 x 좌표를 0.02씩 증가시켜 이동하도록 하는 스크립트를 작성해줘 [answer] | 요청하신 Taxi 컴포넌트 스크립트는 다음과 같습니다. `AzallinTransform` 프로퍼티를 정의하고, 게임 시작 시 아잘린의 Transform 컴포넌트를 조회하여 할당하며, 업데이트 시 x 좌표가 아잘린보다 작을 때만 이동하도록 로직을 구현했습니다. ```lua Property: [Sync] Component AzallinTransform = nil Method: [server only] void OnBeginPlay() { local azallin = _EntityService:GetEntityByPath("/ [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 만든 택시는 멈추지 않고 계속 이동하고 있습니다. 택시는 아잘린이 서 있는 곳에서 멈춰야 하므로, 아잘린의 위치 정보를 이용해야 합니다. 택시가 이동하다 아잘린과의 거리가 가까워지면, 멈추도록 조건을 추가해봅시다. 1. **Taxi**컴포넌트에 새로운 **AzallinTransform** 프로퍼티를 추가하고, 타입을 **Component**로 변경합니다. ```lua Property: [Sync] Component AzallinTransform = nil ``` 2. `OnBeginP
[task] | code [pass] | ⏳ 미판정 [title] | 물체의 이동 Ⅰ [question] | _entityService:GetEntityByPath("/maps/map01/Azallin")을 통해 아잘린 엔티티를 가져와 그 TransformComponent를 Taxi 컴포넌트의 AzallinTransform 프로퍼티에 저장하고, OnUpdate()에서 두 위치의 x 값 차이를 기반으로 이동 여부를 결정하는 스크립트를 작성해줘 [answer] | 사용자가 요청한 Taxi 컴포넌트 스크립트는 `AzallinTransform` 프로퍼티를 통해 아잘린의 위치 정보를 참조하고, `OnUpdate`에서 현재 위치와 목표 위치의 x 좌표 차이를 비교하여 이동하는 로직을 포함해야 합니다. ```lua Property: [Sync] Component AzallinTransform = nil [Sync] Component TaxiTransform = nil Method: [server only] void OnBeginPlay() { local azallin = _EntitySer [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 만든 택시는 멈추지 않고 계속 이동하고 있습니다. 택시는 아잘린이 서 있는 곳에서 멈춰야 하므로, 아잘린의 위치 정보를 이용해야 합니다. 택시가 이동하다 아잘린과의 거리가 가까워지면, 멈추도록 조건을 추가해봅시다. 1. **Taxi**컴포넌트에 새로운 **AzallinTransform** 프로퍼티를 추가하고, 타입을 **Component**로 변경합니다. ```lua Property: [Sync] Component AzallinTransform = nil ``` 2. `OnBeginP
[task] | code [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | DefaultPlayer에 PlayerController 컴포넌트를 추가하여 OnBeginPlay()에서 TransformComponent와 MovementComponent를 참조하고, client only 실행 공간의 MoveArea() 메서드에서 y좌표가 -1.23 초과 시 -1.23로, -2.6 미만 시 -2.6로 강제 보정하는 로직을 OnUpdate()에서 호출하도록 작성해줘 [answer] | 요청하신 Maple GYM의 이동 영역 제한 로직을 구현한 `PlayerController` 컴포넌트 스크립트입니다. ```lua Property: [Sync] Component Transform = nil [Sync] Component Movement = nil Method: void OnBeginPlay() { self.Transform = self.Entity.TransformComponent self.Movement = self.Entity.MovementComponent } [client only] vo [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 운동할수록 캐릭터가 커지고, 그 힘을 돈으로 바꿀 수 있는 월드, 'Maple GYM'을 만들어봅시다. # 이동 방식 변경 RigidBodyComponent의 **KinematicMove**를 활용해 캐릭터의 이동 방식을 변경해봅시다. **DefaultPlayer - RigidBodyComponent**에서 **KinematicMove**를 선택합니다. #### 이동 영역 제한 캐릭터의 이동 방식을 **KinematicMove**로 변경하면 캐릭터가 자유롭게 상하좌우로 이동하게 됩니다. 캐릭터가 지면 영
[task] | code [pass] | ⏳ 미판정 [title] | 물체의 이동 Ⅰ [question] | SpawnService를 사용하여 "/maps/map01/obj" 경로 아래에 택시 모델을 생성한 후, 생성된 엔티티의 RigidbodyComponent를 제거하고 OnUpdate에서 Position을 수정하여 이동하게 하는 스크립트를 작성해줘 [answer] | 요청하신 스크립트를 작성하기 전에, 참고 문서에 기반하여 몇 가지 중요한 사실 관계를 정리해야 합니다. 1. **`RigidbodyComponent` 제거 방법**: 참고 문서에서 StaticNPC 모델을 수정할 때 `RigidbodyComponent`를 제거하라고 안내하고 있습니다. 하지만 이는 **WorkSpace의 NativeModel 편집 모드**에서 수행하는 작업이며, **mLua 스크립트 안에서 런타임 시에 컴포넌트를 제거하는 API(예: `RemoveComponent` 등)는 문서에 명시되어 있지 않습니다.** 따라 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 용감한 시그너스 기사단 소속 아잘린이 먼저 고통의 미궁으로 출발한 나이트워커 부대에 합류할 수 있도록 택시를 불러봅시다. 부른 택시가 아잘린을 지나치지 않고 아잘린 앞에서 멈춰서 아잘린이 탑승할 수 있도록 만들어야 합니다. ![[object Object]](https://mod-file.dn.nexoncdn.co.kr/bbs/1747902531299ee5bec9350ac458d9f255a76eba57191.gif "Example") # StaticNPC 모델 수정하기 StaticNPC 모델에서 Rigid
[task] | code [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | PlayerController 컴포넌트에 self 이벤트 핸들러인 HandlePlayerActionEvent(PlayerActionEvent event)를 추가하여 event.ActionName이 "Attack"일 때 self:WorkOut()을 호출하는 스크립트를 작성해줘 [answer] | PlayerController 컴포넌트에 `HandlePlayerActionEvent` 이벤트 핸들러를 추가하고, 액션 이름이 "Attack"일 때 `WorkOut()` 메서드를 호출하도록 작성한 스크립트는 다음과 같습니다. ```lua Event Handler: [self] HandlePlayerActionEvent(PlayerActionEvent event) { local ActionName = event.ActionName local PlayerEntity = event.PlayerEntity [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] | code [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | PlayerStats 컴포넌트에 Multicast 실행 공간의 SetPow(number currentPow) 메소드를 추가하여 currentPow를 CurrentPow 프로퍼티에 할당하고 log로 출력하는 스크립트를 작성해줘 [answer] | `PlayerStats` 컴포넌트에 `SetPow()` 메소드를 추가하는 스크립트는 다음과 같습니다. 실행 공간을 `multicast`로 설정하여 클라이언트와 서버 양쪽에서 실행될 수 있게 하고, 전달받은 `currentPow` 값을 `CurrentPow` 프로퍼티에 할당하며 로그로 출력합니다. ```lua Method: [multicast] void SetPow(number currentPow) { self.CurrentPow = currentPow log(self.CurrentPow) } ``` [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] | code [pass] | ⏳ 미판정 [title] | Maple GYM 만들기 Ⅰ [question] | PlayerController 컴포넌트의 OnUpdate() 메서드 실행 공간을 사용하지 않음으로 설정하여 서버와 클라이언트 모두에서 프레임마다 MoveArea()를 호출함으로써 캐릭터의 위치 보정 시 튐 현상을 방지하는 스크립트를 작성해줘 [answer] | PlayerController 컴포넌트의 스크립트는 아래처럼 작성합니다. `OnUpdate()` 메서드에 실행 공간 어노테이션을 붙이지 않아서 서버와 클라이언트 모두에서 호출되도록 하고, 내부에서 `client only`로 선언된 `MoveArea()`를 호출하여 클라이언트 측에서만 위치를 보정합니다. ```lua Property: [Sync] Component Transform = nil [Sync] Component Movement = nil Method: void OnBeginPlay() { self.Transfor [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 운동할수록 캐릭터가 커지고, 그 힘을 돈으로 바꿀 수 있는 월드, 'Maple GYM'을 만들어봅시다. # 이동 방식 변경 RigidBodyComponent의 **KinematicMove**를 활용해 캐릭터의 이동 방식을 변경해봅시다. **DefaultPlayer - RigidBodyComponent**에서 **KinematicMove**를 선택합니다. #### 이동 영역 제한 캐릭터의 이동 방식을 **KinematicMove**로 변경하면 캐릭터가 자유롭게 상하좌우로 이동하게 됩니다. 캐릭터가 지면 영
[task] | code [pass] | ⏳ 미판정 [title] | 물체의 이동 Ⅱ [question] | 택시와 원숭이가 같은 맵에 배치된 상태에서, 택시가 이동하여 원숭이를 만나면 원숭이를 밀어내는 로직을 구현한 스크립트를 작성해줘. [answer] | 제시된 참고 문서에는 **택시와 원숭이가 '만나는 것(충돌/접촉)을 감지하는 API(예: OnCollisionEnter, OnTriggerEnter 등)가 존재하지 않습니다.** 문서에 명시된 이동 및 밀어내기 로직은 다음과 같습니다: 1. **택시 이동**: `TransformComponent:Translate(x, y)` 또는 `RigidbodyComponent:Translate(x, y)` 사용 (참고: 문서 본문에는 택시 이동에 `TransformComponent`의 `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