[task] | single_turn [pass] | ⏳ 미판정 [title] | 공격과 피격 [question] | PlayerActionEvent에서 ActionName이 "Attack"으로 매핑되어 있어야만 동작하는 이유는 무엇이며, 다른 키 입력으로 변경하려면 어디서 설정해야 하나요? [answer] | PlayerActionEvent에서 `ActionName`이 "Attack"으로 매핑되어야 동작하는 이유는, 이 이벤트가 플레이어의 특정 액션(행동)이 트리거되었을 때 해당 액션의 이름을 문자열로 전달하기 때문입니다. `HandlePlayerActionEvent` 핸들러 내부에서 `event.ActionName` 값을 확인하여 "Attack"과 일치할 경우에만 공격 함수(`NormalAttack()` 또는 `AttackNormal()`)를 호출하도록 조건문이 작성되어 있기 때문입니다. 다른 키 입력으로 변경하려면, **Player [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 1. **Workspace - BaseEnvironment - NativeScripts - Component - AttackComponent**를 선택합니다. 2. 콘텍스트 메뉴에서 **Extend**를 눌러 컴포넌트를 확장합니다. 확장한 컴포넌트의 이름을 **CharacterAttack**으로 변경합니다. 3. **CharacterAttack** 컴포넌트를 더블 클릭하여 스크립트 에디터를 엽니다. 4. **Method**에서 새로운 함수를 추가하고, 이름을 **NormalAttack** 으로 변경합니다. 5. `Att
[task] | two_turn [pass] | ⏳ 미판정 [title] | 프로퍼티 [question] | 프로퍼티 에디터에서 설정한 값이 스크립트 초깃값보다 우선순위가 높다는 점을 활용하여, 엔티티별로 다른 초깃값을 설정하는 절차와 주의할 사항을 알려주세요. [answer] | 프로퍼티 에디터에서 설정한 값은 스크립트 내의 프로퍼티 초깃값보다 우선순위가 높기 때문에, 이를 활용하여 동일한 스크립트가 적용된 여러 엔티티 각각에 서로 다른 초기 값을 부여할 수 있습니다. ### 설정 절차 1. **스크립트 프로퍼티 정의**: 먼저 스크립트의 `Property:` 블록에서 필요한 프로퍼티를 선언하고, 기본값(초깃값)을 설정합니다. 이 값은 프로퍼티 에디터에서 값을 지정하지 않은 엔티티들이 사용하게 됩니다. ```lua Property: [None] string DisplayName = "Defau [followup] | 프로퍼티 에디터에서 값을 설정하지 않은 엔티티와 설정한 엔티티가 혼재되어 있을 때, 스크립트에서 이 값을 안전하게 읽기 위한 로직을 작성해 주세요. [followup_answer] | 프로퍼티 에디터에서 값을 설정하지 않은 엔티티는 스크립트 `Property:` 블록에 정의된 초깃값을, 설정한 엔티티는 에디터에서 지정한 값을 사용하므로, 스크립트에서는 `self.프로퍼티명`을 통해 값을 읽기만 하면 자동으로 올바른 값이 반환됩니다. 따라서 "안전하게 읽기 위한 로직"은 단순히 프로퍼티에 접근하는 것이며, 추가적인 null 체크나 조건 분기는 필요하지 않습니다. 단, 프로퍼티 타입이 `nil`이 될 수 있는 `any` 타입이거나, 참조 대상이 존재하지 않을 수 있는 `Component`/`ComponentRef` [scores] | [judge_reason] | [source_doc] | 컴포넌트 가리키는 프로퍼티입니다. 프로퍼티 타입을 Component 선택 후, 버튼을 눌러 특정 컴포넌트를 타입으로 설정할 수 있습니다. Component와 ComponentRef의 기본 사용법은 동일하며, 참조 방식이 다릅니다. * Component: 컴포넌트를 직접 참조합니다. 다른 맵에 갔다 오면 참조가 끊어지고 프로퍼티를 사용할 수 없게 됩니다. * ComponentRef: 컴포넌트의 키 값을 가지고 있다가 실제 접근할 때 컴포넌트를 찾습니다. 다른 맵에 갔다 왔을 때 원래 가리키던 컴포넌트에 문제없이 접근할 수 있습니다.
[task] | code [pass] | ⏳ 미판정 [title] | 공격과 피격 [question] | AttackComponent를 확장하여 NormalAttack 메서드와 PlayerActionEvent 핸들러를 구현하고, ctrl 키 입력 시 Vector2(1, 1) 범위로 공격을 수행하는 CharacterAttack 스크립트를 작성해줘 [answer] | AttackComponent를 확장한 `CharacterAttack` 컴포넌트의 스크립트입니다. `NormalAttack` 메서드와 `PlayerActionEvent` 핸들러를 포함하여 `ctrl` 키(행동 이름 "Attack") 입력 시 `Vector2(1, 1)` 범위로 공격을 수행하도록 작성했습니다. ```lua Method: void NormalAttack() { local attackSize = Vector2(1, 1) local attackOffset = Vector2(0, 0) self:Attack(attac [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 1. **Workspace - BaseEnvironment - NativeScripts - Component - AttackComponent**를 선택합니다. 2. 콘텍스트 메뉴에서 **Extend**를 눌러 컴포넌트를 확장합니다. 확장한 컴포넌트의 이름을 **CharacterAttack**으로 변경합니다. 3. **CharacterAttack** 컴포넌트를 더블 클릭하여 스크립트 에디터를 엽니다. 4. **Method**에서 새로운 함수를 추가하고, 이름을 **NormalAttack** 으로 변경합니다. 5. `Att
[task] | single_turn [pass] | ⏳ 미판정 [title] | 공격과 피격 [question] | AttackComponent가 있는 엔티티가 HitComponent가 있는 엔티티를 공격했을 때, 추가 코드를 작성하지 않아도 기본 대미지 값 1이 적용되는 이유는 무엇인가요? [answer] | AttackComponent를 가진 엔티티가 HitComponent를 가진 엔티티를 공격하면, 별도의 추가 처리 코드가 존재하지 않기 때문에 시스템이 기본 동작을 수행합니다. 이 기본 동작에서는 대미지 스킨(피격 이펙트)을 재생할 때 기본값인 1을 사용하도록 정해져 있어, 추가 로직이 없으면 자동으로 1의 대미지 값이 적용됩니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | **AttackComponent**를 가진 엔티티가 **HitComponent**를 가진 엔티티를 공격하면, 별다른 추가 처리를 하지 않아도 엔티티는 피격 당하게 됩니다. 이 경우 추가 처리가 없기 때문에 기본값인 1로 대미지 스킨이 재생됩니다. 피격을 구현할 때는 공격량 그대로 대미지로 받을 수도 있지만, 공격과 다른 공식을 함께 사용해 피격량을 계산할 수도 있습니다. 예를 들어 100의 공격력으로 공격했지만 몬스터의 방어력이 높은 경우 절반의 공격만 유효하게 처리할 수 있습니다. 이번에는 아래 두 가지를 구현해 피격 당하는지를
[task] | instruction_following [pass] | ⏳ 미판정 [title] | 서버와 클라이언트 [question] | 함수의 실행 공간 설정에 따라 요청 주체와 수행 주체가 어떻게 달라지는지 표로 정리해서 답변하세요. [answer] | 메이플스토리 월드에서 함수의 실행 공간(Execution Space) 설정은 클라이언트와 서버 간에 함수를 누가 요청(Request)하고, 누가 실제 수행(Execute)하는지를 결정합니다. 제공된 문서에 따르면, 이 구조는 다음과 같이 정리할 수 있습니다. | 함수의 실행 공간 설정 | 요청 주체 (Who Requests) | 수행 주체 (Who Executes) | 설명 및 특징 | | :--- | :--- | :--- | :--- | | **서버 (Server)** | 서버 | 서버 | 서버 내에서만 호출 및 실행됩니다. 클 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 서버와 클라이언트 간 통신에는 데이터의 전달, 즉 동기화 외에도 공간에 정의된 "액션"을 요청하고 수행하는 과정도 필요합니다. 위의 레벨업 처리 과정을 예시로 들면, 클라이언트가 유저의 입력을 받으면, 서버에게 "몬스터 공격"이라는 "액션"을 요청하게 되고, 서버는 클라이언트의 요청에 따라 "몬스터 공격"이라는 "액션"을 수행하게 되는데요, 이렇듯 각 공간에 정의된 액션을 서로 요청하여 수행케 하는 것을 실행제어라고 합니다. 실행제어는 제작자의 의도에 따라 설정할 수 있습니다. 위에 말한 "액션"은 결국 스크립트에서는 "함수"라 할
[task] | instruction_following [pass] | ⏳ 미판정 [title] | 서버와 클라이언트 [question] | 동기화와 실행제어의 정의 차이를 구분하여, 각 항목에 대해 단계별 번호 목록으로 설명해 주세요. [answer] | 참고 문서에 기반하여 동기화와 실행제어의 정의 차이와 각 개념의 동작 방식을 단계별로 설명합니다. ### 1. 동기화 (Synchronization) 동기화는 서버와 클라이언트라는 별도 공간에 존재하는 프로퍼티 값이 자동으로 일치되도록 하는 **데이터 또는 상태 전달 방식**입니다. 1. **정의**: 서버와 클라이언트 각각의 독립적 공간에 존재하는 프로퍼티 값이 한쪽에서 변경되면, 다른 쪽도 자동으로 동일한 값으로 변경되는 방식을 의미합니다. 2. **동기화 대상**: 모든 프로퍼티가 자동으로 동기화되는 것은 아니며, 컴포 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 서버와 클라이언트가 어떻게 상호작용을 하는지를 알아보았으니, 이제 메이커에서 작성한 프로그램이 서버와 클라이언트에서 어떻게 돌아가는지 알아보도록 합니다. 제작자가 스크립트에서 선언한 프로퍼티와 함수는 별도의 설정을 하지 않는 한 기본적으로 서버와 클라이언트 두 개의 공간에 각각 독립적으로 생성됩니다. 이름은 같지만 서로 다른 공간에 존재하기 때문에 별도의 프로퍼티 또는 함수라 보는 것이 좋습니다. 기본적으로 함수의 호출과 프로퍼티의 값 참조 및 할당은 같은 공간 내에서만 이루어집니다. 예를 들어 A라는 프로퍼티에 값을 B라는 함
[task] | instruction_following [pass] | ⏳ 미판정 [title] | 프로퍼티 동기화 [question] | 동기화 설정 시 프로퍼티 타입별 가능 여부를 표로 정리해서 출력하세요. [answer] | 제공된 참고 문서에는 프로퍼티 타입별 동기화 가능 여부에 대한 표나 구체적인 목록이 포함되어 있지 않습니다. 문서에서는 `[Sync]` 속성을 사용하여 동기화를 설정하는 방법과 `OnSyncProperty` 이벤트 핸들러의 사용법에 대해만 설명하고 있으며, 어떤 타입이 동기화 가능한지에 대한 정보는 찾아볼 수 없습니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 서버, 클라이언트 간 데이터 전송 방식 중 하나인 프로퍼티 동기화에 대해 알아봅시다. # 동기화 메이플스토리 월드에서의 동기화는 서버, 클라이언트 간 데이터 전송 방식의 일종으로,각각의 공간에 존재하는 같은 이름의 프로퍼티를 같은 값으로 맞춰주는 것을 의미합니다. 기본적으로 프로퍼티는 선언과 동시에 서버, 클라이언트 각각의 공간에 생성되지만, 만일 프로퍼티 동기화가 되지 않는다면 이름은 같지만 서로 다른 값으로 설정할 수 있습니다. 제작자의 의도에 따라서 같은 프로퍼티의 값을 각 공간에 따라 다르게 할당
[task] | single_turn [pass] | ⏳ 미판정 [title] | 공격과 피격 [question] | 맵에 이미 배치해 둔 몬스터에게 확장된 HitComponent를 적용했는데 변경 사항이 반영되지 않는 이유는 무엇이며, 어떻게 해결해야 하나요? [answer] | 모델의 프로퍼티 변경 사항은 이미 맵에 배치된 엔티티에는 자동으로 적용되지 않습니다. 이는 엔진의 동작 원리상, 기존에 생성된 엔티티 인스턴스는 모델 변경 사항을 실시간으로 추적하지 않기 때문입니다. 해결 방법은 해당 맵에 배치된 기존 몬스터를 삭제한 뒤, 변경 사항이 적용된 모델로 다시 배치하는 것입니다. 참고로, 모델에서 기본 `HitComponent`를 삭제하고 확장한 `MonsterHit` 컴포넌트를 추가할 때는 반드시 기존 기본 `HitComponent`를 먼저 제거해야 합니다. 두 컴포넌트가 동시에 존재하면 오류가 발 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | **AttackComponent**를 가진 엔티티가 **HitComponent**를 가진 엔티티를 공격하면, 별다른 추가 처리를 하지 않아도 엔티티는 피격 당하게 됩니다. 이 경우 추가 처리가 없기 때문에 기본값인 1로 대미지 스킨이 재생됩니다. 피격을 구현할 때는 공격량 그대로 대미지로 받을 수도 있지만, 공격과 다른 공식을 함께 사용해 피격량을 계산할 수도 있습니다. 예를 들어 100의 공격력으로 공격했지만 몬스터의 방어력이 높은 경우 절반의 공격만 유효하게 처리할 수 있습니다. 이번에는 아래 두 가지를 구현해 피격 당하는지를
[task] | single_turn [pass] | ⏳ 미판정 [title] | 공격과 피격 [question] | 공격은 성공했는데 피격 대상이 안 잡히는 오류가 발생하는데, 충돌 그룹 설정이나 HitComponent 관련해서 점검해야 할 부분이 있을까요? [answer] | 공격이 성공했는데 피격 대상이 잡히지 않는 문제는 주로 **충돌 그룹(Collision Group)** 불일치와 **HitComponent** 설정 누락에서 발생합니다. 아래 항목들을 순서대로 점검해 주세요. ### 1. 공격 범위와 충돌 그룹 매칭 확인 `AttackComponent`의 `Attack()` 또는 `AttackFrom()` 함수를 호출할 때 마지막 인자로 전달하는 충돌 그룹이, 피격 대상 엔티티의 `HitComponent`에 설정된 충돌 그룹과 정확히 일치해야 합니다. * **공격 쪽:** `self:Atta [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 메이플스토리에서 플레이어는 모험가가 되어 메이플 세계를 탐험하고 몬스터를 만나 전투를 합니다. 전투 과정에서 다른 몬스터를 공격하거나 피격당합니다. 메이플스토리뿐만 아니라 다양한 게임에서 공격과 피격은 중요한 개념입니다. 이번 과정에서는 공격과 피격을 구현하는 방법을 학습합니다. ##### 참고 가이드/레퍼런스 [AttackComponent](/apiReference/Components/AttackComponent) [HitComponent](/apiReference/Components/HitComponent
[task] | instruction_following [pass] | ⏳ 미판정 [title] | 프로퍼티 동기화 [question] | 서버에서 클라이언트로만 동기화되는 이유를 3문장 이내로 설명하세요. [answer] | 서버는 단독으로 존재하므로 값이 변경되면 모든 클라이언트로 전송할 수 있지만, 클라이언트는 여러 개로 존재해 각자 다른 값으로 수정될 수 있습니다. 이 경우 서버 입장에서는 어떤 값으로 수정되어야 하는지 판단하기 어렵기 때문에 클라이언트에서 서버로의 동기화는 대체로 제한됩니다. 따라서 프로퍼티 동기화는 일반적으로 서버에서 클라이언트로 진행되며, 서버에서 변경된 값이 클라이언트로 전송되어 같은 값으로 맞춰집니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 서버, 클라이언트 간 데이터 전송 방식 중 하나인 프로퍼티 동기화에 대해 알아봅시다. # 동기화 메이플스토리 월드에서의 동기화는 서버, 클라이언트 간 데이터 전송 방식의 일종으로,각각의 공간에 존재하는 같은 이름의 프로퍼티를 같은 값으로 맞춰주는 것을 의미합니다. 기본적으로 프로퍼티는 선언과 동시에 서버, 클라이언트 각각의 공간에 생성되지만, 만일 프로퍼티 동기화가 되지 않는다면 이름은 같지만 서로 다른 값으로 설정할 수 있습니다. 제작자의 의도에 따라서 같은 프로퍼티의 값을 각 공간에 따라 다르게 할당
[task] | single_turn [pass] | ⏳ 미판정 [title] | 서버와 클라이언트 [question] | 게임의 주요 로직을 서버에서 처리하는 것이 서버 부하를 늘리는데도 권장되는 이유는 무엇인가요? [answer] | 게임의 주요 로직을 서버에서 처리하는 것이 서버 부하를 늘리더라도 권장되는 이유는 **보안(해킹 방지)** 때문입니다. 만약 클라이언트에서 주요 로직(예: 레벨업, 경험치 계산 등)을 처리하고 서버는 그 결과를 받아서 다른 클라이언트에게 동기화만 하는 구조로 만들면 서버의 부하를 줄일 수는 있습니다. 하지만 이 경우 유저가 자신의 클라이언트를 해킹하여 조작된 결과(예: 몬스터 사냥 시 경험치 획득량 증가)를 서버로 전송할 경우, 서버는 그 조작된 결과를 그대로 받아들이게 됩니다. 결국 모든 유저가 이용 중인 게임 환경이 해킹으로 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 멀티 플레이를 제공하는 게임의 경우 각 게임의 특성에 따라 사용되는 통신 모델들이 다양합니다. MapleStory World는 다양한 통신 모델 중에서도 서버 - 클라이언트 모델을 사용하고 있습니다. 이번 과정에서는 MapleStory World의 통신 모델인 서버와 클라이언트의 개념과 구조, 그리고 각 공간 간의 정보전달 방법에 대해 알아보도록 하겠습니다. # 서버와 클라이언트 클라이언트는 게임을 플레이하는 유저들의 모바일이나 PC, 또는 해당 기기에서 개별적으로 돌아가는 프로그램을 의미합니다.주로 유저의
[task] | single_turn [pass] | ⏳ 미판정 [title] | 서버와 클라이언트 [question] | 클라이언트가 다른 클라이언트와 직접 통신을 시도할 경우 서버-클라이언트 모델에서 어떤 문제가 발생하나요? [answer] | 서버-클라이언트 모델에서는 클라이언트가 다른 클라이언트와 직접 통신하는 것이 허용되지 않으며, 오직 서버와만 정보를 주고받습니다. 따라서 클라이언트가 다른 클라이언트와 직접 통신을 시도할 경우 다음과 같은 문제가 발생합니다: 1. **통신 경로 위반**: MapleStory World의 통신 구조상 클라이언트는 서버를 경유하지 않고 다른 클라이언트와 직접 데이터를 교환할 수 없습니다. 모든 정보 전달은 반드시 서버를 통해 이루어져야 합니다. 2. **동기화 실패**: 서버를 거치지 않은 직접 통신은 서버의 게임 상태 관리와 동기 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 멀티 플레이를 제공하는 게임의 경우 각 게임의 특성에 따라 사용되는 통신 모델들이 다양합니다. MapleStory World는 다양한 통신 모델 중에서도 서버 - 클라이언트 모델을 사용하고 있습니다. 이번 과정에서는 MapleStory World의 통신 모델인 서버와 클라이언트의 개념과 구조, 그리고 각 공간 간의 정보전달 방법에 대해 알아보도록 하겠습니다. # 서버와 클라이언트 클라이언트는 게임을 플레이하는 유저들의 모바일이나 PC, 또는 해당 기기에서 개별적으로 돌아가는 프로그램을 의미합니다.주로 유저의
[task] | single_turn [pass] | ⏳ 미판정 [title] | 서버와 클라이언트 [question] | 클라이언트에서 몬스터 처치 시 경험치 증가 로직을 구현하면 왜 해킹에 취약한 구조가 되는지 설명해 주세요. [answer] | 서버와 클라이언트 모델에서 클라이언트는 유저의 입력을 처리하고 서버로부터 받은 정보를 화면에 출력하는 중계자 역할에 집중해야 합니다. 반면 게임의 핵심 로직과 시스템은 서버에서 처리해야 합니다. 만약 몬스터 처치 시 경험치 증가와 같은 주요 로직을 클라이언트에서 구현하고, 그 결과를 서버에 보내서 다른 클라이언트에 동기화하는 구조로 만들면 해킹에 취약해집니다. 그 이유는 다음과 같습니다. 1. **조작된 결과의 신뢰 문제**: 클라이언트에서 로직이 실행되면, 유저가 자신의 클라이언트 프로그램을 해킹(조작)할 수 있습니다. 예를 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 멀티 플레이를 제공하는 게임의 경우 각 게임의 특성에 따라 사용되는 통신 모델들이 다양합니다. MapleStory World는 다양한 통신 모델 중에서도 서버 - 클라이언트 모델을 사용하고 있습니다. 이번 과정에서는 MapleStory World의 통신 모델인 서버와 클라이언트의 개념과 구조, 그리고 각 공간 간의 정보전달 방법에 대해 알아보도록 하겠습니다. # 서버와 클라이언트 클라이언트는 게임을 플레이하는 유저들의 모바일이나 PC, 또는 해당 기기에서 개별적으로 돌아가는 프로그램을 의미합니다.주로 유저의
[task] | single_turn [pass] | ⏳ 미판정 [title] | 공격과 피격 [question] | OnHit() 함수에서 __base:OnHit() 호출 시 damage 인자로 20을 전달하면, 실제 공격량이 100이어도 몬스터가 받는 피격량이 어떻게 변하게 되나요? [answer] | `OnHit()` 함수에서 `__base:OnHit()` 호출 시 damage 인자로 20을 전달하면, 실제 공격량이 100이더라도 몬스터가 최종적으로 받는 피격량(대미지)은 **20**이 됩니다. 기본적으로 `AttackComponent`가 `HitComponent`를 가진 엔티티를 공격하면 공격량 그대로 대미지로 적용되지만, `OnHit()` 함수를 오버라이드하여 `__base:OnHit()`에 고정된 숫자(이 경우 20)를 damage 인자로 전달하면, 기본 동작에서 계산되었을 공격량(100)을 무시하고 직접 전달한 값(20 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | **AttackComponent**를 가진 엔티티가 **HitComponent**를 가진 엔티티를 공격하면, 별다른 추가 처리를 하지 않아도 엔티티는 피격 당하게 됩니다. 이 경우 추가 처리가 없기 때문에 기본값인 1로 대미지 스킨이 재생됩니다. 피격을 구현할 때는 공격량 그대로 대미지로 받을 수도 있지만, 공격과 다른 공식을 함께 사용해 피격량을 계산할 수도 있습니다. 예를 들어 100의 공격력으로 공격했지만 몬스터의 방어력이 높은 경우 절반의 공격만 유효하게 처리할 수 있습니다. 이번에는 아래 두 가지를 구현해 피격 당하는지를
[task] | single_turn [pass] | ⏳ 미판정 [title] | 공격과 피격 [question] | 기본 HitComponent를 모델에서 삭제하지 않고 확장한 MonsterHit 컴포넌트를 함께 사용하면 어떤 문제가 발생하며, 이 둘의 차이는 무엇인가요? [answer] | 기본 **HitComponent**를 모델에서 삭제하지 않고 확장한 **MonsterHit** 컴포넌트를 함께 사용하면 **오류가 발생**합니다. 따라서 확장 컴포넌트를 적용하기 전에는 반드시 기본 HitComponent를 모델에서 제거해야 합니다. 두 컴포넌트의 차이는 다음과 같습니다. 1. **기본 HitComponent**: * 별다른 추가 처리를 하지 않으면, 엔티티가 피격될 때 기본값인 **대미지 1**이 적용됩니다. * 피격량 계산 시 공격량 그대로 대미지로 받거나, 방어력 등 다른 공식을 사용 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | **AttackComponent**를 가진 엔티티가 **HitComponent**를 가진 엔티티를 공격하면, 별다른 추가 처리를 하지 않아도 엔티티는 피격 당하게 됩니다. 이 경우 추가 처리가 없기 때문에 기본값인 1로 대미지 스킨이 재생됩니다. 피격을 구현할 때는 공격량 그대로 대미지로 받을 수도 있지만, 공격과 다른 공식을 함께 사용해 피격량을 계산할 수도 있습니다. 예를 들어 100의 공격력으로 공격했지만 몬스터의 방어력이 높은 경우 절반의 공격만 유효하게 처리할 수 있습니다. 이번에는 아래 두 가지를 구현해 피격 당하는지를
[task] | two_turn [pass] | ⏳ 미판정 [title] | 공격과 피격 [question] | `IsAttackTarget()` 함수의 기본 동작 방식과 공격 실패 시 처리 로직에 대해 알려주세요. [answer] | `IsAttackTarget()` 함수는 `AttackComponent`에 정의되며, 충돌한 엔티티가 공격 대상인지 판단하는 역할을 합니다. 이 함수는 기본적으로 공격자가 자신의 공격 박스에 포함되지 않도록 처리되어 있어, 공격자가 스스로를 타격하는 상황을 방지합니다. 기본 동작 방식과 공격 실패 시 처리 로직은 다음과 같습니다. 1. **기본 동작**: * `defender` 매개변수로 충돌한 엔티티 정보를 전달받습니다. * 해당 엔티티가 타격 가능한 적대적 대상인지 확인합니다. * **`tr [followup] | 공격자가 자신의 공격 박스에 포함되지 않도록 처리된다는 구체적 의미와, `IsAttackTarget()`이 `false`를 반환할 때 `HitComponent`의 `IsHitTarget()` 호출이 생략되는 이유를 설명해 주세요. [followup_answer] | 참고 문서에 근거하여 두 가지 질문에 대해 설명하겠습니다. ### 1. 공격자가 자신의 공격 박스에 포함되지 않도록 처리된다는 구체적 의미 `IsAttackTarget()` 함수는 기본적으로 **공격자 본인이 공격 박스(Attack Box) 안에 들어와도 타격 대상이 되지 않도록** 내부적으로 처리되어 있습니다. * **의미**: 공격자가 자신의 공격 범위에 다른 엔티티와 함께 자신의 엔티티도 감지하더라도, `IsAttackTarget()`은 공격자 본인에게는 `false`를 반환합니다. * **결과**: 이로 인해 공 [scores] | [judge_reason] | [source_doc] | 크리에이터의 공격 제작 방식에 따라 `IsAttackTarget()` 함수를 활용해 피격 대상을 선정할 수 있습니다. `IsAttackTarget()` 함수는 공격자가 공격 박스에 포함되지 않도록 처리되어 있으므로, 공격자가 타격을 받지 않게 처리할 필요가 없습니다. **Entity** 타입의 `defender` 매개변수는 충돌한 엔티티가 공격 대상인지 판단할 수 있는 엔티티 정보를 받습니다. 함수의 리턴값이 **false**면 **AttackComponent**에서 적합한 공격 대상으로 판별하고 이후 판단을 **HitCompone
[task] | single_turn [pass] | ⏳ 미판정 [title] | 몬스터를 스폰해 보자 [question] | 5초 주기를 유지하되, 몬스터 수량이 부족할 때만 스폰되도록 논리를 변경했는데도 불구하고 몬스터가 계속 중복 스폰되는 오류의 원인은 무엇일까요? [answer] | 제공된 문서의 코드와 논리를 분석했을 때, "몬스터가 계속 중복 스폰되는" 현상은 **`self.MonsterArray`에 스폰된 몬스터 엔티티를 저장하는 로직은 있지만, 몬스터가 사살되어 사라졌을 때 해당 배열에서 해당 몬스터를 제거하는 로직이 없기 때문**입니다. 구체적인 원인과 해결 방법은 다음과 같습니다. ### 1. 오류 원인 분석 `OnUpdate()` 함수 내에서 스폰 개수를 계산하는 로직은 다음과 같습니다. ```lua local curMonsterCnt = self:GetCurMonsterCount() local [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 이번에는 5초마다 한 마리씩 스폰하는 것이 아니라, 5초마다 현재 몬스터 수량을 체크하여 최대 몬스터 수량보다 부족한 만큼 생성하도록 수정해 봅시다. 1. **MonsterSpawn**의 `GetRandomPosition()` 함수에 매개 변수를 하나 추가합니다. 2. 매개 변수 타입은 **number**로, 이름은 **spawnCount**로 설정하고, 리턴 타입을 **table**로 변경합니다. 함수는 다음과 같이 수정합니다. ```lua table GetRandomPosition(nu
[task] | two_turn [pass] | ⏳ 미판정 [title] | 공격과 피격 [question] | `IsHitTarget()`과 `OnHit()` 함수에서 최종 대미지를 계산하는 구체적인 코드 구조를 알려주세요. [answer] | 제공된 문서에 따르면 `IsHitTarget()`과 `OnHit()` 함수에서 최종 대미지를 계산하는 구체적인 코드 구조(함수 본문 구현 예시)는 명시되어 있지 않습니다. 문서가 설명하는 대미지 계산 흐름과 함수의 역할은 다음과 같습니다. 1. **공격자의 `AttackComponent`**: `CalcDamage()` 함수를 통해 공격 대미지 값을 반환합니다. 2. **피격자의 `HitComponent`**: * `IsHitTarget()`: 피격 여부를 판단합니다. **true**를 반환해야 대미지가 적용됩니다 [followup] | `CalcDamage()`에서 반환된 값을 `OnHit()`에서 매개변수로 받아 방어자의 회피율을 적용하는 `OnHit()` 함수의 구현 예제를 작성해 주세요. [followup_answer] | 제공된 문서에는 `OnHit()` 함수에서 `CalcDamage()`의 값을 매개변수로 받아 회피율을 적용하는 구체적인 구현 코드(함수 본문)가 명시되어 있지 않습니다. 문서가 설명하는 `OnHit()` 함수의 동작 원리는 다음과 같습니다. 1. 피격자의 `HitComponent`의 `OnHit()` 함수는 공격자의 `AttackComponent`의 `CalcDamage()` 함수가 반환한 값을 **매개변수**로 전달받습니다. 2. 전달받은 값은 그대로 사용할 수도 있고, `OnHit()` 함수 내부에서 추가 계산을 거쳐 * [scores] | [judge_reason] | [source_doc] | 크리에이터의 공격 제작 방식에 따라 `IsAttackTarget()` 함수를 활용해 피격 대상을 선정할 수 있습니다. `IsAttackTarget()` 함수는 공격자가 공격 박스에 포함되지 않도록 처리되어 있으므로, 공격자가 타격을 받지 않게 처리할 필요가 없습니다. **Entity** 타입의 `defender` 매개변수는 충돌한 엔티티가 공격 대상인지 판단할 수 있는 엔티티 정보를 받습니다. 함수의 리턴값이 **false**면 **AttackComponent**에서 적합한 공격 대상으로 판별하고 이후 판단을 **HitCompone
[task] | two_turn [pass] | ⏳ 미판정 [title] | 공격과 피격 [question] | 몬스터가 100번 공격을 당했을 때 특정 이벤트를 처리하기 위한 `HitEvent` 활용 방법을 알려주세요. [answer] | `HitEvent`는 엔티티가 공격을 받아 `HitComponent`의 `OnHit()` 함수가 호출될 때 발생하며, 피격 횟수를 추적하여 특정 조건(예: 100회 피격)에서 추가 로직을 실행하는 데 활용됩니다. 문서에 명시된 `HitEvent` 매개변수(`AttackCenter`, `AttackerEntity`, `Damages`, `Extra`, `FeedbackAction`, `IsCritical`, `TotalDamage`)에는 피격 횟수를 나타내는 값이 포함되어 있지 않으므로, 스크립트 내부에 별도의 변수를 선언하여 매 [followup] | `OnHit()` 함수에서 `HitEvent` 발생 횟수를 카운팅하여 100번째 피격 시 몬스터의 크기를 변경하는 `OnHit()` 및 이벤트 핸들러 코드 예제를 작성해 주세요. [followup_answer] | `OnHit()` 함수는 피격자의 `HitComponent`에 구현되며, 이 함수가 호출될 때 `HitEvent`가 발생하므로 `OnHit()` 내부에서 직접 이벤트 발생 횟수를 카운팅할 수 있습니다. 참고 문서의 예제에서 몬스터의 크기 변경은 `HitComponent`의 `BoxSize` 프로퍼티를 수정하여 이루어집니다. 따라서 `OnHit()` 함수 내부에서 피격 횟수를 추적하고, 100번째 피격 시 초기 크기의 특정 배율로 `BoxSize`를 변경하는 로직을 구현할 수 있습니다. 아래는 몬스터 엔티티에 적용할 `HitCom [scores] | [judge_reason] | [source_doc] | 크리에이터의 공격 제작 방식에 따라 `IsAttackTarget()` 함수를 활용해 피격 대상을 선정할 수 있습니다. `IsAttackTarget()` 함수는 공격자가 공격 박스에 포함되지 않도록 처리되어 있으므로, 공격자가 타격을 받지 않게 처리할 필요가 없습니다. **Entity** 타입의 `defender` 매개변수는 충돌한 엔티티가 공격 대상인지 판단할 수 있는 엔티티 정보를 받습니다. 함수의 리턴값이 **false**면 **AttackComponent**에서 적합한 공격 대상으로 판별하고 이후 판단을 **HitCompone
[task] | single_turn [pass] | ⏳ 미판정 [title] | 공격과 피격 [question] | HitEvent가 발생할 때마다 몬스터의 크기가 1.3배씩 커지도록 구현할 때, TransformComponent의 Scale 값을 어떻게 계산하고 적용해야 하나요? [answer] | HitEvent(피격)가 발생할 때마다 몬스터의 크기를 1.3배씩 키우려면, `OnHit` 함수 내에서 현재 `TransformComponent`의 `Scale` 값을 가져와 1.3을 곱한 후 다시 `Scale` 프로퍼티에 할당해야 합니다. 구체적인 계산 및 적용 방법은 다음과 같습니다. 1. **현재 Scale 값 조회**: `self.Entity.TransformComponent.Scale`을 통해 현재 엔티티의 스케일 값을 변수에 저장합니다. 2. **신규 Scale 계산**: 조회한 값에 1.3을 곱하여 새로운 스케일 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | **AttackComponent**를 가진 엔티티가 **HitComponent**를 가진 엔티티를 공격하면, 별다른 추가 처리를 하지 않아도 엔티티는 피격 당하게 됩니다. 이 경우 추가 처리가 없기 때문에 기본값인 1로 대미지 스킨이 재생됩니다. 피격을 구현할 때는 공격량 그대로 대미지로 받을 수도 있지만, 공격과 다른 공식을 함께 사용해 피격량을 계산할 수도 있습니다. 예를 들어 100의 공격력으로 공격했지만 몬스터의 방어력이 높은 경우 절반의 공격만 유효하게 처리할 수 있습니다. 이번에는 아래 두 가지를 구현해 피격 당하는지를
[task] | code [pass] | ⏳ 미판정 [title] | 공격과 피격 [question] | AttackComponent의 AttackFast() 함수를 사용해 불필요한 객체 생성 없이 캐릭터 위치 기준 공격을 실행하고, HitComponent가 있는 엔티티의 충돌 그룹을 확인해 적군만 피격 처리하도록 필터링하는 스크립트를 작성해줘 [answer] | `AttackFast()` 함수는 캐릭터 위치를 기준으로 공격 범위를 설정하되, 반환 값이 없어 불필요한 table 객체 생성을 줄일 수 있습니다. 적군만 피격 처리하도록 필터링하려면 `AttackFast()` 호출 시 충돌 그룹으로 `CollisionGroups.Monster`를 지정해야 합니다. 피격 대상 엔티티에는 반드시 `HitComponent`가 장착되어 있어야 하며, 이 컴포넌트의 충돌 그룹이 공격 시 지정된 그룹과 일치할 때만 피격 처리가 됩니다. 아래 스크립트는 `AttackFast()`를 사용하여 공격을 실행하고, [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 메이플스토리에서 플레이어는 모험가가 되어 메이플 세계를 탐험하고 몬스터를 만나 전투를 합니다. 전투 과정에서 다른 몬스터를 공격하거나 피격당합니다. 메이플스토리뿐만 아니라 다양한 게임에서 공격과 피격은 중요한 개념입니다. 이번 과정에서는 공격과 피격을 구현하는 방법을 학습합니다. ##### 참고 가이드/레퍼런스 [AttackComponent](/apiReference/Components/AttackComponent) [HitComponent](/apiReference/Components/HitComponent
[task] | two_turn [pass] | ⏳ 미판정 [title] | 공격과 피격 [question] | HitComponent를 통한 피격 처리 과정에서 최종 대미지가 결정되는 메커니즘과 CalcDamage(), CalcCritical() 함수의 역할을 자세히 설명해 주세요. [answer] | ## HitComponent를 통한 피격 처리와 대미지 결정 메커니즘 메이플스토리 월드에서 엔티티가 피격 대상이 되기 위해서는 해당 엔티티에 `HitComponent`가 반드시 장착되어 있어야 합니다. `HitComponent`는 엔티티의 충돌체 모양, 크기, 그리고 충돌체 그룹을 설정하는 역할을 담당합니다. 공격이 가해질 때 `AttackComponent`의 함수(`Attack()`, `AttackFrom()`, `AttackFast()`)가 활성화되어 공격 범위가 정의됩니다. 이 공격 범위 안에 `HitComponent`를 [followup] | GetCriticalDamageRate()를 활용해 크리티컬 대미지 배율을 계산하는 코드 예시와, HitComponent의 충돌체 그룹 설정이 피격 대상 판단에 어떻게 영향을 미치는지 알려 주세요. [followup_answer] | ## GetCriticalDamageRate()를 활용한 크리티컬 대미지 배율 계산 크리티컬 공격이 발생했을 때 적용될 배율은 `GetCriticalDamageRate()` 함수의 반환 값으로 결정됩니다. 이 함수는 `number` 타입의 값을 반환하며, `CalcCritical()`이 `true`를 반환하는 경우 `CalcDamage()`에서 산출된 기본 대미지에 이 배율이 곱해져 최종 대미지가 계산됩니다. 아래는 크리티컬 대미지 배율을 1.5배로 설정하고, 30% 확률로 크리티컬이 발생하도록 구현한 mLua 코드 예시입니다. [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 메이플스토리에서 플레이어는 모험가가 되어 메이플 세계를 탐험하고 몬스터를 만나 전투를 합니다. 전투 과정에서 다른 몬스터를 공격하거나 피격당합니다. 메이플스토리뿐만 아니라 다양한 게임에서 공격과 피격은 중요한 개념입니다. 이번 과정에서는 공격과 피격을 구현하는 방법을 학습합니다. ##### 참고 가이드/레퍼런스 [AttackComponent](/apiReference/Components/AttackComponent) [HitComponent](/apiReference/Components/HitComponent
[task] | instruction_following [pass] | ⏳ 미판정 [title] | 프로퍼티 동기화 [question] | OnSyncProperty 활용 예시를 코드만 출력하고 설명은 주석으로 작성하세요. [answer] | ```lua Property: [Sync] number HP = 100 [Sync] number MP = 100 Method: [client only] void OnSyncProperty(string name, any value) { -- 프로퍼티 이름이 "HP"인 경우 if name == "HP" then -- 서버에서 동기화된 값과 현재 클라이언트의 HP 값이 일치하는지 확인 if self.HP == value then -- 값이 일치하면 동기화가 완료되었음을 로 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 서버, 클라이언트 간 데이터 전송 방식 중 하나인 프로퍼티 동기화에 대해 알아봅시다. # 동기화 메이플스토리 월드에서의 동기화는 서버, 클라이언트 간 데이터 전송 방식의 일종으로,각각의 공간에 존재하는 같은 이름의 프로퍼티를 같은 값으로 맞춰주는 것을 의미합니다. 기본적으로 프로퍼티는 선언과 동시에 서버, 클라이언트 각각의 공간에 생성되지만, 만일 프로퍼티 동기화가 되지 않는다면 이름은 같지만 서로 다른 값으로 설정할 수 있습니다. 제작자의 의도에 따라서 같은 프로퍼티의 값을 각 공간에 따라 다르게 할당
[task] | single_turn [pass] | ⏳ 미판정 [title] | 서버와 클라이언트 [question] | 서버와 클라이언트 간에 단순히 데이터 상태를 맞추는 것 외에, 특정 상황에서의 행동을 전달하기 위한 실행제어 방식이 무엇인지 소개해 주세요. [answer] | 참고 문서에는 실행제어에 대한 정의만 제시되어 있고, 실행제어를 구현하는 구체적인 API, 함수 이름, 또는 코드 예제는 포함되어 있지 않습니다. 문서에 따르면 실행제어는 데이터 또는 상태를 전달하는 방식인 '동기화'와 구별되는 개념으로, 특정 상황에 발생해야 할 행위나 행동들을 서버와 클라이언트 간에 전달하는 방식입니다. 하지만 이를 어떻게 사용하는지 구체적인 방법은 이 문서에 나와 있지 않습니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 서버와 클라이언트가 어떻게 상호작용을 하는지를 알아보았으니, 이제 메이커에서 작성한 프로그램이 서버와 클라이언트에서 어떻게 돌아가는지 알아보도록 합니다. 제작자가 스크립트에서 선언한 프로퍼티와 함수는 별도의 설정을 하지 않는 한 기본적으로 서버와 클라이언트 두 개의 공간에 각각 독립적으로 생성됩니다. 이름은 같지만 서로 다른 공간에 존재하기 때문에 별도의 프로퍼티 또는 함수라 보는 것이 좋습니다. 기본적으로 함수의 호출과 프로퍼티의 값 참조 및 할당은 같은 공간 내에서만 이루어집니다. 예를 들어 A라는 프로퍼티에 값을 B라는 함
[task] | two_turn [pass] | ⏳ 미판정 [title] | 공격과 피격 [question] | 공격은 성공했지만 실제 타격 결과가 달라지는 다양한 경우의 수(회피, 최소 타격 등)를 처리하기 위해 AttackComponent와 HitComponent를 유기적으로 구성하는 방법은 무엇인가요? [answer] | 공격이 성공했으나 실제 타격 결과가 회피나 최소 타격 등으로 달라지는 다양한 경우의 수를 처리하려면, 공격을 담당하는 `AttackComponent`와 피격을 담당하는 `HitComponent`를 각각 구현하여 유기적으로 연결해야 합니다. 기본적으로 `AttackComponent`의 함수(`Attack`, `AttackFrom`, `AttackFast`)를 사용하여 공격 범위를 설정하면, 해당 범위 내에 `HitComponent`가 장착된 엔티티가 존재할 때 피격 처리 대상이 됩니다. `HitComponent`는 엔티티의 충돌체 [followup] | 엔티티의 상태 제어를 활용해 공격 회피나 피격 무적 상태를 구현하는 구체적인 로직과 코드 예시를 보여주세요. [followup_answer] | 제공된 참고 문서에는 엔티티의 상태 제어를 활용한 공격 회피나 피격 무적 상태를 구현하는 구체적인 로직이나 코드 예시가 포함되어 있지 않습니다. 문서에는 "엔티티의 상태 제어하기"라는 참고 가이드 링크가 제시되어 있을 뿐, 실제 상태 제어 API(예: 무적 상태 설정, 회피 처리 함수 등)나 `HitComponent`/`AttackComponent`와의 연동 코드에 대한 설명은 없습니다. 따라서 문서 근거만으로 해당 기능을 구현하는 코드를 작성할 수 없습니다. 참고로, 문서에 명시된 공격과 피격의 기본 구조는 다음과 같습니다: [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 메이플스토리에서 플레이어는 모험가가 되어 메이플 세계를 탐험하고 몬스터를 만나 전투를 합니다. 전투 과정에서 다른 몬스터를 공격하거나 피격당합니다. 메이플스토리뿐만 아니라 다양한 게임에서 공격과 피격은 중요한 개념입니다. 이번 과정에서는 공격과 피격을 구현하는 방법을 학습합니다. ##### 참고 가이드/레퍼런스 [AttackComponent](/apiReference/Components/AttackComponent) [HitComponent](/apiReference/Components/HitComponent
[task] | two_turn [pass] | ⏳ 미판정 [title] | 공격과 피격 [question] | 맵에 이미 배치된 몬스터에 모델 프로퍼티 변경 사항을 적용하려면 어떤 작업이 필요한가요? [answer] | 맵에 이미 배치된 몬스터에는 모델 프로퍼티 변경 사항이 자동으로 적용되지 않습니다. 변경 사항을 적용하려면 배치된 몬스터를 삭제한 뒤, 수정된 모델을 다시 배치해야 합니다. [followup] | 모델에서 기본 HitComponent를 제거하고 확장한 MonsterHit를 추가한 후, 기존에 배치된 몬스터를 삭제하고 재배치하는 과정과 그 이유를 설명해 주세요. [followup_answer] | 모델에서 기본 HitComponent를 제거하고 확장한 MonsterHit를 추가한 후, 기존에 배치된 몬스터를 삭제하고 재배치해야 하는 이유는 다음과 같습니다. **1. 기본 HitComponent 제거 및 MonsterHit 추가 과정** 1. **컴포넌트 확장**: `Workspace - BaseEnvironment - NativeScripts - HitComponent`를 선택한 뒤 콘텍스트 메뉴에서 **Extend**를 선택해 컴포넌트를 확장합니다. 2. **이름 변경**: 확장한 컴포넌트의 이름을 `MonsterH [scores] | [judge_reason] | [source_doc] | **AttackComponent**를 가진 엔티티가 **HitComponent**를 가진 엔티티를 공격하면, 별다른 추가 처리를 하지 않아도 엔티티는 피격 당하게 됩니다. 이 경우 추가 처리가 없기 때문에 기본값인 1로 대미지 스킨이 재생됩니다. 피격을 구현할 때는 공격량 그대로 대미지로 받을 수도 있지만, 공격과 다른 공식을 함께 사용해 피격량을 계산할 수도 있습니다. 예를 들어 100의 공격력으로 공격했지만 몬스터의 방어력이 높은 경우 절반의 공격만 유효하게 처리할 수 있습니다. 이번에는 아래 두 가지를 구현해 피격 당하는지를
[task] | single_turn [pass] | ⏳ 미판정 [title] | 서버와 클라이언트 [question] | 메이플스토리 월드에서 서버와 클라이언트 간의 정보 전달 방식이 일반적 P2P 방식과 어떻게 다른가요? [answer] | 메이플스토리 월드(MapleStory Worlds)는 일반적 P2P(Peer-to-Peer, 대등한 통신) 방식과 달리 **서버-클라이언트 모델**을 사용합니다. 두 방식의 정보 전달 구조는 다음과 같이 명확히 다릅니다. ### 1. 통신 구조의 차이 * **P2P 방식**: 클라이언트(유저 기기)끼리 직접 통신하며 정보를 주고받습니다. * **메이플스토리 월드**: 클라이언트는 **다른 클라이언트와 직접 통신하지 않습니다.** 모든 클라이언트는 오직 **서버와만** 정보를 주고받습니다. ### 2. 정보 흐름과 처리 방 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 멀티 플레이를 제공하는 게임의 경우 각 게임의 특성에 따라 사용되는 통신 모델들이 다양합니다. MapleStory World는 다양한 통신 모델 중에서도 서버 - 클라이언트 모델을 사용하고 있습니다. 이번 과정에서는 MapleStory World의 통신 모델인 서버와 클라이언트의 개념과 구조, 그리고 각 공간 간의 정보전달 방법에 대해 알아보도록 하겠습니다. # 서버와 클라이언트 클라이언트는 게임을 플레이하는 유저들의 모바일이나 PC, 또는 해당 기기에서 개별적으로 돌아가는 프로그램을 의미합니다.주로 유저의
[task] | single_turn [pass] | ⏳ 미판정 [title] | 서버와 클라이언트 [question] | 서버와 클라이언트 사이에서 데이터 동기화와 실행제어는 어떤 차이가 있나요? [answer] | 서버와 클라이언트 사이에서 데이터 동기화와 실행제어는 다음과 같은 차이가 있습니다. **1. 데이터 동기화** * **정의:** 서버와 클라이언트 간에 **데이터를 전달**하는 과정입니다. * **역할:** 두 환경 간에 상태나 값을 일치시키거나 공유하는 데 중점을 둡니다. **2. 실행제어** * **정의:** 공간에 정의된 **"액션"(스크립트 함수)을 요청하고 수행**하는 과정입니다. * **역할:** 클라이언트에서 유저 입력을 받아 서버에게 특정 액션(예: "몬스터 공격")을 요청하고, 서버가 이를 수행하거 [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 서버와 클라이언트 간 통신에는 데이터의 전달, 즉 동기화 외에도 공간에 정의된 "액션"을 요청하고 수행하는 과정도 필요합니다. 위의 레벨업 처리 과정을 예시로 들면, 클라이언트가 유저의 입력을 받으면, 서버에게 "몬스터 공격"이라는 "액션"을 요청하게 되고, 서버는 클라이언트의 요청에 따라 "몬스터 공격"이라는 "액션"을 수행하게 되는데요, 이렇듯 각 공간에 정의된 액션을 서로 요청하여 수행케 하는 것을 실행제어라고 합니다. 실행제어는 제작자의 의도에 따라 설정할 수 있습니다. 위에 말한 "액션"은 결국 스크립트에서는 "함수"라 할
[task] | code [pass] | ⏳ 미판정 [title] | 공격과 피격 [question] | AttackComponent의 AttackFrom() 함수를 활용해 월드 좌표를 기준으로 사각형 공격 범위를 설정하고, HitComponent가 있는 엔티티가 그 범위에 들어왔을 때 피격 처리를 수행하는 스크립트를 작성해줘 [answer] | `AttackFrom()` 함수는 월드 좌표를 기준으로 사각형 공격 범위를 설정할 때 사용됩니다. `Attack()` 함수가 캐릭터의 현재 위치를 기준으로 범위를 설정하는 것과 달리, `AttackFrom()`은 특정 좌표 위치에서 공격이 발생하도록 지정할 수 있어 더 정밀한 공격 범위 제어가 가능합니다. 공격 범위에 `HitComponent`를 가진 엔티티가 들어오면 자동으로 피격 처리가 수행되며, 대미지 및 크리티컬 관련 로직은 `CalcDamage()`, `CalcCritical()`, `GetCriticalDamageRat [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | # 학습 과정 소개 메이플스토리에서 플레이어는 모험가가 되어 메이플 세계를 탐험하고 몬스터를 만나 전투를 합니다. 전투 과정에서 다른 몬스터를 공격하거나 피격당합니다. 메이플스토리뿐만 아니라 다양한 게임에서 공격과 피격은 중요한 개념입니다. 이번 과정에서는 공격과 피격을 구현하는 방법을 학습합니다. ##### 참고 가이드/레퍼런스 [AttackComponent](/apiReference/Components/AttackComponent) [HitComponent](/apiReference/Components/HitComponent
[task] | instruction_following [pass] | ⏳ 미판정 [title] | 프로퍼티 동기화 [question] | Sync를 None으로 변경했을 때 발생하는 결과를 단계별 번호 목록으로 나열하세요. [answer] | Sync를 None으로 변경했을 때 발생하는 결과는 다음과 같습니다. 1. 해당 프로퍼티의 동기화가 이루어지지 않습니다. 2. 프로퍼티 값이 공간별로 따로 관리되게 됩니다. [followup] | [followup_answer] | [scores] | [judge_reason] | [source_doc] | 동기화 설정 방법은 매우 간단합니다. 스크립트 에디터를 한 번이라도 열어서 프로퍼티를 추가해봤다면 프로퍼티 상단에 Sync라고 쓰여 있는 것을 본 적이 있을 것입니다. 이 Sync는 프로퍼티 동기화가 되고 있다는 것을 의미합니다. 만일 프로퍼티 동기화를 원치 않는다면 Sync를 눌러 None으로 변경해 줍니다. 동기화 표시가 None으로 되어 있으면 프로퍼티 동기화는 이루어지지 않는다는 것을 의미하며, 프로퍼티 값을 공간별로 따로 관리할 수 있게 됩니다. #### 타입별 동기화 가능 여부 일부 타입의 프로퍼티는 동기화 설정이