[task] | instruction_following [pass] | ⏳ 미판정 [title] | Effective MSW 1 [question] | Wait 계열 함수의 편리함과 남용 시 발생할 수 있는 문제점을 표로 정리해서 2개 항목으로 나열하세요. [answer] | Wait 계열 함수(`wait()`, `_DataStorage:SetAndWait()`, `_DataStorage:GetAndWait()` 등)의 특징과 남용 시 문제를 정리하면 다음과 같습니다. | 항목 | 내용 | | :--- | :--- | | **편리함** | 실행 순서를 순차적으로 파악하기 쉽고, 사용법이 간편합니다. | | **남용 시 문제점** | 월드의 규모가 커지거나 완성도가 높아질수록 흐름 제어와 최적화 문제를 일으켜 월드가 매우 느려질 수 있으며, 의도한 대로 기능이 제대로 실행되지 않을 수 있습니다. | [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 메이플스토리 월드는 쉬운 코딩을 위해 다양한 편의 기능을 지원하고 있습니다. 대표적으로 간편한 실행 제어 설정 기능이 있습니다. 그러나 간단한 설정이 얽히며 복잡해질 수 있고, 잘못 설정하면 원하는 기능이 제대로 실행되지 않을 수도 있습니다. 때로는 월드가 매우 느려질 수도 있습니다. 이런 문제는 월드의 규모가 작거나 월드 제작 초창기에는 발견하기 어렵습니다. 하지만 월드의 규모가 커지고 완성도가 높아질수록 문제가 될 수 있습니다. 그러므로 제작 초기부터 모든 동작이 원활하고 효율적으로 진행되도록 구조를 고민
[task] | code [pass] | ⏳ 미판정 [title] | MovementComponent를 활용한 엔티티의 이동 제어 [question] | MovementComponent의 SetPosition 함수를 통해 엔티티가 0,0 좌표에서 시작하여 매 1초마다 x좌표가 10씩 증가하는 궤적으로 이동하도록 OnUpdate에서 구현해줘. [answer] | MovementComponent의 `SetPosition` 함수는 매 프레임마다 호출되어 엔티티의 위치를 갱신합니다. "매 1초마다 x좌표가 10씩 증가"한다는 것은 초당 속도(velocity)가 10이라는 의미이므로, `OnUpdate`의 매개변수 `delta` (경과 시간)를 곱하여 매 프레임마다 이동량을 계산해야 합니다. 아래 코드는 엔티티가 0,0 좌표에서 시작하여 x축 방향으로 초당 10의 속도로 이동하도록 구현한 예시입니다. ```lua Property: [None] Vector2 StartPosition = Vect [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | MovementComponent에서는 SetPosition 함수를 통해 엔티티의 좌표를 설정합니다. `SetPosition()`함수는 기본적으로 TransformComponent의 Position을 설정하지만, RigidbodyComponent가 엔티티에 포함되어 있을 경우 RigidbodyComponent를 통해 Position을 설정합니다. 매개 변수로 Vector2 값을 받으며, 이 값에 해당하는 좌표로 엔티티가 이동합니다. ```lua [server only] void OnUpdate(number delta) { l
[task] | instruction_following [pass] | ⏳ 미판정 [title] | Effective MSW 1 [question] | 엔티티 삭제 시 nil 체크와 isvalid() 함수의 차이점을 실제 동작 단계와 함께 3문장 이내로 설명하세요. [answer] | 엔티티 삭제는 단순한 nil 할당이 아니라 '삭제 요청 → 삭제 처리 대기 → 삭제 중 → 삭제 완료 → nil'의 여러 단계를 거치기 때문에, 단순히 `nil`이 아닌지 확인하는 것만으로는 삭제 진행 중의 상태를 놓칠 수 있습니다. `isvalid()` 함수는 이러한 실제 동작의 일련의 상태가 모두 유효한지 검사하여 알 수 없는 동작의 유효성을 보장하는 반면, nil 체크는 최종적으로 값이 비어있는지만 확인합니다. 따라서 엔티티나 컴포넌트가 삭제 처리 중인 중간 단계에 안전하게 접근하려면 `nil` 체크 대신 `isvalid()` [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 메이플스토리 월드는 쉬운 코딩을 위해 다양한 편의 기능을 지원하고 있습니다. 대표적으로 간편한 실행 제어 설정 기능이 있습니다. 그러나 간단한 설정이 얽히며 복잡해질 수 있고, 잘못 설정하면 원하는 기능이 제대로 실행되지 않을 수도 있습니다. 때로는 월드가 매우 느려질 수도 있습니다. 이런 문제는 월드의 규모가 작거나 월드 제작 초창기에는 발견하기 어렵습니다. 하지만 월드의 규모가 커지고 완성도가 높아질수록 문제가 될 수 있습니다. 그러므로 제작 초기부터 모든 동작이 원활하고 효율적으로 진행되도록 구조를 고민
[task] | two_turn [pass] | ⏳ 미판정 [title] | MovementComponent를 활용한 엔티티의 이동 제어 [question] | IsClimbPaused 프로퍼티는 어떤 상황에서 true가 반환되며, 이를 활용하여 사다리에서 멈추었을 때 특정 스크립트를 실행하는 코드는 어떻게 작성하나요? [answer] | `IsClimbPaused` 프로퍼티는 플레이어 엔티티가 사다리 또는 로프 위에서 이동 중 멈춰 있는 상태일 때 `true`를 반환합니다. 이 프로퍼티는 boolean 타입이며, 읽기 전용(ReadOnly)으로 플레이어 엔티티에만 유효합니다. 사다리에서 멈추었을 때 특정 스크립트를 실행하려면 `OnUpdate` 메서드에서 `IsClimbPaused`의 값을 매 프레임마다 확인하여 상태가 `true`로 전환되는 시점에 원하는 로직을 실행하도록 작성할 수 있습니다. 단순히 `true`인 동안 계속 실행되면 반복 실행이 되므로, 이전 [followup] | IsClimbPaused가 true일 때만 실행되는 로직을 OnUpdate에서 처리하려면 어떤 조건문을 써야 하나요? [followup_answer] | `IsClimbPaused`가 `true`일 때만 로직을 실행하려면 `OnUpdate` 메서드 내에서 `if` 조건문을 사용하여 해당 프로퍼티의 값을 `true`와 비교하면 됩니다. 참고 문서의 예제와 동일한 방식으로, `self.Entity.MovementComponent.IsClimbPaused`를 읽어 `true`인지 확인하는 조건문을 작성합니다. ```lua [server only] void OnUpdate(number delta) { if self.Entity.MovementComponent.IsClimbPaus [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 이번 과정에서는 점프, 플레이어 이동 및 엔티티 좌표 설정 등 MovementComponent가 제공하는 주요 기능들과 MovementComponent의 기본 작동 방식에 대해 알아봅니다. # MovementComponent 소개 **MovementComponent**는 캐릭터의 이동속도와 점프력 설정은 물론 RigidbodyComponent가 포함된 엔티티를 강제로 점프시키거나 이동 또는 정지시킬 수 있는 여러 기능을 제공합니다. 스크립트 컴포넌트를 통해 TransformComponent를 제어하여 동적으
[task] | instruction_following [pass] | ⏳ 미판정 [title] | 플레이어 설정과 제어 [question] | RemoveActionKey와 SetActionKey를 활용하여 기존 조작키를 삭제하고 새로운 키를 연결하는 2단계 구성 스크립트를 단계별 번호 목록으로 제시하세요. [answer] | `RemoveActionKey`와 `SetActionKey`를 활용해 기존 조작키를 삭제하고 새로운 키를 연결하는 2단계 구성은 다음과 같습니다. 1. **MyDesk**에 PlayerSetting 컴포넌트를 생성하고, DefaultPlayer에 추가합니다. 2. `RemoveActionKey`를 이용해 삭제할 기존 키에 연결된 액션을 제거하고, `SetActionKey`를 이용해 새로운 키에 원하는 액션을 연결하는 스크립트를 작성합니다. ```lua Method: [client only] void OnBeginPlay() { [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 플레이어의 기본 속성에 발동할 수 있게 하는 조건을 추가할 수 있습니다. `AddCondition()` 함수를 사용해 플레이어의 행동을 제약하기 위한 조건을 추가할 수 있습니다. 기본적으로 사용 가능한 공격, 점프 등을 일시적으로 특정 조건을 만족할 때 기능 발동을 제한하거나, 추가 발동 조건을 추가해 색다른 재미를 선사할 수 있습니다. 1. **MyDesk**에 PlayerSetting 컴포넌트를 생성하고, DefaultPlayer에 추가합니다. 2. Jump 액션이 실행되는 조건을 작성합니다. 10 이상은 Jump가 실
[task] | single_turn [pass] | ⏳ 미판정 [title] | 플레이어 설정과 제어 [question] | TeleportService:TeleportToEntityPath()와 PlayerComponent:MoveToMapPosition()의 주요 차이점은 무엇인가요? [answer] | `TeleportService:TeleportToEntityPath()`와 `PlayerComponent:MoveToMapPosition()`의 주요 차이점은 대상 엔티티의 범위입니다. * **`TeleportService:TeleportToEntityPath()`**: 모든 Entity를 대상으로 이동을 시킬 수 있습니다. * **`PlayerComponent:MoveToMapPosition()`**: 플레이어(Player)에만 활용 가능합니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `MoveToMapPosition()`를 이용해 플레이어를 특정 위치로 이동시킬 수 있습니다. 이 기능을 활용해 여러 맵으로 모든 유저를 한 번에 옮겨 새로운 맵에서 새로운 게임을 할 수 있게 합니다. 1. **MyDesk**에 새로운 PlayerManagement 컴포넌트를 생성하고, DefaultPlayer에 추가합니다. 2. `TimerService`를 이용해 10초를 셀 수 있게 만들고, 10초 뒤 이동할 map의 이름과 그 맵의 위치를 입력합니다. 맵의 이름은 Hierarchy의 이름과 동일해야 합니다. >**
[task] | single_turn [pass] | ⏳ 미판정 [title] | 아바타 표정 바꾸기 [question] | 표정은 얼굴 설정에 따라 다르게 나타난다고 하는데, 내가 만든 맵에서 특정 표정이 전혀 반응하지 않을 때 얼굴 설정이 원인인 것인지 코드의 문제인 것인지 어떻게 구분해야 하나요? [answer] | 문서에 따르면, 총 22가지의 표정은 플레이어의 얼굴 설정에 따라 실제로 렌더링되는 모습(표정 애니메이션의 형태)이 달라집니다. 하지만 이 사실은 "표정 재생 로직이 실행되는지 여부"와 "표정이 화면에 어떻게 보이는지"를 구분해야 함을 의미합니다. 특정 표정이 **전혀 반응하지 않는(애니메이션이 재생되지 않는)** 경우와 **반응은 하지만 원하는 대로 보이지 않는** 경우를 구분하여 다음과 같이 점검할 수 있습니다. ### 1. 코드의 문제인지 확인하는 방법 (로직 점검) 코드가 올바르게 실행되고 있는지 확인하기 위해 `log [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 AvatarRendererComponent의 `PlayEmotion`을 사용해 플레이어 아바타의 표정을 바꿀 수 있습니다. 특정 입력 키와 표정을 연결 지어 생동감 있게 감정을 표현할 수도 있고, 몬스터에게 맞았을 때 특정 표정을 재생시킬 수도 있습니다. 적극적으로 사용해 유저들끼리의 활발하고 쉬운 의사소통을 할 수 있게 도와주세요. # 표정 종류 총 22가지의 표정을 제공합니다. 표정은 얼굴마다 다르게 나타나므로 크리에이터가 설정한 얼굴에 따라 가이드의 표정과 다를 수 있습니다 | 표정 | key | 예
[task] | two_turn [pass] | ⏳ 미판정 [title] | 플레이어 설정과 제어 [question] | PlayerComponent의 주요 프로퍼티와 PlayerControllerComponent를 활용하여 플레이어의 상태와 이동을 제어하는 기본 개념은 무엇인가요? [answer] | PlayerComponent와 PlayerControllerComponent는 메이플스토리 월드에서 플레이어의 고유 상태와 행동을 제어하는 데 사용되는 두 가지 핵심 컴포넌트입니다. ### 1. PlayerComponent 플레이어 엔티티에만 존재하며, 플레이어를 식별하고 기본 속성을 제어하는 역할을 합니다. Player 모델에 이 컴포넌트가 없으면 해당 엔티티는 플레이어로 인식되지 않습니다. 주요 프로퍼티는 다음과 같습니다. * **MaxHp**: 플레이어의 최대 체력을 설정합니다. 기본값은 1000이며, 변경 시 UI 상 [followup] | RespawnDuration 기본값 5초 외에, RespawnPosition을 지정하지 않았을 때의 위치 결정 순서와 PVPMode 활성화 시의 구체적 동작을 확인하고 싶어요. [followup_answer] | `RespawnPosition`을 지정하지 않았을 때의 위치 결정 순서와 `PVPMode` 활성화 시의 동작은 다음과 같습니다. **1. RespawnPosition 미지정 시 위치 결정 순서** `RespawnPosition` 프로퍼티에 위치를 명시적으로 설정하지 않은 경우, 시스템은 다음 순서대로 리스폰 위치를 결정합니다. 1. **SpawnLocation**의 위치 2. **맵 진입 시점의 위치** 즉, SpawnLocation에 설정된 좌표가 우선하며, 해당 값도 없다면 플레이어가 처음 맵에 들어왔을 때의 좌표를 기준 [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 Player 모델에는 캐릭터의 초기 속성을 만들 때도 유용하게 사용하지만, 캐릭터를 이동시키거나, 상태를 제어할 때 유용하게 사용할 수 있습니다. PlayerComponent와 PlayerControllerComponent의 개념을 알아보고, 액션과 상태 애니메이션의 관계를 파악해 크리에이터의 의도에 따라 플레이어가 동작할 수 있게 만들어봅시다. # PlayerComponent 개념 **PlayerComponent**는 다른 엔티티와 다르게 플레이어만이 가지고 있는 특성을 모아 놓은 컴포넌트입니다. 대표적으
[task] | code [pass] | ⏳ 미판정 [title] | 플레이어 설정과 제어 [question] | 플레이어가 사망(DeadEvent)할 때 현재 위치를 리스폰 위치로 설정하는 PlayerSetting 컴포넌트 스크립트를 작성해줘. [answer] | 플레이어가 사망할 때 `DeadEvent`가 발생하면, 해당 플레이어의 현재 `TransformComponent.Position`을 `PlayerComponent.RespawnPosition`에 대입하여 다음 리스폰 위치로 설정합니다. 다음은 요청하신 PlayerSetting 컴포넌트 스크립트입니다. ```lua Method: [client only] void OnBeginPlay() { self.Entity:ConnectEvent(DeadEvent, function() self.Entity.PlayerCo [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `MoveToMapPosition()`를 이용해 플레이어를 특정 위치로 이동시킬 수 있습니다. 이 기능을 활용해 여러 맵으로 모든 유저를 한 번에 옮겨 새로운 맵에서 새로운 게임을 할 수 있게 합니다. 1. **MyDesk**에 새로운 PlayerManagement 컴포넌트를 생성하고, DefaultPlayer에 추가합니다. 2. `TimerService`를 이용해 10초를 셀 수 있게 만들고, 10초 뒤 이동할 map의 이름과 그 맵의 위치를 입력합니다. 맵의 이름은 Hierarchy의 이름과 동일해야 합니다. >**
[task] | single_turn [pass] | ⏳ 미판정 [title] | 플레이어 설정과 제어 [question] | 기존 조작키를 삭제하고 새로운 키를 만들 때 RemoveActionKey와 SetActionKey를 동시에 호출해야 하는 이유가 있나요? [answer] | 아니요, `RemoveActionKey`와 `SetActionKey`를 반드시 동시에 호출해야 하는 기술적 이유는 없습니다. 두 함수는 각각 독립적인 역할을 수행합니다. `RemoveActionKey`는 특정 키에 연결된 기존 액션을 해제하는 기능이고, `SetActionKey`는 새로운 키에 특정 액션을 연결하는 기능입니다. 참고 문서의 예제에서는 왼쪽 Ctrl 키에 연결된 액션을 삭제하고 F 키에 Attack을 연결하는 시나리오를 보여주기 위해 두 함수를 함께 사용했을 뿐입니다. 만약 기존 키를 삭제하지 않고 단순히 새로운 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 플레이어의 기본 속성에 발동할 수 있게 하는 조건을 추가할 수 있습니다. `AddCondition()` 함수를 사용해 플레이어의 행동을 제약하기 위한 조건을 추가할 수 있습니다. 기본적으로 사용 가능한 공격, 점프 등을 일시적으로 특정 조건을 만족할 때 기능 발동을 제한하거나, 추가 발동 조건을 추가해 색다른 재미를 선사할 수 있습니다. 1. **MyDesk**에 PlayerSetting 컴포넌트를 생성하고, DefaultPlayer에 추가합니다. 2. Jump 액션이 실행되는 조건을 작성합니다. 10 이상은 Jump가 실
[task] | instruction_following [pass] | ⏳ 미판정 [title] | Effective MSW 1 [question] | wait()와 TimerService의 차이점을 3문장 이내로 요약하세요. [answer] | `wait()`는 해당 코드의 실행을 일시 정지시켜 이후 작업이 순차적으로만 진행되게 하는 동기적 대기 함수입니다. 반면 `TimerService`는 특정 시간 이후에 함수를 실행하도록 예약할 뿐, 현재 코드의 흐름을 멈추지 않습니다. 따라서 `wait()`는 병렬 처리를 방해하지만, `TimerService`는 여러 작업을 동시에 진행하는 데 사용할 수 있습니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `wait()`는 보통 아래 예시 코드처럼 간단하게 사용합니다. ```lua _UIToast:ShowMessage("Show Message") wait(1) _UIToast:ShowMessage("Show Delay Message") ``` 하지만 `wait()`를 사용할 때는 주의해야 합니다. `wait()`는 말 그대로 행동을 '기다리고' 있기 때문에 여기저기에 마구 사용한다면 전체적인 흐름을 파악하기 어려워집니다. 또한, '대기'를 하므로 이후 작업이 진행되지 않는 문제도 있습니다. 아래 예시를 통해 '대기' 때문에
[task] | single_turn [pass] | ⏳ 미판정 [title] | 플레이어 설정과 제어 [question] | 모든 유저를 10초 후 다른 맵으로 일괄 이동시키려면 TimerService와 함께 어떤 메서드를 호출해야 하나요? [answer] | `_TimerService:SetTimerOnce()`로 10초 타이머를 설정하고, 타이머가 만료되면 `_UserService.UserEntities`를 순회하며 각 플레이어 엔티티의 `PlayerComponent:MoveToMapPosition()` 메서드를 호출해야 합니다. ```lua Method: [server only] void OnBeginPlay() { _TimerService:SetTimerOnce(function() for userId, userEntity in pairs(_UserServic [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `MoveToMapPosition()`를 이용해 플레이어를 특정 위치로 이동시킬 수 있습니다. 이 기능을 활용해 여러 맵으로 모든 유저를 한 번에 옮겨 새로운 맵에서 새로운 게임을 할 수 있게 합니다. 1. **MyDesk**에 새로운 PlayerManagement 컴포넌트를 생성하고, DefaultPlayer에 추가합니다. 2. `TimerService`를 이용해 10초를 셀 수 있게 만들고, 10초 뒤 이동할 map의 이름과 그 맵의 위치를 입력합니다. 맵의 이름은 Hierarchy의 이름과 동일해야 합니다. >**
[task] | instruction_following [pass] | ⏳ 미판정 [title] | Effective MSW 1 [question] | isvalid() 함수를 활용한 안전한 엔티티 접근 코드를 코드만 출력하고 설명은 주석으로 작성하세요. [answer] | ```lua Property: [None] string TargetEntityId = "a22396e1-6365-42d4-9cef-5924c223f7fa" Method: [server only] void CheckEntitySafely() { -- 엔티티를 ID로 가져옴 local targetEntity = _EntityService:GetEntity(self.TargetEntityId) -- nil 체크 대신 isvalid()를 사용하여 엔티티가 유효한 상태인지 확인 -- 엔티티 삭제는 즉시 nil [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 메이플스토리 월드는 쉬운 코딩을 위해 다양한 편의 기능을 지원하고 있습니다. 대표적으로 간편한 실행 제어 설정 기능이 있습니다. 그러나 간단한 설정이 얽히며 복잡해질 수 있고, 잘못 설정하면 원하는 기능이 제대로 실행되지 않을 수도 있습니다. 때로는 월드가 매우 느려질 수도 있습니다. 이런 문제는 월드의 규모가 작거나 월드 제작 초창기에는 발견하기 어렵습니다. 하지만 월드의 규모가 커지고 완성도가 높아질수록 문제가 될 수 있습니다. 그러므로 제작 초기부터 모든 동작이 원활하고 효율적으로 진행되도록 구조를 고민
[task] | single_turn [pass] | ⏳ 미판정 [title] | 플레이어 설정과 제어 [question] | Player의 리스폰 지점을 플레이 중 죽은 위치로 설정하려면 어떤 컴포넌트를 사용하고 어떤 이벤트를 연결해야 하나요? [answer] | Player의 리스폰 지점을 플레이 중 죽은 위치로 설정하려면 **PlayerSetting** 컴포넌트를 사용해야 합니다. 이 컴포넌트는 `DefaultPlayer`에 추가하여 적용합니다. 이동할 이벤트는 **DeadEvent**입니다. `ConnectEvent`를 이용해 `DeadEvent`를 연결하고, 이벤트가 발생했을 때 `PlayerComponent`의 `RespawnPosition`을 현재 `TransformComponent`의 `Position` 값으로 설정하면 됩니다. 아래는 해당 기능을 구현한 mLua 스크립트 예 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `MoveToMapPosition()`를 이용해 플레이어를 특정 위치로 이동시킬 수 있습니다. 이 기능을 활용해 여러 맵으로 모든 유저를 한 번에 옮겨 새로운 맵에서 새로운 게임을 할 수 있게 합니다. 1. **MyDesk**에 새로운 PlayerManagement 컴포넌트를 생성하고, DefaultPlayer에 추가합니다. 2. `TimerService`를 이용해 10초를 셀 수 있게 만들고, 10초 뒤 이동할 map의 이름과 그 맵의 위치를 입력합니다. 맵의 이름은 Hierarchy의 이름과 동일해야 합니다. >**
[task] | code [pass] | ⏳ 미판정 [title] | 플레이어 설정과 제어 [question] | MagicStone 엔티티의 TriggerEnterEvent가 발생했을 때 PlayerComponent가 있는 엔티티만 '/maps/map01/portal-3' 경로로 이동시키는 PlayerManagement 컴포넌트 스크립트를 작성해줘. [answer] | MagicStone 엔티티의 `TriggerEnterEvent`가 발생했을 때, 해당 트리거에 닿은 엔티티(`event.TriggerBodyEntity`)에 `PlayerComponent`가 있는지 확인하여 플레이어가 맞다면 `MoveToEntityByPath` 메서드를 사용해 지정된 경로로 이동시킵니다. 요청하신 PlayerManagement 컴포넌트 스크립트는 다음과 같습니다. ```lua Method: [server only] void OnBeginPlay() { local MagicStone = _EntitySer [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `MoveToMapPosition()`를 이용해 플레이어를 특정 위치로 이동시킬 수 있습니다. 이 기능을 활용해 여러 맵으로 모든 유저를 한 번에 옮겨 새로운 맵에서 새로운 게임을 할 수 있게 합니다. 1. **MyDesk**에 새로운 PlayerManagement 컴포넌트를 생성하고, DefaultPlayer에 추가합니다. 2. `TimerService`를 이용해 10초를 셀 수 있게 만들고, 10초 뒤 이동할 map의 이름과 그 맵의 위치를 입력합니다. 맵의 이름은 Hierarchy의 이름과 동일해야 합니다. >**
[task] | single_turn [pass] | ⏳ 미판정 [title] | 플레이어 설정과 제어 [question] | 점프 액션에 조건을 추가했는데 로그가 뜨면서 동작이 차단되는 것을 확인하려면 어떤 로그를 추가해야 하나요? [answer] | 점프 액션에 조건을 추가하고, 조건이 만족되지 않아 점프가 차단되는 상황을 로그로 확인하려면 `AddCondition` 함수의 조건 함수 내부에서 조건이 `false`가 되는 분기에 `log()`를 호출하면 됩니다. 참고 문서의 예시처럼 `PlayerComponent.Hp`가 10 미만일 때 점프를 막는다면, 해당 조건문이 참일 때 로그를 출력하도록 작성합니다. ```lua Method: [client only] void OnBeginPlay() { local playerController = self.Entity.Pla [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 플레이어의 기본 속성에 발동할 수 있게 하는 조건을 추가할 수 있습니다. `AddCondition()` 함수를 사용해 플레이어의 행동을 제약하기 위한 조건을 추가할 수 있습니다. 기본적으로 사용 가능한 공격, 점프 등을 일시적으로 특정 조건을 만족할 때 기능 발동을 제한하거나, 추가 발동 조건을 추가해 색다른 재미를 선사할 수 있습니다. 1. **MyDesk**에 PlayerSetting 컴포넌트를 생성하고, DefaultPlayer에 추가합니다. 2. Jump 액션이 실행되는 조건을 작성합니다. 10 이상은 Jump가 실
[task] | single_turn [pass] | ⏳ 미판정 [title] | 플레이어 설정과 제어 [question] | PlayerSetting 컴포넌트를 MyDesk에서 생성한 후 DefaultPlayer에 추가하는 이유는 무엇인가요? [answer] | PlayerSetting 컴포넌트를 MyDesk에서 생성한 후 DefaultPlayer에 추가하는 이유는, 이 컴포넌트가 플레이어의 기본 조작과 동작 조건을 제어하기 위해 **플레이어 엔티티에 직접 연결**되어야 하기 때문입니다. 구체적인 이유는 다음과 같습니다: 1. **PlayerControllerComponent 접근 필요**: `AddCondition()` 또는 `SetActionKey()`와 같은 함수는 `self.Entity.PlayerControllerComponent`를 통해 호출됩니다. PlayerSetting [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 플레이어의 기본 속성에 발동할 수 있게 하는 조건을 추가할 수 있습니다. `AddCondition()` 함수를 사용해 플레이어의 행동을 제약하기 위한 조건을 추가할 수 있습니다. 기본적으로 사용 가능한 공격, 점프 등을 일시적으로 특정 조건을 만족할 때 기능 발동을 제한하거나, 추가 발동 조건을 추가해 색다른 재미를 선사할 수 있습니다. 1. **MyDesk**에 PlayerSetting 컴포넌트를 생성하고, DefaultPlayer에 추가합니다. 2. Jump 액션이 실행되는 조건을 작성합니다. 10 이상은 Jump가 실
[task] | single_turn [pass] | ⏳ 미판정 [title] | 플레이어 설정과 제어 [question] | 플레이어만 인식해서 특정 엔티티 경로로 이동시키고 싶을 때, 어떤 컴포넌트를 추가로 배치해야 하며 왜 필요한가요? [answer] | 플레이어만 인식해서 특정 엔티티 경로로 이동시키려면 **TriggerComponent**를 추가로 배치해야 합니다. 이 컴포넌트가 필요한 이유는 다음과 같습니다. * **플레이어 식별:** 특정 엔티티에 붙은 TriggerComponent가 `PlayerComponent`를 인식할 수 있게 만듭니다. * **타겟팅 제한:** 이 구조를 통해 해당 엔티티는 오직 플레이어만 알아차릴 수 있게 됩니다. 따라서 같은 공간에서 똑같이 움직이는 몬스터 같은 다른 엔티티는 이동 대상에서 제외되어, 플레이어만 원하는 경로로 이동시킬 수 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `MoveToMapPosition()`를 이용해 플레이어를 특정 위치로 이동시킬 수 있습니다. 이 기능을 활용해 여러 맵으로 모든 유저를 한 번에 옮겨 새로운 맵에서 새로운 게임을 할 수 있게 합니다. 1. **MyDesk**에 새로운 PlayerManagement 컴포넌트를 생성하고, DefaultPlayer에 추가합니다. 2. `TimerService`를 이용해 10초를 셀 수 있게 만들고, 10초 뒤 이동할 map의 이름과 그 맵의 위치를 입력합니다. 맵의 이름은 Hierarchy의 이름과 동일해야 합니다. >**
[task] | instruction_following [pass] | ⏳ 미판정 [title] | Effective MSW 1 [question] | 문서에 제시된 _DataStorageService:GetAndWait 예제 코드만 출력하고, 문제점 분석은 코드 주석으로만 작성하세요. [answer] | ```lua local str = _DataStorageService:GetAndWait("MyStat", "STR") local dex = _DataStorageService:GetAndWait("MyStat", "DEX") local int = _DataStorageService:GetAndWait("MyStat", "INT") local luck = _DataStorageService:GetAndWait("MyStat", "LUCK") local hp = _DataStorageService:GetAndWait("MyStat", [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `wait()`는 보통 아래 예시 코드처럼 간단하게 사용합니다. ```lua _UIToast:ShowMessage("Show Message") wait(1) _UIToast:ShowMessage("Show Delay Message") ``` 하지만 `wait()`를 사용할 때는 주의해야 합니다. `wait()`는 말 그대로 행동을 '기다리고' 있기 때문에 여기저기에 마구 사용한다면 전체적인 흐름을 파악하기 어려워집니다. 또한, '대기'를 하므로 이후 작업이 진행되지 않는 문제도 있습니다. 아래 예시를 통해 '대기' 때문에
[task] | code [pass] | ⏳ 미판정 [title] | 플레이어 설정과 제어 [question] | PlayerControllerComponent의 LookDirectionX 프로퍼티를 1로 설정하고, FixedLookAt을 true로 변경하여 캐릭터가 항상 오른쪽을 바라보게 하는 스크립트를 작성해줘 [answer] | PlayerControllerComponent의 `LookDirectionX` 프로퍼티를 1로 설정하면 캐릭터의 기본 시선이 오른쪽이 됩니다. `FixedLookAt`을 true로 설정하면 캐릭터가 방향을 바꾸더라도 이동 모습이 바뀌지 않고 한 방향만 바라보게 됩니다. 두 값은 스크립트 실행 시점에 컴포넌트 프로퍼티를 직접 수정하여 설정할 수 있습니다. 아래는 `OnBeginPlay()` 생명주기 메서드에서 해당 설정을 적용하는 mLua 스크립트입니다. ```lua Method: [client only] void OnBeginP [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | **PlayerControllerComponent**는 입력에 따라 액션을 수행하고, 특정 조건을 처리합니다.예를 들어, 공격 키를 눌렀을 때 특정 애니메이션을 재생하는 액션을 연결하면 공격 키가 입력되었을 때마다 작동합니다. 그러나 사다리에 매달려 있을 때는 사다리에 매달린 애니메이션이 재생되는 중이므로 공격 애니메이션은 재생되지 않게 해야 오르는 동작이 어색하지 않습니다. 그러므로 사다리에 플레이어가 매달려 있을 때, '공격 키를 눌러도 공격 액션이 재생되지 않는다'란 조건을 추가할 수 있습니다. 기본 Player 모델에는
[task] | single_turn [pass] | ⏳ 미판정 [title] | 플레이어 설정과 제어 [question] | MoveToMapPosition()에서 맵 이름을 입력할 때 주의해야 할 점은 무엇이며, 잘못된 경우 어떤 문제가 발생할 수 있나요? [answer] | `MoveToMapPosition()`에서 맵 이름을 입력할 때 가장 중요한 주의사항은 **입력할 맵 이름이 Hierarchy(계층 구조)에서 해당 맵에 지정된 이름과 정확히 동일해야 한다는 점**입니다. 이 규칙을 지키지 않을 경우, 스크립트에서 지정한 이름으로 맵을 찾을 수 없으므로 **플레이어가 원하는 위치로 이동하지 못하고 이동 처리가 실패**하는 문제가 발생할 수 있습니다. 아래는 `MoveToMapPosition()`를 사용하는 예시입니다. `'map02'`로 입력된 값은 Hierarchy에서 해당 맵의 이름과 완전히 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `MoveToMapPosition()`를 이용해 플레이어를 특정 위치로 이동시킬 수 있습니다. 이 기능을 활용해 여러 맵으로 모든 유저를 한 번에 옮겨 새로운 맵에서 새로운 게임을 할 수 있게 합니다. 1. **MyDesk**에 새로운 PlayerManagement 컴포넌트를 생성하고, DefaultPlayer에 추가합니다. 2. `TimerService`를 이용해 10초를 셀 수 있게 만들고, 10초 뒤 이동할 map의 이름과 그 맵의 위치를 입력합니다. 맵의 이름은 Hierarchy의 이름과 동일해야 합니다. >**
[task] | single_turn [pass] | ⏳ 미판정 [title] | 플레이어 설정과 제어 [question] | AddCondition 함수로 특정 조건일 때만 점프를 막으려면 코드를 어떻게 작성해야 하나요? [answer] | `AddCondition()` 함수는 `PlayerControllerComponent`에서 사용하며, 특정 액션(예: "Jump")이 실행되기 전 조건을 검사합니다. 조건 함수가 `true`를 반환하면 해당 액션이 허용되고, `false`를 반환하면 액션이 차단됩니다. 아래 예제는 HP가 10 미만인 경우에만 점프를 막는 스크립트입니다. `MyDesk`에 `PlayerSetting` 컴포넌트를 생성하고 `DefaultPlayer`에 추가한 후, 아래 코드를 입력하면 됩니다. ```lua Method: [client only] v [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 플레이어의 기본 속성에 발동할 수 있게 하는 조건을 추가할 수 있습니다. `AddCondition()` 함수를 사용해 플레이어의 행동을 제약하기 위한 조건을 추가할 수 있습니다. 기본적으로 사용 가능한 공격, 점프 등을 일시적으로 특정 조건을 만족할 때 기능 발동을 제한하거나, 추가 발동 조건을 추가해 색다른 재미를 선사할 수 있습니다. 1. **MyDesk**에 PlayerSetting 컴포넌트를 생성하고, DefaultPlayer에 추가합니다. 2. Jump 액션이 실행되는 조건을 작성합니다. 10 이상은 Jump가 실
[task] | instruction_following [pass] | ⏳ 미판정 [title] | Effective MSW 1 [question] | wait와 TimerService의 동작 차이를 직렬과 병렬 관점에서 3문장 이내로 설명하세요. [answer] | `wait`는 특정 동작 후 다음 코드가 실행되도록 대기하는 직렬 처리 방식입니다. 반면 `TimerService`는 별도의 일을 만들어 동시에 실행되도록 하는 병렬 처리 방식입니다. 따라서 두 도구의 동작 흐름 차이를 정확히 이해하고 상황에 맞게 사용해야 합니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `wait`는 대기한 뒤에 직접 어떤 행동을 수행하는 것이고, `TimerService`는 해당 행동을 수행하는 별도의 일을 만드는 것입니다. `wait`는 직렬, `TimerService`는 병렬 형태로 동작합니다. 따라서 `wait`의 사용 코드는 다음과 같이 표현할 수 있습니다 ```lua local targetEntity = _EntityService:GetEntity("a22396e1-6365-42d4-9cef-5924c223f7fa") targetEntity.TestComponent:ShowMessage() func
[task] | instruction_following [pass] | ⏳ 미판정 [title] | Effective MSW 1 [question] | wait() 사용 시 발생하는 세 가지 주요 문제점을 단계별 번호 목록으로 정리하세요. [answer] | `wait()` 사용 시 발생하는 세 가지 주요 문제점은 다음과 같습니다. 1. **대기 이후 동작의 유효성 보장 불가** `wait()` 실행 후 코드가 계속 진행되지만, 그 사이에 엔티티나 컴포넌트가 삭제되었을 수 있습니다. 따라서 대기 이후에 참조하는 객체가 더 이상 유효하지 않을 가능성이 있어 오류가 발생할 수 있습니다. 2. **대기 동작 누적 시 긴 지연 시간 발생** DB 조회나 리소스 로딩 등 시간이 걸리는 작업에 `wait()`를 여러 번 연속으로 사용하면 요청-대기-수신 과정이 순차적으로 반복되어 전 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `wait()`는 보통 아래 예시 코드처럼 간단하게 사용합니다. ```lua _UIToast:ShowMessage("Show Message") wait(1) _UIToast:ShowMessage("Show Delay Message") ``` 하지만 `wait()`를 사용할 때는 주의해야 합니다. `wait()`는 말 그대로 행동을 '기다리고' 있기 때문에 여기저기에 마구 사용한다면 전체적인 흐름을 파악하기 어려워집니다. 또한, '대기'를 하므로 이후 작업이 진행되지 않는 문제도 있습니다. 아래 예시를 통해 '대기' 때문에
[task] | code [pass] | ⏳ 미판정 [title] | 플레이어 설정과 제어 [question] | 10초 후 모든 플레이어를 'map02' 맵의 Vector2(2,2) 위치로 이동시키는 PlayerManagement 컴포넌트 스크립트를 작성해줘. [answer] | 요청하신 기능을 구현하기 위한 `PlayerManagement` 컴포넌트 스크립트입니다. 1. **MyDesk**에서 새로운 `PlayerManagement` 컴포넌트를 생성하고, `DefaultPlayer`에 추가합니다. 2. 아래 코드를 해당 컴포넌트에 붙여넣습니다. ```lua Method: [server only] void OnBeginPlay() { _TimerService:SetTimerOnce(function() for userId, userEntity in pairs(_UserService [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `MoveToMapPosition()`를 이용해 플레이어를 특정 위치로 이동시킬 수 있습니다. 이 기능을 활용해 여러 맵으로 모든 유저를 한 번에 옮겨 새로운 맵에서 새로운 게임을 할 수 있게 합니다. 1. **MyDesk**에 새로운 PlayerManagement 컴포넌트를 생성하고, DefaultPlayer에 추가합니다. 2. `TimerService`를 이용해 10초를 셀 수 있게 만들고, 10초 뒤 이동할 map의 이름과 그 맵의 위치를 입력합니다. 맵의 이름은 Hierarchy의 이름과 동일해야 합니다. >**
[task] | single_turn [pass] | ⏳ 미판정 [title] | Effective MSW 1 [question] | 메이플스토리 월드에서 엔티티의 실제 삭제 과정이 기대한 동작과 다른 여러 단계로 이루어져 있는 구체적인 이유는 무엇인가요? [answer] | 메이플스토리 월드에서 엔티티의 삭제가 단순히 '삭제 요청 → nil'이 되는 것이 아니라 '삭제 요청 → 삭제 처리 대기 → 삭제 중 → 삭제 완료 → nil'의 여러 단계를 거치는 구체적인 이유는 **삭제 요청 시점에도 엔티티가 처리해야 할 작업(처리해야 할 일)이 남아 있고, 그 과정에서 추가로 수행해야 할 작업(해야 할 일)이 존재하기 때문**입니다. 이 모든 작업들이 완전히 끝난 시점에야 비로소 엔티티가 실제로 삭제되고 nil 상태가 됩니다. 이러한 여러 단계의 상태 변화와 처리 과정을 모두 안전하게 확인하기 위해 `isv [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 메이플스토리 월드는 쉬운 코딩을 위해 다양한 편의 기능을 지원하고 있습니다. 대표적으로 간편한 실행 제어 설정 기능이 있습니다. 그러나 간단한 설정이 얽히며 복잡해질 수 있고, 잘못 설정하면 원하는 기능이 제대로 실행되지 않을 수도 있습니다. 때로는 월드가 매우 느려질 수도 있습니다. 이런 문제는 월드의 규모가 작거나 월드 제작 초창기에는 발견하기 어렵습니다. 하지만 월드의 규모가 커지고 완성도가 높아질수록 문제가 될 수 있습니다. 그러므로 제작 초기부터 모든 동작이 원활하고 효율적으로 진행되도록 구조를 고민
[task] | code [pass] | ⏳ 미판정 [title] | 아바타 표정 바꾸기 [question] | `_UserService`와 `AvatarRendererComponent`의 `PlayEmotion` 메서드를 사용하여 숫자키 4를 누르면 `EmotionalType.Smile` 표정을 5초간 재생하는 스크립트를 작성해줘 [answer] | 요청하신 기능(숫자키 4 누름 시 `EmotionalType.Smile` 표정 5초 재생)을 구현한 스크립트입니다. 1. **`HandleKeyDownEvent`**: `InputService`의 `KeyDownEvent`를 통해 키 입력을 감지합니다. 클라이언트에서 키가 눌러졌을 때 서버로 처리를 위임하거나, 문서 예시처럼 클라이언트에서 직접 서버 메서드를 호출하는 방식이 아닌, **서버에서 직접 입력 이벤트를 수신**하여 처리하는 것이 더 안정적인 구조일 수 있으나, 제공된 참고 문서의 예제(`[Client Only]` 핸들 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 키보드의 숫자키를 1부터 5까지 누르면 각각 다른 표정이 5초 동안 재생합니다. 1. MyDesk에서 새로운 컴포넌트를 만들고, 스크립트 작성 화면을 엽니다. 2. Function: 옆의 추가 를 눌러 **New**를 선택합니다. 3. 함수 이름을 Emote로 변경하고, 더 보기 를 선택해 **Add Parameter**를 두 번 추가해 매개 변수를 입력합니다. 5. `PlayEmotion`을 이용해 재생할 표정을 작성합니다. 6. Entity Event Handler에 `KeyDownEvent`를 추가하고, 표정 재생을
[task] | single_turn [pass] | ⏳ 미판정 [title] | Effective MSW 1 [question] | wait() 함수를 자주 사용해야 하는 경우와, 월드 성능 저하를 방지하기 위해 피해야 하는 경우의 차이는 어떻게 구분하나요? [answer] | 제공된 참고 문서에는 `wait()` 함수를 "자주 사용해야 하는 경우"와 "피해야 하는 경우"를 구체적으로 구분하는 기준이나 예시가 명시되어 있지 않습니다. 문서에서는 **Wait 계열 함수**(`wait()`, `_DataStorage:SetAndWait()`, `_DataStorage:GetAndWait()` 등)가 실행 순서를 파악하기 쉽고 편리하다는 장점이 있으나, **"편리하다는 이유로 남발하면 문제가 생길 수 있다"**는 점만 언급하고 있을 뿐, 어떤 상황에서 반드시 사용해야 하고 어떤 상황에서 금지해야 하는지에 대한 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 메이플스토리 월드는 쉬운 코딩을 위해 다양한 편의 기능을 지원하고 있습니다. 대표적으로 간편한 실행 제어 설정 기능이 있습니다. 그러나 간단한 설정이 얽히며 복잡해질 수 있고, 잘못 설정하면 원하는 기능이 제대로 실행되지 않을 수도 있습니다. 때로는 월드가 매우 느려질 수도 있습니다. 이런 문제는 월드의 규모가 작거나 월드 제작 초창기에는 발견하기 어렵습니다. 하지만 월드의 규모가 커지고 완성도가 높아질수록 문제가 될 수 있습니다. 그러므로 제작 초기부터 모든 동작이 원활하고 효율적으로 진행되도록 구조를 고민
[task] | single_turn [pass] | ⏳ 미판정 [title] | Effective MSW 1 [question] | 엔티티를 삭제 요청한 직후 nil 체크로 유효성을 확인했는데도 가끔 에러가 나는 이유는 무엇인가요? [answer] | 엔티티 삭제 요청 직후 `nil` 체크(`~= nil`)로 유효성을 확인해도 에러가 발생하는 이유는, 엔티티가 삭제 요청 즉시 `nil`이 되지 않기 때문입니다. 메이플스토리 월드에서 엔티티 삭제 과정은 단순한 상태 변경이 아니라 여러 단계로 이루어집니다. * **기대했던 동작:** 삭제 요청 → 즉시 `nil` * **실제 동작:** 삭제 요청 → 삭제 처리 대기 → 삭제 중 → 삭제 완료 → `nil` 삭제 요청이 들어간 후에도 엔티티는 내부적으로 '삭제 처리 대기' 및 '삭제 중' 상태를 거칩니다. 이 과정 동안 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 메이플스토리 월드는 쉬운 코딩을 위해 다양한 편의 기능을 지원하고 있습니다. 대표적으로 간편한 실행 제어 설정 기능이 있습니다. 그러나 간단한 설정이 얽히며 복잡해질 수 있고, 잘못 설정하면 원하는 기능이 제대로 실행되지 않을 수도 있습니다. 때로는 월드가 매우 느려질 수도 있습니다. 이런 문제는 월드의 규모가 작거나 월드 제작 초창기에는 발견하기 어렵습니다. 하지만 월드의 규모가 커지고 완성도가 높아질수록 문제가 될 수 있습니다. 그러므로 제작 초기부터 모든 동작이 원활하고 효율적으로 진행되도록 구조를 고민
[task] | instruction_following [pass] | ⏳ 미판정 [title] | Effective MSW 1 [question] | Server와 Client 각각에서 eventActiveTime 기반 경과 시간 계산을 수행하는 코드를 출력하고 로직 설명은 주석으로만 작성하세요. [answer] | ```lua Property: [Sync] number eventActiveTime = 0 Method: [server only] void StartEvent() { -- Server에서 이벤트 시작 시점의 서버 시간을 eventActiveTime에 저장 -- 이 값은 Client로 동기화되므로 Client에서도 접근 가능 self.eventActiveTime = _UtilLogic.ServerElapsedSeconds } [client only] void Update() { -- Client에서 매 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `wait`는 대기한 뒤에 직접 어떤 행동을 수행하는 것이고, `TimerService`는 해당 행동을 수행하는 별도의 일을 만드는 것입니다. `wait`는 직렬, `TimerService`는 병렬 형태로 동작합니다. 따라서 `wait`의 사용 코드는 다음과 같이 표현할 수 있습니다 ```lua local targetEntity = _EntityService:GetEntity("a22396e1-6365-42d4-9cef-5924c223f7fa") targetEntity.TestComponent:ShowMessage() func