[task] | single_turn [pass] | ⏳ 미판정 [title] | 프로퍼티 동기화 [question] | Sync 표시가 None으로 되어 있으면 프로퍼티 값이 공간별로 어떻게 관리되는지 궁금합니다. [answer] | `[None]`으로 설정된 프로퍼티는 서버와 클라이언트(공간) 사이에서 값이 동기화되지 않습니다. 이로 인해 각 공간(서버, 각 클라이언트)은 해당 프로퍼티의 값을 독립적으로 관리하게 됩니다. 구체적으로 설명하면 다음과 같습니다. 1. **동기화 없음**: `[Sync]`로 설정된 프로퍼티는 서버에서 값이 변경되면 모든 클라이언트에 자동으로 반영됩니다. 반면, `[None]`으로 설정된 프로퍼티는 서버에서 값을 변경해도 클라이언트는 알 수 없으며, 클라이언트에서 값을 변경해도 서버는 알 수 없습니다. 2. **공간별 독립 관 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 동기화 설정 방법은 매우 간단합니다. 스크립트 에디터를 한 번이라도 열어서 프로퍼티를 추가해봤다면 프로퍼티 상단에 Sync라고 쓰여 있는 것을 본 적이 있을 것입니다. 이 Sync는 프로퍼티 동기화가 되고 있다는 것을 의미합니다. 만일 프로퍼티 동기화를 원치 않는다면 Sync를 눌러 None으로 변경해 줍니다. 동기화 표시가 None으로 되어 있으면 프로퍼티 동기화는 이루어지지 않는다는 것을 의미하며, 프로퍼티 값을 공간별로 따로 관리할 수 있게 됩니다. #### 타입별 동기화 가능 여부 일부 타입의 프로퍼티는 동기화 설정이
[task] | single_turn [pass] | ⏳ 미판정 [title] | InputService를 활용한 입력과 액션 [question] | InputService 이벤트 핸들러를 서버에서만 실행되도록 설정했는데, 왜 유저 입력 이벤트가 절대 트리거되지 않는 걸까요? [answer] | InputService에서 발생하는 유저 입력 이벤트는 **클라이언트에서만 발생**하도록 설계되어 있습니다. 따라서 이벤트 핸들러를 서버 실행 공간(`[server only]` 등)으로 설정하면, 서버는 해당 입력 이벤트를 수신할 수 없으므로 절대 트리거되지 않습니다. 유저의 키보드 입력과 같은 InputService 이벤트는 클라이언트 환경에서만 유효하며, 이를 처리하는 이벤트 핸들러 역시 **클라이언트 실행 공간**(`[client only]`)에서 실행되어야 정상적으로 동작합니다. ### 올바른 설정 예시 이벤트 핸들러의 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 모든 게임은 유저의 입력과 입력에 대한 피드백으로 게임이 진행됩니다. 메이플스토리 월드에서는 InputService를 통해 유저의 입력에 대한 액션을 제어할 수 있습니다. 이번 과정에서는 유저의 입력이 발생했을 때의 액션을 추가하는 방법을 알아보겠습니다. # 참고 가이드 [Event System](https://mod-developers.nexon.com/docs?postId=73) [Entity Event System](https://mod-developers.nexon.com/docs?postId=176
[task] | single_turn [pass] | ⏳ 미판정 [title] | InputService를 활용한 입력과 액션 [question] | InputService를 통해 발생한 입력 이벤트를 처리하는 핸들러는 반드시 클라이언트에서만 실행되어야 하는 이유와 그 제약 사항이 무엇인가요? [answer] | InputService를 통해 발생한 입력 이벤트 핸들러는 반드시 클라이언트에서만 실행되어야 합니다. 이는 유저의 입력 이벤트 자체가 클라이언트에서만 발생하기 때문입니다. 따라서 해당 이벤트에 반응하는 각 이벤트 핸들러도 클라이언트 공간에서만 실행되도록 지정되어야 합니다. 제약 사항은 다음과 같습니다. 1. **실행 공간 제한**: 입력 이벤트 핸들러는 클라이언트에서만 실행되므로, 서버에서 직접 실행되는 로직을 포함할 수 없습니다. 2. **로컬 플레이어 확인 필요**: 클라이언트에서 실행되는 핸들러는 모든 엔티티의 입력을 수신 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 모든 게임은 유저의 입력과 입력에 대한 피드백으로 게임이 진행됩니다. 메이플스토리 월드에서는 InputService를 통해 유저의 입력에 대한 액션을 제어할 수 있습니다. 이번 과정에서는 유저의 입력이 발생했을 때의 액션을 추가하는 방법을 알아보겠습니다. # 참고 가이드 [Event System](https://mod-developers.nexon.com/docs?postId=73) [Entity Event System](https://mod-developers.nexon.com/docs?postId=176
[task] | single_turn [pass] | ⏳ 미판정 [title] | InputService를 활용한 입력과 액션 [question] | ScreenTouchEvent의 매개변수에서 터치 좌표를 가져올 때 어떤 필드를 사용해야 하는지 알 수가 없습니다. [answer] | `ScreenTouchEvent` 이벤트 핸들러에서 터치 좌표를 가져오려면 이벤트 객체의 `TouchPoint` 필드를 사용합니다. 이 필드는 터치한 위치의 좌표를 `Vector2` 타입으로 제공합니다. 다음은 터치 좌표를 콘솔에 출력하는 예제입니다. ```lua [service: InputService] HandleScreenTouchEvent(ScreenTouchEvent event) { local TouchPoint = event.TouchPoint log("Touch Point : "..tostring(To [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | KeyHoldEvent는 키보드의 키가 눌려있는 동안 프레임마다 발생하며, 이벤트가 발생할 때마다 HandleKeyHoldEvent 역시 매번 실행됩니다. KeyHoldEvent가 핸들러의 매개 변수로 전송되며, 다른 이벤트와 마찬가지로 유저가 입력한 키 정보가 포함되어 들어옵니다. 다음은 키를 누르는 동안 로그를 출력하는 예제입니다. ```lua [service: InputService] HandleKeyHoldEvent(KeyHoldEvent event) { --------------- Native Event Sende
[task] | single_turn [pass] | ⏳ 미판정 [title] | InputService를 활용한 입력과 액션 [question] | 키를 한 프레임도 없이 빠르게 눌렀다 뗄 때 KeyReleaseEvent가 발생하지 않는 이유는 무엇인가요? [answer] | `KeyReleaseEvent`는 키가 눌려 있는 상태(Hold)에 있다가 그 상태에서 키를 뗐을 때 1회 발생하는 이벤트입니다. 따라서 키를 한 프레임도 없이 빠르게 눌렀다 뗀 경우, 'Hold 되어 있던 상태'가 존재하지 않으므로 `KeyReleaseEvent`는 발생하지 않습니다. 문서에 따르면, 키가 한 프레임이라도 Hold 되어 있던 상태에서 Release 상태가 되었을 때 액션을 추가하고 싶을 때만 `HandleKeyReleaseEvent`를 사용한다고 명시되어 있습니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | KeyHoldEvent는 키보드의 키가 눌려있는 동안 프레임마다 발생하며, 이벤트가 발생할 때마다 HandleKeyHoldEvent 역시 매번 실행됩니다. KeyHoldEvent가 핸들러의 매개 변수로 전송되며, 다른 이벤트와 마찬가지로 유저가 입력한 키 정보가 포함되어 들어옵니다. 다음은 키를 누르는 동안 로그를 출력하는 예제입니다. ```lua [service: InputService] HandleKeyHoldEvent(KeyHoldEvent event) { --------------- Native Event Sende
[task] | single_turn [pass] | ⏳ 미판정 [title] | InputService를 활용한 입력과 액션 [question] | InputService 이벤트 핸들러에서 KeyboardKey.T와 같은 상수를 직접 비교하는 것이 표준적인 방식인가요? [answer] | 네, `InputService` 이벤트 핸들러에서 `KeyboardKey.T`와 같은 상수를 직접 비교하는 것이 표준적인 방식입니다. 참고 문서의 예제 코드들을 보면, `HandleKeyHoldEvent`, `HandleKeyReleaseEvent` 등 키보드 입력 이벤트 핸들러 내에서 `event.key` 값을 `KeyboardKey` 타입의 상수(예: `KeyboardKey.T`)와 `==` 연산자를 사용하여 비교하는 패턴이 일관되게 사용되고 있습니다. 이는 이벤트에 포함된 키 정보를 확인하여 특정 키에 대한 액션을 실행하기 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | KeyHoldEvent는 키보드의 키가 눌려있는 동안 프레임마다 발생하며, 이벤트가 발생할 때마다 HandleKeyHoldEvent 역시 매번 실행됩니다. KeyHoldEvent가 핸들러의 매개 변수로 전송되며, 다른 이벤트와 마찬가지로 유저가 입력한 키 정보가 포함되어 들어옵니다. 다음은 키를 누르는 동안 로그를 출력하는 예제입니다. ```lua [service: InputService] HandleKeyHoldEvent(KeyHoldEvent event) { --------------- Native Event Sende
[task] | code [pass] | ⏳ 미판정 [title] | InputService를 활용한 입력과 액션 [question] | InputService의 KeyDownEvent 이벤트 핸들러를 이용하여 특정 키 입력 시 클라이언트에서 log로 메시지를 출력하는 스크립트를 작성해줘 [answer] | InputService의 `KeyDownEvent` 이벤트 핸들러를 사용하여 특정 키가 눌렸을 때 클라이언트에서 `log`로 메시지를 출력하는 스크립트는 다음과 같습니다. 입력 이벤트는 클라이언트에서만 발생하므로, 이벤트 핸들러의 실행 공간을 `[client only]`로 지정하는 것이 적절합니다. ```lua Event Handler: [client only] [service: InputService] HandleKeyDownEvent(KeyDownEvent event) { -- Parameters local k [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 모든 게임은 유저의 입력과 입력에 대한 피드백으로 게임이 진행됩니다. 메이플스토리 월드에서는 InputService를 통해 유저의 입력에 대한 액션을 제어할 수 있습니다. 이번 과정에서는 유저의 입력이 발생했을 때의 액션을 추가하는 방법을 알아보겠습니다. # 참고 가이드 [Event System](https://mod-developers.nexon.com/docs?postId=73) [Entity Event System](https://mod-developers.nexon.com/docs?postId=176
[task] | code [pass] | ⏳ 미판정 [title] | 공격과 피격 [question] | **AttackComponent**의 `IsAttackTarget()`에서 `false`를 반환하여 특정 엔티티가 공격 대상이 아님을 판별하고, **HitComponent**의 `OnHit()`에서 `HitEvent` 발생 횟수를 카운트하여 100회 도달 시 특별한 처리(예: 로그 출력)를 수행하는 스크립트를 작성해줘. [answer] | 제공된 문서에는 `IsAttackTarget()` 함수의 존재와 동작 방식, 그리고 `HitEvent`의 발생 횟수를 확인하여 특별한 처리를 할 수 있다는 언급은 있지만, **`IsAttackTarget()`의 구현 예제 코드**나 **`HitEvent` 발생 횟수를 카운트하는 구체적인 프로퍼티/메서드 사용법**이 상세히 기술되어 있지 않습니다. 문서에 따르면: 1. `IsAttackTarget(Entity defender)` 함수는 `AttackComponent`에 존재하며, 리턴값이 `false`면 공격 실패로 이후 절차가 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 크리에이터의 공격 제작 방식에 따라 `IsAttackTarget()` 함수를 활용해 피격 대상을 선정할 수 있습니다. `IsAttackTarget()` 함수는 공격자가 공격 박스에 포함되지 않도록 처리되어 있으므로, 공격자가 타격을 받지 않게 처리할 필요가 없습니다. **Entity** 타입의 `defender` 매개변수는 충돌한 엔티티가 공격 대상인지 판단할 수 있는 엔티티 정보를 받습니다. 함수의 리턴값이 **false**면 **AttackComponent**에서 적합한 공격 대상으로 판별하고 이후 판단을 **HitCompone
[task] | two_turn [pass] | ⏳ 미판정 [title] | 서버와 클라이언트 [question] | 서버에 선언된 함수의 실행 공간을 클라이언트로 설정하면 서버 내 다른 함수에서 호출이 가능하다고 하는데, 이 경우 서버와 클라이언트 간 함수 호출 시 발생할 수 있는 예외나 주의사항은 무엇인가? [answer] | 제공된 참고 문서에는 서버에 선언된 함수의 실행 공간을 클라이언트로 설정했을 때 발생하는 **구체적인 예외 상황이나 기술적인 주의사항(예: 데이터 동기화 충돌, 지연 처리, 실패 시 처리 등)에 대한 설명이 없습니다.** 문서에서 언급되는 내용만으로는 다음과 같은 사실만 확인됩니다. 1. **실행제어의 개념**: 서버와 클라이언트 간에 "액션"(함수)을 요청하고 수행하는 과정을 실행제어라고 합니다. 2. **실행 공간 설정의 효과**: 서버에 선언된 함수의 실행 공간을 클라이언트로 설정하면, 해당 함수는 **서버 내 다른 함 [followup] | 서버 함수에서 클라이언트 실행 공간의 함수를 호출할 때, 해당 함수가 클라이언트에서 실행됨을 보장하는 mLua 메서드 선언부 예시를 보여줘. [followup_answer] | 제공된 참고 문서에는 서버 함수에서 클라이언트 실행 공간의 함수를 호출하는 **구체적인 mLua 메서드 선언부 예시 코드**가 포함되어 있지 않습니다. 문서에서는 "서버에 선언된 함수 B의 실행 공간을 클라이언트로 설정했다면, 함수 B는 서버 내 다른 함수에서 호출이 가능하지만, 클라이언트에서 실행되기 때문에 서버에서 호출할 수 있는 클라이언트 함수처럼 사용이 가능합니다"라고 개념적으로 설명하고 있으며, `<MethodB의 실행 공간을 클라이언트, MethodC의 실행 공간을 서버로 설정했을 때의 요청과 수행>`이라는 제목의 예시 [scores] | [judge_reason] | [source_doc] | 서버와 클라이언트 간 통신에는 데이터의 전달, 즉 동기화 외에도 공간에 정의된 "액션"을 요청하고 수행하는 과정도 필요합니다. 위의 레벨업 처리 과정을 예시로 들면, 클라이언트가 유저의 입력을 받으면, 서버에게 "몬스터 공격"이라는 "액션"을 요청하게 되고, 서버는 클라이언트의 요청에 따라 "몬스터 공격"이라는 "액션"을 수행하게 되는데요, 이렇듯 각 공간에 정의된 액션을 서로 요청하여 수행케 하는 것을 실행제어라고 합니다. 실행제어는 제작자의 의도에 따라 설정할 수 있습니다. 위에 말한 "액션"은 결국 스크립트에서는 "함수"라 할
[task] | two_turn [pass] | ⏳ 미판정 [title] | 서버와 클라이언트 [question] | MapleStory World에서 서버와 클라이언트의 통신 모델 구조가 어떻게 작동하는지 개요를 설명해 주세요. [answer] | MapleStory World는 **서버-클라이언트(Server-Client) 모델**을 기반으로 통신을 처리합니다. 이 구조는 다음과 같은 원리로 작동합니다. ### 1. 기본 구성 * **클라이언트(Client)**: 유저의 모바일, PC 등 기기에 설치되어 실행되는 프로그램입니다. 유저의 입력(조작)을 처리하고, 서버로부터 받은 정보를 시각적으로 출력하는 역할을 담당합니다. * **서버(Server)**: 다수의 클라이언트가 연결되는 중앙 컴퓨터(또는 프로그램)입니다. 게임 진행의 주요 로직과 시스템을 관리하며, 모든 [followup] | [server only] 또는 [client only] 실행 공간 지정이 필요한 구체적인 상황과, 이를 위반할 때 발생할 수 있는 예외 케이스는 무엇이며, 올바른 코드 작성 예시를 보여주세요. [followup_answer] | 제공된 참고 문서에는 `[server only]` 또는 `[client only]` 태그를 사용하는 구체적인 문법이나, 이를 위반했을 때 발생하는 특정 예외 케이스(에러 코드 등)에 대한 기술이 포함되어 있지 않습니다. 문서에 명시된 내용은 서버와 클라이언트의 **역할 분담 원칙**과 **해킹 취약성 방지**에 초점을 맞추고 있으며, 구체적인 코드 실행 공간 지정 문법은 제시되지 않았습니다. 다만, 문서의 내용을 바탕으로 **역할 분담 원칙**에 맞는 올바른 설계 방향은 다음과 같이 설명할 수 있습니다. ### 1. 역할 분담 [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 멀티 플레이를 제공하는 게임의 경우 각 게임의 특성에 따라 사용되는 통신 모델들이 다양합니다. MapleStory World는 다양한 통신 모델 중에서도 서버 - 클라이언트 모델을 사용하고 있습니다. 이번 과정에서는 MapleStory World의 통신 모델인 서버와 클라이언트의 개념과 구조, 그리고 각 공간 간의 정보전달 방법에 대해 알아보도록 하겠습니다. # 서버와 클라이언트 클라이언트는 게임을 플레이하는 유저들의 모바일이나 PC, 또는 해당 기기에서 개별적으로 돌아가는 프로그램을 의미합니다.주로 유저의
[task] | two_turn [pass] | ⏳ 미판정 [title] | 프로퍼티 동기화 [question] | 서버에서 프로퍼티 값을 변경하면 클라이언트로 전송되지만, 클라이언트에서 단독으로 프로퍼티 값을 수정하면 서버에 반영되지 않는 이유는 무엇이며, 이 경우 어떤 문제가 발생할 수 있는지 설명해 주세요. [answer] | 서버에서 프로퍼티 값을 변경하면 클라이언트로 전송되지만, 클라이언트에서 단독으로 프로퍼티 값을 수정하면 서버에 반영되지 않는 이유는 다음과 같습니다. 1. **동기화 방향성**: 메이플스토리 월드의 프로퍼티 동기화는 기본적으로 **서버에서 클라이언트로** 한 방향으로 진행됩니다. 2. **서버의 단일성 vs 클라이언트의 복수성**: * **서버**: 단독으로 존재하므로, 서버에서 값이 변경되면 모든 클라이언트로 일관되게 전송할 수 있습니다. * **클라이언트**: 여러 명이 접속하여 각자 다른 클라이언트를 [followup] | 클라이언트에서 직접 프로퍼티를 수정하여 서버와 값이 달라진 상태(스킵)가 발생했을 때, 이를 해결하기 위해 서버 로직을 어떻게 수정해야 하는지 코드 예시를 보여주세요. [followup_answer] | 참고 문서에 따르면, 클라이언트에서 단독으로 프로퍼티 값을 변경하는 것은 **특수한 경우를 제외하고는 추천하지 않는 방법**이며, 프로퍼티 동기화는 기본적으로 **서버에서 클라이언트로** 진행됩니다. 따라서 "클라이언트에서 직접 프로퍼티를 수정하여 생긴 스킵을 해결하기 위해 서버 로직을 수정"하는 것은 메이플스토리 월드의 프로퍼티 동기화 설계 원칙과 맞지 않습니다. 대신, 프로퍼티 값의 변경 로직은 **항상 서버에서 수행**되어야 하며, 클라이언트는 서버로부터 동기화된 값을 받아 UI 등에만 반영하는 역할에 집중해야 합니다. 즉 [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 서버, 클라이언트 간 데이터 전송 방식 중 하나인 프로퍼티 동기화에 대해 알아봅시다. # 동기화 메이플스토리 월드에서의 동기화는 서버, 클라이언트 간 데이터 전송 방식의 일종으로,각각의 공간에 존재하는 같은 이름의 프로퍼티를 같은 값으로 맞춰주는 것을 의미합니다. 기본적으로 프로퍼티는 선언과 동시에 서버, 클라이언트 각각의 공간에 생성되지만, 만일 프로퍼티 동기화가 되지 않는다면 이름은 같지만 서로 다른 값으로 설정할 수 있습니다. 제작자의 의도에 따라서 같은 프로퍼티의 값을 각 공간에 따라 다르게 할당
[task] | code [pass] | ⏳ 미판정 [title] | InputService를 활용한 입력과 액션 [question] | InputService의 KeyDownEvent 핸들러를 사용하여 T 키가 눌릴 때마다 로그를 출력하는 스크립트를 작성해줘 [answer] | InputService의 `KeyDownEvent` 핸들러를 사용하여 T 키 입력 시 로그를 출력하는 스크립트는 다음과 같습니다. ```lua Event Handler: [service: InputService] HandleKeyDownEvent(KeyDownEvent event) { local key = event.key if key == KeyboardKey.T then log("T key pressed!") end } ``` [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `KeyDownEvent`는 키를 눌렀을 때 발생하는 이벤트입니다. `KeyDownEvent`가 발생하면 **HandleKeyDownEvent**가 실행됩니다. `KeyDownEvent`가 핸들러의 매개 변수로 전송되며, 이벤트에는 유저가 입력한 키가 enum으로 넘어오게 됩니다. 다음은 `T` 키를 눌렀을 때 로그를 출력하는 예제입니다. ```lua Event Handler: [service: InputService] HandleKeyDownEvent(KeyDownEvent event) { --------------- N
[task] | single_turn [pass] | ⏳ 미판정 [title] | InputService를 활용한 입력과 액션 [question] | KeyHoldEvent와 KeyReleaseEvent의 발생 조건 차이와 각각 어떤 상황에 적합한지 궁금합니다. [answer] | KeyHoldEvent와 KeyReleaseEvent의 발생 조건과 적합한 상황은 다음과 같습니다. **1. 발생 조건 차이** * **KeyHoldEvent**: 키보드의 키가 **눌려있는 동안 프레임마다** 발생하는 이벤트입니다. 따라서 키를 누르고 있는 시간 동안 `HandleKeyHoldEvent`가 매 프레임마다 반복적으로 실행됩니다. * **KeyReleaseEvent**: 키보드의 키가 눌려있는 상태에서 **키에서 손을 떼었을 때 1회** 발생하는 이벤트입니다. `HandleKeyReleaseEvent`는 키가 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | KeyHoldEvent는 키보드의 키가 눌려있는 동안 프레임마다 발생하며, 이벤트가 발생할 때마다 HandleKeyHoldEvent 역시 매번 실행됩니다. KeyHoldEvent가 핸들러의 매개 변수로 전송되며, 다른 이벤트와 마찬가지로 유저가 입력한 키 정보가 포함되어 들어옵니다. 다음은 키를 누르는 동안 로그를 출력하는 예제입니다. ```lua [service: InputService] HandleKeyHoldEvent(KeyHoldEvent event) { --------------- Native Event Sende
[task] | two_turn [pass] | ⏳ 미판정 [title] | 서버와 클라이언트 [question] | 스크립트 컴포넌트에서 프로퍼티 동기화 여부를 설정하는 기능과, 특정 컴포넌트(주로 클라이언트 전용)에서 동기화가 이루어지지 않는 특성에 대해 알려 주세요. [answer] | 메이플스토리 월드(mLua)에서 스크립트 컴포넌트의 프로퍼티 동기화는 컴포넌트의 기능과 특성에 따라 다르게 동작하며, 제작자가 이를 직접 설정할 수 있습니다. **1. 클라이언트 전용 컴포넌트의 동기화 특성** 주로 클라이언트에서만 작동하는 컴포넌트의 경우, 서버로 데이터를 전송할 필요가 없기 때문에 프로퍼티 동기화가 이루어지지 않습니다. 이는 불필요한 네트워크 트래픽을 줄이고 효율적인 구조를 만들기 위한 설계입니다. **2. 스크립트 컴포넌트의 동기화 설정 기능** 스크립트 컴포넌트에서는 제작자가 본인의 컴포넌트 기능, 특성, [followup] | 클라이언트 전용 컴포넌트에서 서버와 통신해야 할 때 동기화 대신 어떤 방식(예: 실행제어 등)을 사용해야 하는지와 그 코드적 접근 방법을 설명해 주세요. [followup_answer] | 제공된 참고 문서에는 클라이언트 전용 컴포넌트에서 서버와 통신하기 위해 **실행제어**를 구체적으로 어떻게 사용하는지에 대한 코드 예제나 상세한 API 설명이 포함되어 있지 않습니다. 문서에서 실행제어에 대해 설명하는 부분은 다음과 같이 매우 간략합니다: > "MapleStory World에서는 데이터 또는 상태를 전달하는 방식인 동기화와 특정 상황에 발생해야 할 행위, 행동들을 전달하는 방식인 실행제어를 제공하고 있습니다." 즉, 문서상으로는 실행제어가 "특정 상황에 발생해야 할 행위, 행동들을 전달하는 방식"임을 알 수 있으 [scores] | [judge_reason] | [source_doc] | 서버와 클라이언트가 어떻게 상호작용을 하는지를 알아보았으니, 이제 메이커에서 작성한 프로그램이 서버와 클라이언트에서 어떻게 돌아가는지 알아보도록 합니다. 제작자가 스크립트에서 선언한 프로퍼티와 함수는 별도의 설정을 하지 않는 한 기본적으로 서버와 클라이언트 두 개의 공간에 각각 독립적으로 생성됩니다. 이름은 같지만 서로 다른 공간에 존재하기 때문에 별도의 프로퍼티 또는 함수라 보는 것이 좋습니다. 기본적으로 함수의 호출과 프로퍼티의 값 참조 및 할당은 같은 공간 내에서만 이루어집니다. 예를 들어 A라는 프로퍼티에 값을 B라는 함
[task] | code [pass] | ⏳ 미판정 [title] | InputService를 활용한 입력과 액션 [question] | InputService의 IsKeyPressed() 함수를 OnUpdate 메서드에서 호출하여 Enter 키가 눌린 상태일 때만 로그를 출력하는 스크립트를 작성해줘 [answer] | `OnUpdate` 메서드 안에서 `_InputService:IsKeyPressed()` 함수를 사용해 Enter 키(`KeyboardKey.Return`)가 눌린 상태를 매 프레임마다 확인하고, 조건이 true일 때 로그를 출력하는 스크립트입니다. ```lua Method: [client only] void OnUpdate(number delta) { local isEnterPressed = _InputService:IsKeyPressed(KeyboardKey.Return) if isEnterPressed [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `KeyDownEvent`는 키를 눌렀을 때 발생하는 이벤트입니다. `KeyDownEvent`가 발생하면 **HandleKeyDownEvent**가 실행됩니다. `KeyDownEvent`가 핸들러의 매개 변수로 전송되며, 이벤트에는 유저가 입력한 키가 enum으로 넘어오게 됩니다. 다음은 `T` 키를 눌렀을 때 로그를 출력하는 예제입니다. ```lua Event Handler: [service: InputService] HandleKeyDownEvent(KeyDownEvent event) { --------------- N
[task] | instruction_following [pass] | ⏳ 미판정 [title] | InputService를 활용한 입력과 액션 [question] | ScreenTouchHoldEvent와 ScreenTouchReleaseEvent의 발생 시점과 이벤트 객체에 포함된 좌표 정보 변수 이름을 3문장 이내로 설명하세요. [answer] | `ScreenTouchHoldEvent`는 화면을 터치하고 있는 동안 프레임마다 발생하며, `ScreenTouchReleaseEvent`는 터치를 종료했을 때 1회 발생합니다. 두 이벤트 모두 핸들러의 매개 변수로 이벤트 객체를 전달받으며, 터치 중이거나 터치를 뗀 위치의 좌표 정보는 `event.TouchPoint` 변수에 포함되어 있습니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `ScreenTouchHoldEvent`는 화면을 터치하고 있는 동안 프레임마다 발생합니다. 이벤트가 발생할 때마다 **HandleScreenTouchHoldEvent**가 실행됩니다. `ScreenTouchHoldEvent`가 핸들러의 매개 변수로 전송되며, 터치 중인 위치의 좌표 정보가 포함되어 있습니다. 화면을 터치 중일 때 터치한 위치의 좌표를 콘솔 창에 출력하는 예제입니다. ```lua [service: InputService] HandleScreenTouchHoldEvent(ScreenTouchHoldEvent even
[task] | single_turn [pass] | ⏳ 미판정 [title] | InputService를 활용한 입력과 액션 [question] | HandleKeyHoldEvent에서 특정 키를 누르고 있는 동안 매 프레임마다 함수가 실행된다는 점이 로직 성능에 영향을 줄 수 있는지 걱정됩니다. [answer] | `HandleKeyHoldEvent`는 키보드의 키가 눌려있는 동안 **매 프레임마다** 이벤트가 발생하고, 이에 따라 핸들러 함수도 매 프레임마다 실행됩니다. 따라서 이 핸들러 내부에 무거운 로직(예: 복잡한 계산, 빈번한 네트워크 통신, 대량의 엔티티 조작 등)이 있다면 프레임마다 반복적으로 실행되어 성능 저하를 유발할 수 있습니다. 성능 문제를 방지하기 위해 다음과 같은 방식으로 로직을 구성하는 것이 좋습니다. 1. **상태 관리 분리**: `HandleKeyHoldEvent` 내부에서는 단순한 상태 확인(예: 키가 눌려있 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | KeyHoldEvent는 키보드의 키가 눌려있는 동안 프레임마다 발생하며, 이벤트가 발생할 때마다 HandleKeyHoldEvent 역시 매번 실행됩니다. KeyHoldEvent가 핸들러의 매개 변수로 전송되며, 다른 이벤트와 마찬가지로 유저가 입력한 키 정보가 포함되어 들어옵니다. 다음은 키를 누르는 동안 로그를 출력하는 예제입니다. ```lua [service: InputService] HandleKeyHoldEvent(KeyHoldEvent event) { --------------- Native Event Sende
[task] | code [pass] | ⏳ 미판정 [title] | InputService를 활용한 입력과 액션 [question] | InputService의 IsAnyKeyPressed() 함수를 OnUpdate 메서드에서 호출하여 어떤 키라도 눌린 상태라면 로그를 출력하는 스크립트를 작성해줘 [answer] | `InputService`의 `IsAnyKeyPressed()` 함수는 현재 아무 키라도 눌려 있으면 `true`를, 그렇지 않으면 `false`를 반환합니다. 이 함수는 이벤트 핸들러 대신 `OnUpdate` 메서드 안에서 주기적으로 호출하여 키 입력 상태를 실시간으로 확인할 때 사용할 수 있습니다. 아래는 `OnUpdate`에서 `IsAnyKeyPressed()`를 호출하여 어떤 키라도 눌린 상태임을 감지하면 로그를 출력하는 mLua 스크립트입니다. ```lua Method: [client only] void OnUpdate [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `KeyDownEvent`는 키를 눌렀을 때 발생하는 이벤트입니다. `KeyDownEvent`가 발생하면 **HandleKeyDownEvent**가 실행됩니다. `KeyDownEvent`가 핸들러의 매개 변수로 전송되며, 이벤트에는 유저가 입력한 키가 enum으로 넘어오게 됩니다. 다음은 `T` 키를 눌렀을 때 로그를 출력하는 예제입니다. ```lua Event Handler: [service: InputService] HandleKeyDownEvent(KeyDownEvent event) { --------------- N
[task] | code [pass] | ⏳ 미판정 [title] | InputService를 활용한 입력과 액션 [question] | InputService의 KeyUpEvent 핸들러를 사용하여 T 키에서 손을 떼었을 때 1회 로그를 출력하는 스크립트를 작성해줘 [answer] | `KeyUpEvent`는 키보드의 키를 눌렀다가 손을 떼었을 때 1회 발생하는 이벤트입니다. 해당 이벤트가 발생하면 `HandleKeyUpEvent` 함수가 실행되며, 이벤트 객체에 포함된 `key` 값을 확인하여 특정 키가 해제되었는지 판별할 수 있습니다. 다음은 `T` 키에서 손을 떼었을 때 로그를 1회 출력하는 mLua 스크립트입니다. ```lua Event Handler: [service: InputService] HandleKeyUpEvent(KeyUpEvent event) { --------------- Nat [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `KeyDownEvent`는 키를 눌렀을 때 발생하는 이벤트입니다. `KeyDownEvent`가 발생하면 **HandleKeyDownEvent**가 실행됩니다. `KeyDownEvent`가 핸들러의 매개 변수로 전송되며, 이벤트에는 유저가 입력한 키가 enum으로 넘어오게 됩니다. 다음은 `T` 키를 눌렀을 때 로그를 출력하는 예제입니다. ```lua Event Handler: [service: InputService] HandleKeyDownEvent(KeyDownEvent event) { --------------- N
[task] | two_turn [pass] | ⏳ 미판정 [title] | 서버와 클라이언트 [question] | mLua 스크립트에서 서버와 클라이언트 공간이 독립적으로 동작하는 기본 원리와 프로퍼티 동기화의 방향성(서버 [answer] | mLua 스크립트에서 서버와 클라이언트 공간은 기본적으로 독립적으로 동작합니다. 제작자가 스크립트에서 선언한 프로퍼티와 함수는 별도의 설정이 없으면 서버와 클라이언트 두 공간에 각각 독립적인 인스턴스로 생성됩니다. 이름은 같지만 서로 다른 공간에 존재하므로, 이는 서로 다른 프로퍼티나 함수로 간주해야 합니다. **독립적 동작 원리** 기본적으로 함수 호출과 프로퍼티의 값 참조 및 할당은 같은 공간 내에서만 이루어집니다. * 서버에서 함수를 호출하거나 프로퍼티 값을 변경하면, 서버 공간 내의 프로퍼티와 함수에만 영향을 미칩니다. [followup] | 클라이언트)이 무엇인지 설명해 주세요. → [Sync] 프로퍼티가 선언되어 있지 않은 경우, 클라이언트에서 값을 변경해도 서버에는 반영되지 않는 이유와 일 대 다 관계에서의 충돌 방지 원리를 구체적으로 설명해 주세요. [followup_answer] | mLua 스크립트에서 서버와 클라이언트 공간은 기본적으로 독립적으로 동작하며, 프로퍼티의 동기화 방향성과 그 원리는 다음과 같습니다. **1. [Sync] 프로퍼티가 선언되지 않은 경우의 동작** 프로퍼티에 `[Sync]` 속성이 선언되지 않으면, 해당 프로퍼티는 서버와 클라이언트 간에 값이 자동 동기화되지 않습니다. * **공간 분리:** 서버와 클라이언트는 서로 독립적인 공간을 가지므로, 한 공간에서 프로퍼티 값을 변경해도 다른 공간의 프로퍼티에는 아무런 변화가 발생하지 않습니다. * **클라이언트 변경 시:** 클라이 [scores] | [judge_reason] | [source_doc] | 서버와 클라이언트가 어떻게 상호작용을 하는지를 알아보았으니, 이제 메이커에서 작성한 프로그램이 서버와 클라이언트에서 어떻게 돌아가는지 알아보도록 합니다. 제작자가 스크립트에서 선언한 프로퍼티와 함수는 별도의 설정을 하지 않는 한 기본적으로 서버와 클라이언트 두 개의 공간에 각각 독립적으로 생성됩니다. 이름은 같지만 서로 다른 공간에 존재하기 때문에 별도의 프로퍼티 또는 함수라 보는 것이 좋습니다. 기본적으로 함수의 호출과 프로퍼티의 값 참조 및 할당은 같은 공간 내에서만 이루어집니다. 예를 들어 A라는 프로퍼티에 값을 B라는 함
[task] | single_turn [pass] | ⏳ 미판정 [title] | InputService를 활용한 입력과 액션 [question] | KeyDownEvent 핸들러에서 키가 눌리는 동안 로그가 계속 출력되는 것이 아니라 한 번만 출력되는 이유를 알고 싶어요. [answer] | `KeyDownEvent`는 특정 키를 **눌렀을 때** 발생하는 이벤트입니다. 이 이벤트의 정의상 키가 처음 눌리는 순간에만 한 번 발생하며, 키를 계속 누르고 있는 동안에는 추가적으로 발생하지 않습니다. 따라서 `HandleKeyDownEvent` 핸들러는 키 입력이 처음 감지되는 시점에 1회 실행되어 로그가 한 번만 출력됩니다. 키를 계속 누르고 있는 동안의 상태(홀드 상태)를 처리하려면 `IsKeyPressed()` 함수를 사용하거나, `KeyUpEvent`(키를 떼는 순간)를 함께 활용하는 방식이 필요합니다. 참고로, [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `KeyDownEvent`는 키를 눌렀을 때 발생하는 이벤트입니다. `KeyDownEvent`가 발생하면 **HandleKeyDownEvent**가 실행됩니다. `KeyDownEvent`가 핸들러의 매개 변수로 전송되며, 이벤트에는 유저가 입력한 키가 enum으로 넘어오게 됩니다. 다음은 `T` 키를 눌렀을 때 로그를 출력하는 예제입니다. ```lua Event Handler: [service: InputService] HandleKeyDownEvent(KeyDownEvent event) { --------------- N
[task] | two_turn [pass] | ⏳ 미판정 [title] | InputService를 활용한 입력과 액션 [question] | `KeyDownEvent`와 `IsKeyPressed()` 함수를 사용하여 키 입력을 처리하는 방식의 차이는 무엇이며, 각각 어떤 경우에 사용하는 것이 적합한가요? [answer] | `KeyDownEvent`와 `IsKeyPressed()`는 모두 키보드 입력을 처리하는 방식이지만, 동작 원리와 적용 시점이 명확히 다릅니다. ### 1. 동작 방식의 차이 **KeyDownEvent (이벤트 기반)** * **특징:** 키가 **눌린 순간**에 1회 발생하도록 설계된 이벤트입니다. * **처리 방식:** `HandleKeyDownEvent` 핸들러가 실행되며, 이벤트 객체를 통해 어떤 키가 눌렸는지(`event.key`)를 확인합니다. * **반복 실행:** 키를 계속 누르고 있어도, 처음 눌린 순 [followup] | `IsKeyPressed()`를 `OnUpdate`에서 사용할 때 매 프레임마다 로그가 중복 출력되는 문제를 방지하고, 특정 키가 눌려 있는 동안에만 액션이 실행되도록 코드를 어떻게 수정해야 하는지 구체적인 예제를 보여주세요. [followup_answer] | `IsKeyPressed()`는 현재 키가 눌려 있는지 여부를 `true`/`false`로 반환하는 함수이므로, `OnUpdate`에서 호출하면 키가 눌려 있는 동안 매 프레임마다 조건이 `true`가 되어 로그나 액션이 반복적으로 실행됩니다. 이 문제를 방지하고 "키가 눌려 있는 동안에만" 액션을 실행하려면, 단순히 로그를 출력하는 대신 **키 입력 상태에 따라 지속적 동작(이동, 회전 등)을 제어하는 로직**을 구현해야 합니다. 또한, 매 프레임 로그가 중복되는 것을 원하지 않는다면 로그 출력을 제거하거나, 상태가 변경될 때만 [scores] | [judge_reason] | [source_doc] | `KeyDownEvent`는 키를 눌렀을 때 발생하는 이벤트입니다. `KeyDownEvent`가 발생하면 **HandleKeyDownEvent**가 실행됩니다. `KeyDownEvent`가 핸들러의 매개 변수로 전송되며, 이벤트에는 유저가 입력한 키가 enum으로 넘어오게 됩니다. 다음은 `T` 키를 눌렀을 때 로그를 출력하는 예제입니다. ```lua Event Handler: [service: InputService] HandleKeyDownEvent(KeyDownEvent event) { --------------- N
[task] | single_turn [pass] | ⏳ 미판정 [title] | InputService를 활용한 입력과 액션 [question] | HandleKeyDownEvent와 HandleKeyUpEvent 중 키를 누르고 있는 동안 지속되는 동작을 구현하려면 어떤 이벤트를 사용해야 하나요? [answer] | 키를 누르고 있는 동안 지속되는 동작을 구현하려면 `KeyDownEvent`를 사용해야 합니다. `KeyDownEvent`는 키를 눌렀을 때 발생하는 이벤트이며, `HandleKeyDownEvent` 핸들러가 실행됩니다. 반면 `KeyUpEvent`는 키에서 손을 떼었을 때 **1회**만 발생하는 이벤트입니다. 참고로, 키가 눌려 있는 동안 매 프레임마다 상태 확인을 원한다면 이벤트 핸들러 대신 `OnUpdate` 메서드에서 `_InputService:IsKeyPressed()` 함수를 사용하는 방식도 가능합니다. 이 함수는 키 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `KeyDownEvent`는 키를 눌렀을 때 발생하는 이벤트입니다. `KeyDownEvent`가 발생하면 **HandleKeyDownEvent**가 실행됩니다. `KeyDownEvent`가 핸들러의 매개 변수로 전송되며, 이벤트에는 유저가 입력한 키가 enum으로 넘어오게 됩니다. 다음은 `T` 키를 눌렀을 때 로그를 출력하는 예제입니다. ```lua Event Handler: [service: InputService] HandleKeyDownEvent(KeyDownEvent event) { --------------- N
[task] | single_turn [pass] | ⏳ 미판정 [title] | InputService를 활용한 입력과 액션 [question] | InputService의 IsAnyKeyPressed() 함수는 특정 키가 아닌 아무 키라도 눌렸을 때 true를 반환하는 것이 맞나요? [answer] | 네, 맞습니다. `IsAnyKeyPressed()`는 특정 키를 지정하지 않고, 아무 키라도 눌려 있는 상태이면 `true`를 반환하고 아무 키도 눌리지 않은 상태이면 `false`를 반환합니다. 이 함수는 이벤트 핸들러를 사용하지 않고 매 프레임 업데이트 시점의 키 입력 상태를 확인하기 위해 `OnUpdate` 같은 메서드 내에서 `_InputService`를 통해 호출할 수 있습니다. ```lua Method: [client only] void OnUpdate(number delta) { local anyKeyPres [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `KeyDownEvent`는 키를 눌렀을 때 발생하는 이벤트입니다. `KeyDownEvent`가 발생하면 **HandleKeyDownEvent**가 실행됩니다. `KeyDownEvent`가 핸들러의 매개 변수로 전송되며, 이벤트에는 유저가 입력한 키가 enum으로 넘어오게 됩니다. 다음은 `T` 키를 눌렀을 때 로그를 출력하는 예제입니다. ```lua Event Handler: [service: InputService] HandleKeyDownEvent(KeyDownEvent event) { --------------- N
[task] | instruction_following [pass] | ⏳ 미판정 [title] | InputService를 활용한 입력과 액션 [question] | 두 이벤트 핸들러의 실행 공간(Space)과 매개 변수에 포함된 TouchId, TouchPoint 필드를 비교한 표로 정리해서 작성하세요. [answer] | `ScreenTouchHoldEvent`와 `ScreenTouchReleaseEvent`의 실행 공간 및 매개 변수 필드를 비교한 표는 다음과 같습니다. | 구분 | ScreenTouchHoldEvent | ScreenTouchReleaseEvent | | :--- | :--- | :--- | | **실행 공간 (Space)** | Client | Client | | **TouchId** | `event.TouchId`<br>(터치 식별자) | `event.TouchId`<br>(터치 식별자) | | **TouchPoint** | [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | `ScreenTouchHoldEvent`는 화면을 터치하고 있는 동안 프레임마다 발생합니다. 이벤트가 발생할 때마다 **HandleScreenTouchHoldEvent**가 실행됩니다. `ScreenTouchHoldEvent`가 핸들러의 매개 변수로 전송되며, 터치 중인 위치의 좌표 정보가 포함되어 있습니다. 화면을 터치 중일 때 터치한 위치의 좌표를 콘솔 창에 출력하는 예제입니다. ```lua [service: InputService] HandleScreenTouchHoldEvent(ScreenTouchHoldEvent even
[task] | code [pass] | ⏳ 미판정 [title] | 프로퍼티 동기화 [question] | 서버에서 HP 프로퍼티의 값을 감소시킬 때, 클라이언트에서 OnSyncProperty 이벤트를 통해 HP가 동기화된 시점에 HP 게이지 UI를 갱신하는 스크립트를 작성해줘. [answer] | 서버에서 HP 프로퍼티의 값을 변경하면, `[Sync]` 속성이 설정된 프로퍼티는 자동으로 클라이언트로 전송됩니다. 클라이언트에서는 `OnSyncProperty` 이벤트 핸들러가 호출되며, 이 시점에 HP 게이지 UI를 갱신하는 로직을 구현할 수 있습니다. 아래는 서버에서 HP를 감소시키고, 클라이언트에서 해당 동기화 이벤트를 받아 UI를 갱신하는 mLua 스크립트 예시입니다. ```lua Property: [Sync] number HP = 100 Method: [server only] void DecreaseHP(numb [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 서버, 클라이언트 간 데이터 전송 방식 중 하나인 프로퍼티 동기화에 대해 알아봅시다. # 동기화 메이플스토리 월드에서의 동기화는 서버, 클라이언트 간 데이터 전송 방식의 일종으로,각각의 공간에 존재하는 같은 이름의 프로퍼티를 같은 값으로 맞춰주는 것을 의미합니다. 기본적으로 프로퍼티는 선언과 동시에 서버, 클라이언트 각각의 공간에 생성되지만, 만일 프로퍼티 동기화가 되지 않는다면 이름은 같지만 서로 다른 값으로 설정할 수 있습니다. 제작자의 의도에 따라서 같은 프로퍼티의 값을 각 공간에 따라 다르게 할당
[task] | instruction_following [pass] | ⏳ 미판정 [title] | 실행 제어 [question] | 서버와 클라이언트 간 데이터 통신의 기본 흐름을 '메시지 생성'부터 '메시지에 따른 행동'까지 4단계로만 순서대로 나열해서 답변하세요. [answer] | 1. 메시지 생성 2. 메시지 송신 3. 메시지 수신 4. 메시지에 따른 행동 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 클라이언트와 서버의 흐름을 쉽게 제어할 수 있게 하는 실행 제어의 개념과 활용 방법을 알아봅니다. ##### 들어가기에 앞서 본 과정을 이해하기 위해선 다음 가이드 선행 학습이 필요합니다. [서버와 클라이언트](https://mod-developers.nexon.com/docs?postId=207%7B%22target%22:%22\_self%22%7D) # 서버 - 클라이언트 간 데이터 통신 **클라이언트 - 서버** 간의 흐름을 제어하려면 데이터를 전송해야 합니다. 예를 들어, 서버에서 클라이언트로 "3초
[task] | code [pass] | ⏳ 미판정 [title] | 서버와 클라이언트 [question] | 클라이언트에서 서버로 몬스터 공격 액션을 요청하고, 서버에서 해당 액션을 수행하여 몬스터 체력을 감소시키는 스크립트를 작성해줘 (Method: [server] HandleAttackAction, Event Handler: [self] HandleTouchEvent) [answer] | 요청하신 시나리오(클라이언트에서 `HandleTouchEvent`로 서버에 요청하고, 서버의 `HandleAttackAction`에서 체력을 감소)를 구현하기 위해 **참고 문서에 없는 API와 프로퍼티가 있습니다.** 참고 문서에는 `_UserService`, `_EntityService`, `_SpawnService`와 `HandleUserEnterEvent`, `HandleEntityCreateEvent`, `HandleButtonClickEvent` 등만 정의되어 있습니다. 1. **`HandleTouchEvent`**: [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 서버와 클라이언트 간 통신에는 데이터의 전달, 즉 동기화 외에도 공간에 정의된 "액션"을 요청하고 수행하는 과정도 필요합니다. 위의 레벨업 처리 과정을 예시로 들면, 클라이언트가 유저의 입력을 받으면, 서버에게 "몬스터 공격"이라는 "액션"을 요청하게 되고, 서버는 클라이언트의 요청에 따라 "몬스터 공격"이라는 "액션"을 수행하게 되는데요, 이렇듯 각 공간에 정의된 액션을 서로 요청하여 수행케 하는 것을 실행제어라고 합니다. 실행제어는 제작자의 의도에 따라 설정할 수 있습니다. 위에 말한 "액션"은 결국 스크립트에서는 "함수"라 할
[task] | code [pass] | ⏳ 미판정 [title] | InputService를 활용한 입력과 액션 [question] | InputService의 KeyDownEvent 이벤트 핸들러를 이용하여 키 입력 감지 시 Entity의 TransformComponent.Position을 수정하여 이동하는 스크립트를 작성해줘 [answer] | `InputService`의 `KeyDownEvent`는 유저가 키를 누르는 **순간**에 1회만 발생하며, 키를 계속 누르고 있을 때 연속적으로 발생하지 않습니다. 따라서 `KeyDownEvent`를 단독으로 사용하여 엔티티를 부드럽게 이동시키는 것은 불가능합니다. `KeyDownEvent`로 이동 상태를 `true`/`false`로 토글하거나 시작하는 것만 가능합니다. 키를 누르고 있는 동안 계속 이동하려면 `InputService`의 `KeyHoldEvent`(키를 계속 누르고 있을 때 매 프레임 발생)를 사용해야 합니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 모든 게임은 유저의 입력과 입력에 대한 피드백으로 게임이 진행됩니다. 메이플스토리 월드에서는 InputService를 통해 유저의 입력에 대한 액션을 제어할 수 있습니다. 이번 과정에서는 유저의 입력이 발생했을 때의 액션을 추가하는 방법을 알아보겠습니다. # 참고 가이드 [Event System](https://mod-developers.nexon.com/docs?postId=73) [Entity Event System](https://mod-developers.nexon.com/docs?postId=176
[task] | code [pass] | ⏳ 미판정 [title] | InputService를 활용한 입력과 액션 [question] | InputService의 KeyDownEvent 이벤트 핸들러와 _TimerService를 이용하여 키 입력 시 일정한 시간 후 특정 액션을 실행하는 스크립트를 작성해줘 [answer] | `InputService`의 `KeyDownEvent`는 클라이언트에서만 발생하므로, 해당 이벤트 핸들러는 `[client only]` 실행 공간으로 선언해야 합니다. 키 입력이 감지되면 `_TimerService:SetTimerOnce`를 호출하여 지정된 시간만큼 대기한 후 특정 액션을 실행하도록 구성할 수 있습니다. 아래는 S 키를 눌렀을 때 1초 후 "Ultimate Skill 사용" 액션을 실행하는 예제 스크립트입니다. ```lua Property: [None] number DelayTime = 1.0 Method: [ [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 모든 게임은 유저의 입력과 입력에 대한 피드백으로 게임이 진행됩니다. 메이플스토리 월드에서는 InputService를 통해 유저의 입력에 대한 액션을 제어할 수 있습니다. 이번 과정에서는 유저의 입력이 발생했을 때의 액션을 추가하는 방법을 알아보겠습니다. # 참고 가이드 [Event System](https://mod-developers.nexon.com/docs?postId=73) [Entity Event System](https://mod-developers.nexon.com/docs?postId=176