msw-combat-system
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesemsw-combat-system
msw-combat-system
MSW 전투 파이프라인 전체. 2D 장르 불문 공통 전투 레이어 중 MSW 네이티브 API 지원 항목만 정리. 수식·이론 제외. 전부 원본 재검증 완료 (2026-04-21).
default-local-workspace/Environment/NativeScripts/**/*.d.mlua의심/예외는 캐시 먼저 확인.
docs/engine-source-index.mdMSW完整战斗流水线。仅整理所有2D品类通用战斗层中MSW原生API支持的内容,不包含公式与理论。所有内容均已通过原文件重新验证(2026-04-21)。
default-local-workspace/Environment/NativeScripts/**/*.d.mlua如有疑问或例外情况,请先查看缓存。
docs/engine-source-index.md0. 커버리지 매트릭스
0. 覆盖范围矩阵
| # | 레이어 | 네이티브 | 커스텀 필요 |
|---|---|---|---|
| 1 | Attack Resolution | | Capsule/Cone/Ray, 관통 카운트 |
| 2 | Damage Model | | 속성 상성, 복합 공식 |
| 3 | Hit Reaction | Body별 넉백 API, | 경직 레벨, 상태이상 |
| 4 | Game Feel | 6개 전부 네이티브 (Hit Stop, Shake, Zoom, Flash, VFX, SFX) | — |
| 5 | Combat State | | MP/Stamina/Rage, 어그로 |
| 6 | Event Bus | | OnKill/OnBlocked |
| 7 | AI | | Decorator/Memory(Blackboard), Threat Table |
| + | Damage Skin | | — |
| + | Hit Effect | | — |
| + | Avatar Motion | | — |
| # | 层级 | 原生支持 | 需自定义 |
|---|---|---|---|
| 1 | 攻击判定(Attack Resolution) | | Capsule/Cone/Ray、穿透计数 |
| 2 | 伤害模型(Damage Model) | | 属性克制、复合公式 |
| 3 | 受击反应(Hit Reaction) | 按部位击退API、基于 | 僵直等级、异常状态 |
| 4 | 游戏手感(Game Feel) | 6项全部原生支持(Hit Stop、震动、缩放、闪屏、VFX、SFX) | — |
| 5 | 战斗状态(Combat State) | | MP/耐力/怒气、仇恨值 |
| 6 | 事件总线(Event Bus) | | OnKill/OnBlocked |
| 7 | AI | | Decorator/记忆(Blackboard)、威胁表 |
| + | 伤害皮肤(Damage Skin) | | — |
| + | 击中特效(Hit Effect) | | — |
| + | 角色动作(Avatar Motion) | | — |
0.5 References — 어디로 가야 하나
0.5 参考文档 — 去哪里查找
본 SKILL.md는 시스템 흐름과 네이티브 API 표면만 다룬다. 실제 모델 JSON·스크립트 전체 코드·변형 패턴은 아래 references/* 에서 직접 Read한다.
| 파일 | 다루는 범위 | 언제 읽나 |
|---|---|---|
| 몬스터 | 전투 가능한 몬스터 만들 때 |
| | 머리 위 HP 바 붙일 때 |
| 투사체 (Body 없는 엔티티 + | 화살·총알·마법탄 등 원거리 공격 만들 때 |
| BehaviourTree — | BT 기반 몬스터·보스 AI, 다층 의사결정 필요할 때 |
우선순위: *본 SKILL.md (개념·API 표) → 해당 references/ (구현 전체) →검증 (의심 시)**.mod/*.cs
本SKILL.md仅涵盖系统流程与原生API表面。实际模型JSON、完整脚本代码、变形模式请直接阅读下方references/*文档。
| 文件 | 覆盖范围 | 阅读时机 |
|---|---|---|
| 怪物 | 创建可战斗的怪物时 |
| 基于 | 需要添加头顶HP条时 |
| 投射物(无Body实体 + | 创建弓箭、子弹、魔法弹等远程攻击时 |
| 行为树(BehaviourTree)—— | 需要基于BT的怪物/BOSS AI、多层决策时 |
优先级:本SKILL.md(概念·API表)→ 对应references/*(完整实现)→验证(有疑问时).mod/*.cs
1. Attack Resolution
1. 攻击判定(Attack Resolution)
1-1. Shape & Attack 발동
1-1. 形状与攻击触发
HitComponent.ColliderTypeAttackComponent:
Attack(Vector2 size, Vector2 offset, string attackInfo, CollisionGroup? cg) → table<Component>
Attack(Shape shape, string attackInfo, CollisionGroup? cg) → table<Component>
AttackFast(Shape shape, string attackInfo, CollisionGroup? cg) → void (대량 판정용, 탄막)
AttackFrom(Vector2 size, Vector2 position, string attackInfo, CollisionGroup? cg) → table<Component>
emitter EmitAttackEvent(AttackEvent)- Shape: /
RectangleShape(center, size)/CircleShape(center, radius)BoxShape(pos, size, angle) - Polygon 피격면:
HitComponent.PolygonPoints: SyncList<Vector2> - 는 히트 테이블 미생성 → 탄막·대량 판정 성능 유리
AttackFast
HitComponent.ColliderTypeAttackComponent:
Attack(Vector2 size, Vector2 offset, string attackInfo, CollisionGroup? cg) → table<Component>
Attack(Shape shape, string attackInfo, CollisionGroup? cg) → table<Component>
AttackFast(Shape shape, string attackInfo, CollisionGroup? cg) → void (用于大量判定,如弹幕)
AttackFrom(Vector2 size, Vector2 position, string attackInfo, CollisionGroup? cg) → table<Component>
emitter EmitAttackEvent(AttackEvent)- Shape: /
RectangleShape(center, size)/CircleShape(center, radius)BoxShape(pos, size, angle) - 多边形受击面:
HitComponent.PolygonPoints: SyncList<Vector2> - 不生成命中表 → 弹幕、大量判定场景性能更优
AttackFast
1-2. 타겟 필터
1-2. 目标过滤
| 지점 | 오버라이드 | 용도 |
|---|---|---|
| 공격자 | | 진영·거리·상태 |
| 피격자 | | 무적·면역 |
한쪽이라도 false → 히트 제외. super 호출은 (mlua 고유).
__base:IsAttackTarget(...)- 기본
HitComponent.CollisionGroup.CollisionGroups.HitBox마지막 인자로 타겟 그룹 지정Attack(..., cg) - 중복 히트 방지 / 관통 / 최대 히트 수: 네이티브 없음. 반환 테이블 +
Attack캐시로 스크립트 관리table<Entity, boolean>
| 判定点 | 可重写 | 用途 |
|---|---|---|
| 攻击者 | | 阵营、距离、状态 |
| 受击者 | | 无敌、免疫 |
任意一方返回false则排除命中。父类调用需使用****(mlua特有语法)。
__base:IsAttackTarget(...)- 默认值为
HitComponent.CollisionGroup。可通过CollisionGroups.HitBox最后一个参数指定目标分组Attack(..., cg) - 重复命中防止 / 穿透 / 最大命中数:无原生支持,需通过返回表 +
Attack缓存实现脚本管理table<Entity, boolean>
1-3. attackInfo
태깅
attackInfo1-3. attackInfo
标记
attackInfoCalcDamageIsHitTargetGetDisplayHitCount"melee.light""dot.poison"attackInfoCalcDamageIsHitTargetGetDisplayHitCount"melee.light""dot.poison"1-4. ⚠️ IsLegacy
1-4. ⚠️ IsLegacy
HitComponent.IsLegacy = falseColliderTypeColliderOffsetPolygonPointsBoxOffsetColliderName仅当时,//才有效。/已废弃。
HitComponent.IsLegacy = falseColliderTypeColliderOffsetPolygonPointsBoxOffsetColliderName1-5. 공격 형태별 Shape 매핑
1-5. 攻击形态对应Shape映射
| 형태 | Shape 구성 |
|---|---|
| 근접 전방 Box | |
| 원형 AoE | |
| 투사체 | Body 없는 모델(Sprite+Transform만) 스폰 + |
MSW 전용 투사체 시스템 없음 — 엔티티 + 조합으로 구현.
AttackComponent| 形态 | Shape构成 |
|---|---|
| 近战前方Box | |
| 圆形AoE | |
| 投射物 | 无Body模型(仅Sprite+Transform)生成 + 在 |
MSW无专属投射物系统 — 需通过实体 + 组合实现。
AttackComponent1-6. 연속 이동 — 투사체·몬스터·AI 공통 규칙
1-6. 连续移动 — 投射物·怪物·AI通用规则
연속 이동(추적·비행·자동 이동)은 매 프레임 기반. 타이머()로 이동시키면 6~10Hz 순간이동으로 보여 끊긴다.
OnUpdate(delta)SetTimerRepeat(0.1~0.15s)连续移动(追踪、飞行、自动移动)需基于**每帧**实现。若用定时器()移动,会呈现6~10Hz的瞬移效果,导致动作卡顿。
OnUpdate(delta)SetTimerRepeat(0.1~0.15s)대상별 권장 API
各对象推荐API
| 대상 | Body 유무 | 이동 API | 근거 |
|---|---|---|---|
| 몬스터 / NPC / AI | 있음 (맵 타입 Body + | | |
| 투사체 / 젬 / 드롭 아이템 / 이펙트 | 없음 (Sprite+Transform+Trigger) | | Body 없으면 Transform 직접 조작 안전. 공식 "Create a Long-Range Projectile" 튜토리얼 패턴 |
| Rigidbody 엔티티 직접 제어 (고급) | 있음 | | |
맵 타입별 실제 velocity 환산은MovementComponent.InputSpeed§10 참조 (MapleTile=×1, RectTile=÷1.2, SideView=×1.5).msw-general/references/platform.md
| 对象 | 是否有Body | 移动API | 依据 |
|---|---|---|---|
| 怪物 / NPC / AI | 有(对应地图类型的Body + | | |
| 投射物 / 宝石 / 掉落物品 / 特效 | 无(Sprite+Transform+Trigger) | 每帧调用 | 无Body时直接操作Transform更安全。符合官方「Create a Long-Range Projectile」教程模式 |
| 直接控制Rigidbody实体(高级) | 有 | | |
在不同地图类型下的实际速度换算,请参考MovementComponent.InputSpeed§10(MapleTile=×1, RectTile=÷1.2, SideView=×1.5)。msw-general/references/platform.md
금지 패턴
禁止模式
| ❌ | 사유 |
|---|---|
| 6~10Hz teleport, 프레임 보간 없음 → 뚝뚝 끊김 |
| 둘 다 텔레포트 메서드 ( |
| 다음 프레임 물리엔진이 덮어쓰고 네트워크 동기화 차단 |
| 프레임률 의존. 60FPS·30FPS에서 속도 다름 |
| ❌ | 原因 |
|---|---|
使用 | 6~10Hz瞬移,无帧间插值 → 动作卡顿 |
在 | 两者均为瞬移方法( |
(有Body激活的实体)直接赋值 | 下一帧物理引擎会覆盖该值,且会阻断网络同步 |
不使用delta,直接以常量值移动(如 | 速度依赖帧率,60FPS与30FPS下速度不同 |
⚠ 공식 msw-search 안티패턴 주의
⚠ 官方msw-search反模式注意
mlua_Document_RetrieverOnUpdateMovementComponent:SetPosition(...)MoveToDirectionTranslateFlappyFish RemakeStopping the TaxiMaking a Moving FootholdPositionmlua_Document_RetrieverOnUpdateMovementComponent:SetPosition(...)MoveToDirectionTranslateFlappyFish RemakeStopping the TaxiMaking a Moving FootholdPositionMovementComponent 부착 — 몬스터/NPC
挂载MovementComponent — 怪物/NPC
몬스터 모델에 기본 포함 안 됨. 에 다음 컴포넌트가 모두 있어야 한다.
.model| 컴포넌트 | 비고 |
|---|---|
| 기본 |
| 렌더 |
| Body (맵 타입) | |
| |
怪物模型默认不包含该组件。需同时包含以下组件:
.model| 组件 | 备注 |
|---|---|
| 默认组件 |
| 渲染组件 |
| Body(对应地图类型) | |
| 设置 |
교차 참조
交叉参考
- **넉백(1-shot 임펄스)**은 연속 이동이 아니므로 §3-1 그대로 사용
- 맵 타입별 Body 선택 / InputSpeed 환산식: §4·§10
msw-general/references/platform.md
- **击退(单次冲量)**不属于连续移动,直接使用§3-1中的方法即可
- 地图类型对应Body选择 / InputSpeed换算公式:§4·§10
msw-general/references/platform.md
2. Damage Model
2. 伤害模型(Damage Model)
AttackComponent:
method integer CalcDamage(attacker, defender, attackInfo) -- default 1
method boolean CalcCritical(attacker, defender, attackInfo) -- default false
method float GetCriticalDamageRate() -- default 2.0
method int32 GetDisplayHitCount(attackInfo) -- default 1
method void OnAttack(defender)
HitComponent:
method void OnHit(Entity attacker, integer damage, boolean isCritical, string attackInfo, int32 hitCount)
emitter EmitHitEvent(HitEvent)AttackComponent:
method integer CalcDamage(attacker, defender, attackInfo) -- 默认值1
method boolean CalcCritical(attacker, defender, attackInfo) -- 默认值false
method float GetCriticalDamageRate() -- 默认值2.0
method int32 GetDisplayHitCount(attackInfo) -- 默认值1
method void OnAttack(defender)
HitComponent:
method void OnHit(Entity attacker, integer damage, boolean isCritical, string attackInfo, int32 hitCount)
emitter EmitHitEvent(HitEvent)2-1. HitEvent
페이로드
HitEvent2-1. HitEvent
负载
HitEventAttackCenter: Vector2
AttackerEntity: Entity (nilable)
Damages: List<integer> -- 멀티히트 분할
Extra: any -- ★ 확장 슬롯 (knockback/stun/element/tags)
IsCritical: boolean
TotalDamage: integer
FeedbackAction: HitFeedbackAction -- ⚠ 전체 enum deprecated부가 정보(넉백 벡터·경직 시간·속성)는 테이블로 실어 전달.
ExtraAttackCenter: Vector2
AttackerEntity: Entity (可空)
Damages: List<integer> -- 多段伤害拆分
Extra: any -- ★ 扩展字段(击退/僵直/属性/标签)
IsCritical: boolean
TotalDamage: integer
FeedbackAction: HitFeedbackAction -- ⚠ 整个枚举已废弃附加信息(击退向量、僵直时间、属性)需通过表传递。
Extra2-2. AttackEvent
페이로드
AttackEvent2-2. AttackEvent
负载
AttackEventDefenderEntity: Entityself包含。攻击者为事件处理者。
DefenderEntity: Entityself2-3. ⚠️ 직접 HP 차감 안티패턴 — HitEvent
우회 금지
HitEvent2-3. ⚠️ 直接扣减HP反模式 — 禁止绕过HitEvent
HitEventmonster.Hp -= damagetarget.MonsterAI.HP -= damageHitEvent若直接修改受击者HP(如 / ),则不会触发
monster.Hp -= damagetarget.MonsterAI.HP -= damageHitEvent3. Hit Reaction
3. 受击反应(Hit Reaction)
3-1. 넉백 — Body별 API
3-1. 击退 — 按Body类型对应API
| Body (맵 타입) | 구현 |
|---|---|
| Rigidbody (MapleTile) | |
| Kinematicbody (RectTile/탑다운) | |
| Sideviewbody (SideViewRectTile) | |
- Rigidbody 는 엔진이 자동 감쇠. Kinematic/Sideview 는 에서 수동 감쇠 (
OnUpdate)MoveVelocity *= 0.9 - 벽 튕김: 구독 후 velocity 반전
FootholdCollisionEvent - 넉백은 1-shot 임펄스 — 연속 이동(추적·비행)과 혼동 금지. 연속 이동은 §1-6
- ⚠ 금지: Body 활성 엔티티에 직접 대입 → 네트워크 동기화 차단.
TransformComponent.Position은 텔레포트 메서드이므로body:SetPosition(...)루프에서 호출 금지 (§1-6)OnUpdate
| Body(地图类型) | 实现方式 |
|---|---|
| Rigidbody(MapleTile) | |
| Kinematicbody(RectTile/俯视角) | |
| Sideviewbody(SideViewRectTile) | |
- Rigidbody由引擎自动衰减速度。Kinematic/Sideview需在中手动衰减(
OnUpdate)MoveVelocity *= 0.9 - 墙壁反弹:订阅后反转velocity
FootholdCollisionEvent - 击退为单次冲量 — 请勿与连续移动(追踪、飞行)混淆。连续移动规则见§1-6
- ⚠ 禁止:对有Body激活的实体直接赋值→ 阻断网络同步。
TransformComponent.Position是瞬移方法,禁止在body:SetPosition(...)循环中调用(§1-6)OnUpdate
3-2. i-frame
3-2. 无敌帧(i-frame)
표준 패턴: 기반 deadline 체크 + 에서 false. 기본 가 이 패턴을 그대로 제공 (§9-4).
_UtilLogic.ElapsedSecondsHitComponent:IsHitTargetDefaultPlayerPlayerHit.mlua대안: 무적 중 을 별도 그룹으로 교체 → 판정 자체 제외. 프레임 단위 정확도에 유리.
HitComponent.CollisionGroup标准模式:基于的截止时间检查 + 在中返回false。DefaultPlayer默认的已实现该模式(§9-4)。
_UtilLogic.ElapsedSecondsHitComponent:IsHitTargetPlayerHit.mlua替代方案:无敌期间将切换为单独分组 → 直接排除判定。帧级精度更优。
HitComponent.CollisionGroup3-3. 상태이상 (Buff/Debuff)
3-3. 异常状态(Buff/Debuff)
네이티브 부재. 직접 구현 + 틱 + 커스텀 / 브로드캐스트.
@Component BuffComponent_TimerService:SetTimerRepeatStatusAppliedEventStatusExpiredEvent단순 스턴 1종이면 + 입력/AI 차단 플래그로 충분.
StateComponent:ChangeState("STUN")无原生支持。需自行实现 + Tick + 自定义/广播。
@Component BuffComponent_TimerService:SetTimerRepeatStatusAppliedEventStatusExpiredEvent若仅需简单眩晕,使用 + 输入/AI阻断标记即可。
StateComponent:ChangeState("STUN")4. Game Feel — 전부 네이티브
4. 游戏手感(Game Feel)— 全部原生支持
| 요소 | API | ExecSpace |
|---|---|---|
| Hit Stop (전역) | | ClientOnly |
| Hit Stop (개별) | | @Sync |
| Slow Motion | | ClientOnly |
| Camera Shake | | Client |
| Camera Zoom | | Client |
| Hit Flash | | @Sync |
| Color HDR 오버브라이트 | | — |
| VFX 고정 | | — |
| VFX 부착 | | — |
| VFX 제거 | | — |
| SFX 2D | | Client |
| SFX 3D | | Client |
| SFX 루프 | | Client |
| SFX 부착 | | Client |
| BGM | | Client |
| 프리로드 | | ClientOnly |
PlayEffectFlipX, FlipY, SortingLayer, OrderInLayer, Alpha, StartFrameIndex, EndFrameIndex, PlayRate, SyncFlip, Color, MaterialID, IgnoreMapLayerCheck, LitMode현재 카메라 획득: .
_CameraService:GetCurrentCameraComponent()| 要素 | API | 执行空间 |
|---|---|---|
| Hit Stop(全局) | | ClientOnly |
| Hit Stop(单个对象) | | @Sync |
| 慢动作 | | ClientOnly |
| 相机震动 | | Client |
| 相机缩放 | | Client |
| 击中闪屏 | | @Sync |
| Color HDR叠加 | | — |
| 固定位置VFX | | — |
| 挂载VFX | | — |
| 移除VFX | | — |
| 2D SFX | | Client |
| 3D SFX | | Client |
| 循环SFX | | Client |
| 挂载SFX | | Client |
| BGM | | Client |
| 预加载 | | ClientOnly |
PlayEffectFlipX, FlipY, SortingLayer, OrderInLayer, Alpha, StartFrameIndex, EndFrameIndex, PlayRate, SyncFlip, Color, MaterialID, IgnoreMapLayerCheck, LitMode获取当前相机:.
_CameraService:GetCurrentCameraComponent()ParticleService — 내장 파티클
ParticleService — 内置粒子
RUID 없이 enum 값만으로 범용 파티클 연출. 3종류:
-- BasicParticle: 범용 프리셋 (RUID 불필요)
integer _ParticleService:PlayBasicParticle(BasicParticleType, Entity instigator, Vector3 pos, number zRot, Vector3 scale, boolean isLoop, Dictionary options)
integer _ParticleService:PlayBasicParticleAttached(BasicParticleType, Entity parent, Vector3 localPos, number localZRot, Vector3 localScale, boolean isLoop, Dictionary options)
-- SpriteParticle: 커스텀 스프라이트를 파티클로 (spriteRUID 필요)
integer _ParticleService:PlaySpriteParticle(SpriteParticleType, string spriteRUID, Entity instigator, Vector3 pos, number zRot, Vector3 scale, boolean isLoop, Dictionary options)
integer _ParticleService:PlaySpriteParticleAttached(SpriteParticleType, string spriteRUID, Entity parent, Vector3 localPos, number localZRot, Vector3 localScale, boolean isLoop, Dictionary options)
-- AreaParticle: 넓은 영역 환경 파티클 (areaSize 추가)
integer _ParticleService:PlayAreaParticle(AreaParticleType, Vector2 areaSize, Entity instigator, Vector3 pos, number zRot, Vector3 scale, boolean isLoop, Dictionary options)
void _ParticleService:RemoveParticle(integer serial)options 키:
Color, SortingLayer, OrderInLayer, ParticleSize, ParticleCount루프 파티클()은 반드시 로 정리. serial을 에 저장해두어야 나중에 제거 가능.
isLoop=trueRemoveParticle(serial)self._T无需RUID,仅通过枚举值即可实现通用粒子效果。包含3种类型:
-- BasicParticle: 通用预设(无需RUID)
integer _ParticleService:PlayBasicParticle(BasicParticleType, Entity instigator, Vector3 pos, number zRot, Vector3 scale, boolean isLoop, Dictionary options)
integer _ParticleService:PlayBasicParticleAttached(BasicParticleType, Entity parent, Vector3 localPos, number localZRot, Vector3 localScale, boolean isLoop, Dictionary options)
-- SpriteParticle: 将自定义Sprite作为粒子(需spriteRUID)
integer _ParticleService:PlaySpriteParticle(SpriteParticleType, string spriteRUID, Entity instigator, Vector3 pos, number zRot, Vector3 scale, boolean isLoop, Dictionary options)
integer _ParticleService:PlaySpriteParticleAttached(SpriteParticleType, string spriteRUID, Entity parent, Vector3 localPos, number localZRot, Vector3 localScale, boolean isLoop, Dictionary options)
-- AreaParticle: 大范围环境粒子(需添加areaSize)
integer _ParticleService:PlayAreaParticle(AreaParticleType, Vector2 areaSize, Entity instigator, Vector3 pos, number zRot, Vector3 scale, boolean isLoop, Dictionary options)
void _ParticleService:RemoveParticle(integer serial)options参数键:
Color, SortingLayer, OrderInLayer, ParticleSize, ParticleCount循环粒子()必须通过清理。需将serial存储在中以便后续移除。
isLoop=trueRemoveParticle(serial)self._TBasicParticleType 전체 목록
BasicParticleType完整列表
| 계열 | 이름 | 설명 |
|---|---|---|
| 폭발/충격 | | 스파크 (1회) — 범용 피격 |
| 연속 스파크 | |
| 원형으로 튀는 스파크 | |
| 작은 폭발 + 연기 | |
| 큰 폭발 + 연기 | |
| 아주 작은 폭발 (Color 옵션 무효) | |
| 원형 파동 + 연기 (Color 옵션 무효) | |
| 원형 파동 후 중심 수렴 | |
| 원형 빛 폭발 | |
| 원형 빛 폭발 + 방향성 빛 | |
| 불/화염 | | 만화풍 불꽃 |
| 강한 만화풍 불꽃 | |
| 한 곳에 화염 생성 | |
| 화염 방출 | |
| 바닥에서 큰 화염 | |
| 바닥에서 중간 화염 | |
| 바닥에서 작은 화염 | |
| 거대한 화염 기둥 (Color 옵션 무효) | |
| 번개/전기 | | 구형 전기 파티클 |
| 번개 | |
| 긴 번개 | |
| 전기파 방출 | |
| 주기적 전기파 | |
| 주기적 번개 | |
| 주기적 긴 번개 | |
| 버프/마법 | | 바닥에서 오로라 빛 |
| 바닥에서 강한 빛 상승 | |
| 큰 파티클이 한 점으로 수렴 | |
| 파티클이 한 점으로 수렴 | |
| 큰 빛 주변에 빛과 파티클 | |
| 회전하는 원 주변에 파티클 | |
| 별빛이 중심으로 수렴 | |
| 넓은 원형 파동 | |
| 바닥에서 기둥 형태 상승 | |
| 기타 | | 불꽃놀이 |
| 여러 폭죽 동시 | |
| 반딧불이 | |
| 옆으로 액체 분출 | |
| 바닥으로 액체 분출 | |
| 넓은 모래 폭풍 | |
| 바닥에서 흰 안개 상승 | |
| 큰 물보라 | |
| 한 곳에 물 뿌림 |
| 系列 | 名称 | 说明 |
|---|---|---|
| 爆炸/冲击 | | 火花(单次)— 通用击中效果 |
| 连续火花 | |
| 呈圆形散射的火花 | |
| 小型爆炸 + 烟雾 | |
| 大型爆炸 + 烟雾 | |
| 微型爆炸(Color选项无效) | |
| 圆形冲击波 + 烟雾(Color选项无效) | |
| 圆形冲击波后向中心收敛 | |
| 圆形光效爆炸 | |
| 圆形光效爆炸 + 方向性光线 | |
| 火/火焰 | | 卡通风格火焰 |
| 强烈卡通风格火焰 | |
| 在指定位置生成火焰 | |
| 喷射火焰 | |
| 从地面升起的大型火焰 | |
| 从地面升起的中型火焰 | |
| 从地面升起的小型火焰 | |
| 巨型火焰柱(Color选项无效) | |
| 闪电/电 | | 球形电粒子 |
| 闪电 | |
| 长闪电 | |
| 释放电波 | |
| 周期性电波 | |
| 周期性闪电 | |
| 周期性长闪电 | |
| Buff/魔法 | | 从地面升起的极光 |
| 从地面升起的强光 | |
| 大型粒子向单点收敛 | |
| 粒子向单点收敛 | |
| 强光周围伴随光线与粒子 | |
| 旋转圆形周围伴随粒子 | |
| 星光向中心收敛 | |
| 大范围圆形冲击波 | |
| 从地面升起的柱状光效 | |
| 其他 | | 烟花 |
| 多枚烟花同时绽放 | |
| 萤火虫 | |
| 向侧面喷射液体 | |
| 向地面喷射液体 | |
| 大范围沙尘暴 | |
| 从地面升起的白色雾气 | |
| 大型水花 | |
| 向指定位置喷水 |
SpriteParticleType 전체 목록 (8종)
SpriteParticleType完整列表(8种)
| 이름 | 설명 |
|---|---|
| 스프라이트가 원형으로 퍼지며 등장 |
| 파티클+스프라이트가 원형 영역에 등장 |
| 파티클+스프라이트가 원형으로 폭발 |
| 파티클+스프라이트 단순 등장 |
| 파티클+스프라이트가 퍼짐 |
| 특정 방향으로 이동하며 생성 |
| 가느다란 선으로 특정 방향 이동 |
| 스프라이트에 색상 효과 적용 |
| 名称 | 说明 |
|---|---|
| Sprite呈圆形扩散出现 |
| 粒子+Sprite在圆形区域出现 |
| 粒子+Sprite呈圆形爆炸 |
| 粒子+Sprite简单出现 |
| 粒子+Sprite扩散 |
| 沿指定方向移动并生成 |
| 以细直线沿指定方向移动 |
| 为Sprite添加颜色效果 |
AreaParticleType 전체 목록 (12종)
AreaParticleType完整列表(12种)
| 이름 | 설명 |
|---|---|
| 비 |
| 눈 |
| 안개 |
| 짙은 내려오는 안개 |
| 올라오는 안개 |
| 올라오는 별 무리 |
| 반짝이는 별 무리 |
| 별+성운 파티클 (제자리) |
| 별+성운 파티클 (상승) |
| 가는 선 |
| 가는 선 + 굵은 선 |
| 빠른 직선 |
| 名称 | 说明 |
|---|---|
| 雨 |
| 雪 |
| 雾 |
| 厚重下落雾 |
| 上升雾 |
| 上升星群 |
| 闪烁星群 |
| 星+星云粒子(静止) |
| 星+星云粒子(上升) |
| 细线 |
| 细线 + 粗线 |
| 快速直线 |
EffectService vs ParticleService 선택
EffectService vs ParticleService选择
| 상황 | 권장 |
|---|---|
| 메이플스토리 스킬/피격 애니메이션 (구체적 이미지) | |
| 범용 피격·폭발 (빠른 구현) | |
| 커스텀 이미지를 파티클로 흩뿌리기 | |
| 비·눈·안개 등 환경 연출 | |
| 버프 오라 등 지속 효과 | 둘 다 |
| 풍성한 연출 | EffectService + ParticleService 동시 조합 |
서버 이벤트 → 클라이언트 이펙트 표준 패턴:프로퍼티 변경 →@Sync감지 → EffectService/ParticleService 호출.OnSyncProperty(ClientOnly)
| 场景 | 推荐 |
|---|---|
| 冒险岛风格技能/击中动画(具体图像) | |
| 通用击中·爆炸(快速实现) | |
| 将自定义图像作为粒子散射 | |
| 雨·雪·雾等环境效果 | |
| Buff光环等持续效果 | 两者均支持 |
| 丰富效果 | 同时组合EffectService + ParticleService |
服务器事件→客户端效果标准模式:修改属性 → 在@Sync中检测 → 调用EffectService/ParticleService.OnSyncProperty(ClientOnly)
5. 사망 / 부활
5. 死亡 / 复活
| 이벤트 | 발행 조건 | 페이로드 |
|---|---|---|
| | 없음 |
| | 없음 |
| 모든 상태 전환 시 자동 | |
킬러 추적: DeadEvent 페이로드 없음 → 에서 캐시 후 에서 사용.
HandleHitEventself.LastAttacker = event.AttackerEntityHandleDeadEvent플레이어 전용 사망·부활은 §9-1 우선 사용.
PlayerComponent.Respawn/ProcessDead/ProcessRevive| 事件 | 触发条件 | 负载 |
|---|---|---|
| 调用 | 无 |
| 调用 | 无 |
| 所有状态切换时自动触发 | |
追踪击杀者:无负载 → 在中缓存,然后在中使用。
DeadEventHandleHitEventself.LastAttacker = event.AttackerEntityHandleDeadEvent玩家专属死亡·复活优先使用§9-1中的。
PlayerComponent.Respawn/ProcessDead/ProcessRevive6. Event Bus
6. 事件总线(Event Bus)
| 논리 이벤트 | MSW 구현 |
|---|---|
| OnAttackStart | |
| OnAttackHit / OnDamageTaken | 네이티브 |
| OnAttackMiss | 커스텀 — |
| OnCriticalHit | |
| OnDeath / OnRevive | 네이티브 |
| OnStateChange | 네이티브 |
| OnKill / OnBlocked / OnParry / OnStatusApplied | 커스텀 |
| 逻辑事件 | MSW实现方式 |
|---|---|
| OnAttackStart | |
| OnAttackHit / OnDamageTaken | 原生 |
| OnAttackMiss | 自定义 — |
| OnCriticalHit | 通过 |
| OnDeath / OnRevive | 原生 |
| OnStateChange | 原生 |
| OnKill / OnBlocked / OnParry / OnStatusApplied | 自定义 |
6-1. 커스텀 이벤트 규칙
6-1. 自定义事件规则
- 정의: +
@Event script XxxEvent extends EventType들property - 수신: 키워드 (method 아님),
handler@EventSender("Self" | "Service","XxxService" | "Logic","XxxLogic") - 연결/해제: /
entity:ConnectEvent(XxxEvent, self.Handler)에서 반드시OnEndPlay(엔진 자동 해제 없음)DisconnectEvent - 전역: 싱글턴 +
@Logic CombatEventBusLogic@EventSender("Logic","CombatEventBusLogic")
- 定义:+ 相关
@Event script XxxEvent extends EventTypeproperty - 接收:使用关键字(非method),搭配
handler@EventSender("Self" | "Service","XxxService" | "Logic","XxxLogic") - 连接/断开:/ 必须在
entity:ConnectEvent(XxxEvent, self.Handler)中调用OnEndPlay(引擎不会自动断开)DisconnectEvent - 全局事件:单例 +
@Logic CombatEventBusLogic@EventSender("Logic","CombatEventBusLogic")
7. AI — FSM(StateComponent) + BT(AIComponent) 둘 다 네이티브
7. AI — FSM(StateComponent) + BT(AIComponent)均原生支持
| 패턴 | 적합 | 참조 |
|---|---|---|
FSM ( | 단순 적 (3~5상태), 플레이어 IDLE/HIT/DEAD, 보스 페이즈, 애니메이션 동기 ( | |
BT ( | 패트롤+추적+공격 조합, 다양한 보스 패턴, Composite/Decorator 재사용, 확률 가중 행동 | |
| 模式 | 适用场景 | 参考文档 |
|---|---|---|
FSM( | 简单敌人(3~5种状态)、玩家IDLE/HIT/DEAD、BOSS阶段、动画同步( | |
BT( | 巡逻+追踪+攻击组合、多样BOSS模式、Composite/Decorator复用、带权重随机行为 | |
7-1. FSM — StateComponent
(요약)
StateComponent7-1. FSM — StateComponent
(摘要)
StateComponentStateComponent@State script XxxStateType extends StateTypeOnEnterOnUpdateOnExitOnConditionCheckIDLEDEADHitComponentHITAIChaseAIWanderMOVEATTACKPATROLSTUNPHASE2OnBeginPlayAddState("이름", XxxStateType)AddCondition(from, to)OnConditionCheck()⚠ 상태 이름은 UPPERCASE 강제, 미등록 이름은 즉시.[LEA-3005] InvalidArgument : 'stateName'키를 등록해도AvatarStateAnimationComponent.StateToAvatarBodyActionSheet엔 자동 등록되지 않음 — 둘은 별개.StateComponent
전체 구현 →
references/fsm-state.mdStateComponent@State script XxxStateType extends StateTypeOnEnterOnUpdateOnExitOnConditionCheckIDLEDEADHitComponentHITAIChaseAIWanderMOVEATTACKPATROLSTUNPHASE2OnBeginPlayAddState("名称", XxxStateType)AddCondition(from, to)OnConditionCheck()⚠ 状态名称必须为大写,未注册名称会立即触发。即使注册了[LEA-3005] InvalidArgument : 'stateName'的键,也不会自动注册到AvatarStateAnimationComponent.StateToAvatarBodyActionSheet— 两者相互独立。StateComponent
完整实现→
references/fsm-state.md7-2. BT — AIComponent
(요약)
AIComponent7-2. BT — AIComponent
(摘要)
AIComponentAIComponentSequenceNodeSelectorNodeRandomSelectorNodeParallelNode@BTNodeAIChaseComponentAIWanderComponent⚠ 커스텀 BT 사용 시에서.model/AIChaseComponent제거AIWanderComponent
전체 구현 →
references/ai-bt.md몬스터 엔티티 전체 구성 →references/monster-setup.md본 SKILL.md는 전투 특화(ATTACK/HIT/DEAD + DeadEvent/ReviveEvent + BT 진입점)만 다룬다. 일반 mlua 상태 머신/스크립팅 패턴은참조.msw-scripting
AIComponentSequenceNodeSelectorNodeRandomSelectorNodeParallelNode@BTNodeAIChaseComponentAIWanderComponent⚠ 使用自定义BT时,需在中移除.model/AIChaseComponentAIWanderComponent
完整实现→
references/ai-bt.md怪物实体完整构成→references/monster-setup.md本SKILL.md仅专注于战斗特化内容(ATTACK/HIT/DEAD + DeadEvent/ReviveEvent + BT入口)。通用mlua状态机/脚本模式请参考。msw-scripting
8. UI 네이티브
8. 原生UI
| UI | API |
|---|---|
| HP 바 (화면 고정) | |
| 데미지 숫자 | |
| 크로스헤어 | |
| 콤보 카운터 / 버프 아이콘 | |
월드스페이스 HP바 (머리 위): 네이티브 부재. 두 가지 구현 옵션:
| 옵션 | 방식 | 적합 상황 |
|---|---|---|
| 간이형 | 자식 엔티티 | 임시 프로토타입, 단순 게이지 |
| 완성형 | | 양산용, 다중 몬스터 동시 표시 |
| UI | API |
|---|---|
| HP条(屏幕固定) | |
| 伤害数字 | |
| 准星 | 在 |
| 连招计数器 / Buff图标 | |
世界空间HP条(头顶):无原生支持。有两种实现方案:
| 方案 | 方式 | 适用场景 |
|---|---|---|
| 简易版 | 子实体 | 临时原型、简单进度条 |
| 完整版 | 基于 | 量产项目、多怪物同时显示 |
9. DefaultPlayer 전투 네이티브
9. DefaultPlayer原生战斗功能
플레이어 엔티티는 HP·부활·입력을 네이티브로 갖는다. 커스텀 / 프로퍼티 만들지 말 것 — 사용.
HpMaxHpPlayerComponent/PlayerComponent전체 프로퍼티·메서드 표는PlayerControllerComponent참조. 여기서는 전투 핵심만.msw-defaultplayer/SKILL.md
玩家实体原生支持HP、复活、输入功能。请勿创建自定义/属性 — 使用。
HpMaxHpPlayerComponent/PlayerComponent完整属性·方法表请参考PlayerControllerComponent。此处仅列出战斗核心内容。msw-defaultplayer/SKILL.md
9-1. 전투 핵심 API
9-1. 战斗核心API
| 항목 | 사용법 |
|---|---|
| HP 감소 | |
| 사망 판정 | |
| 부활 | |
| 클라 전용 사망 처리 | |
| 방향 판정 ★ | |
| 액션 훅 오버라이드 | |
| 액션 이벤트 수신 | |
| 项目 | 使用方法 |
|---|---|
| HP减少 | |
| 死亡判定 | |
| 复活 | |
| 客户端专属死亡处理 | |
| 方向判定 ★ | |
| 动作钩子重写 | |
| 动作事件接收 | |
9-3. PlayerActionEvent
PlayerActionEvent9-3. PlayerActionEvent
PlayerActionEventproperty string ActionName -- "Attack" / "Jump" / "Crouch" / ...
property Entity PlayerEntityPlayerAttack extends AttackComponent@EventSender("Self") handler HandlePlayerActionEvent(...)event.ActionName == "Attack"property string ActionName -- "Attack" / "Jump" / "Crouch" / ...
property Entity PlayerEntityPlayerAttack extends AttackComponent@EventSender("Self") handler HandlePlayerActionEvent(...)event.ActionName == "Attack"9-4. 기본 제공 템플릿 (RootDesk/MyDesk/
)
RootDesk/MyDesk/9-4. 官方提供模板(RootDesk/MyDesk/
)
RootDesk/MyDesk/수정 없이 복붙 가능. 필요 시 오버라이드:
| 파일 | 역할 | 핵심 포인트 |
|---|---|---|
| 전방 Box 공격 | |
| i-frame | |
| 몬스터 HP | 커스텀 |
| sprite 크기 기반 근접 | |
可直接复制使用,按需重写:
| 文件 | 作用 | 核心要点 |
|---|---|---|
| 前方Box攻击 | 使用 |
| 无敌帧 | |
| 怪物HP | 自定义 |
| 基于Sprite大小的近战攻击 | 在 |
9-5. 시간 기준
9-5. 时间基准
_UtilLogic.ElapsedSecondsos.clock()推荐使用****(世界时间基准,暂停/恢复时保持一致)。禁止使用。
_UtilLogic.ElapsedSecondsos.clock()9-6. 표준 CollisionGroup
9-6. 标准CollisionGroup
| 상수 | 용도 |
|---|---|
| 몬스터 → 플레이어 공격 |
| 플레이어 → 몬스터 공격 |
| |
| 常量 | 用途 |
|---|---|
| 怪物→玩家攻击 |
| 玩家→怪物攻击 |
| |
10. 아바타 모션 — AvatarStateAnimationComponent
AvatarStateAnimationComponent10. 角色动作 — AvatarStateAnimationComponent
AvatarStateAnimationComponentStateComponent@Sync property SyncDictionary<string, AvatarBodyActionElement> StateToAvatarBodyActionSheet -- IsLegacy=false
@Sync property SyncDictionary<string, string> ActionSheet -- IsLegacy=true (deprecated)
method void SetActionSheet(string key, string animationClipRuid)
method void RemoveActionSheet(string key)
method string StateStringToAnimationKey(string stateName)
emitter EmitBodyActionStateChangeEvent(BodyActionStateChangeEvent)- → 매핑된
ChangeState("HIT")자동 재생MapleAvatarBodyActionState.Hit - 전투 관련 상태값: =3,
Attack=14,Hit=10,Dead=4,Alert=13Heal - 고정,
IsLegacy=false만 사용StateToAvatarBodyActionSheet
Avatar 컴포넌트(등) 전반은AvatarRendererComponent참조. 본 섹션은 전투 모션 매핑만 다룬다.msw-defaultplayer
将状态切换自动关联到角色动画。
StateComponent@Sync property SyncDictionary<string, AvatarBodyActionElement> StateToAvatarBodyActionSheet -- IsLegacy=false
@Sync property SyncDictionary<string, string> ActionSheet -- IsLegacy=true(已废弃)
method void SetActionSheet(string key, string animationClipRuid)
method void RemoveActionSheet(string key)
method string StateStringToAnimationKey(string stateName)
emitter EmitBodyActionStateChangeEvent(BodyActionStateChangeEvent)- 调用→ 自动播放映射的
ChangeState("HIT")MapleAvatarBodyActionState.Hit - 战斗相关状态值:=3,
Attack=14,Hit=10,Dead=4,Alert=13Heal - 固定设置,仅使用
IsLegacy=falseStateToAvatarBodyActionSheet
Avatar组件(等)整体内容请参考AvatarRendererComponent。本章节仅专注于战斗动作映射。msw-defaultplayer
11. 데미지 스킨 (숫자 표시)
11. 伤害皮肤(数字显示)
기본 RUID
默认RUID
| 용도 | RUID | 사용처 |
|---|---|---|
| 타격 | | 공격자 |
| 피격 | | 피격자 측 표시 — |
| 회복 | | 힐/포션 — |
| 用途 | RUID | 使用场景 |
|---|---|---|
| 攻击伤害 | | 攻击者 |
| 受击伤害 | | 受击者显示 — 手动调用 |
| 恢复 | | 治疗/药水 — 手动调用 |
11-1. 자동 모드 (컴포넌트 기반)
11-1. 自动模式(基于组件)
Attack/AttackFast| 위치 | 컴포넌트 | 역할 |
|---|---|---|
| 공격자 | | 어떤 스킨/스타일로 표시할지 |
| 피격자 | | 표시 위치 오프셋 |
| 피격자 | | 데미지 숫자 본체(엔티티 위) |
3개 모두 에 포함시켜두면 스크립트 코드 0줄로 데미지 숫자가 뜬다.
.model调用时,若同时满足以下3个条件,则自动显示伤害数字:
Attack/AttackFast| 位置 | 组件 | 作用 |
|---|---|---|
| 攻击者 | | 指定显示的皮肤/样式 |
| 受击者 | | 指定显示位置偏移 |
| 受击者 | | 伤害数字本体(显示在实体上方) |
将3个组件全部添加到中,无需编写脚本即可显示伤害数字。
.modelDamageSkinSettingComponent
(공격자)
DamageSkinSettingComponentDamageSkinSettingComponent
(攻击者)
DamageSkinSettingComponent| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
| DataRef | 타격 RUID (위 표) | 데미지 숫자 스킨 RUID |
| Vector2 | (1, 1) | 숫자 크기 |
| float | 1 | 투명도 |
| float | 1 | 재생 속도 |
| float | 0.05 | 멀티히트 간 딜레이(초) |
| DamageSkinTweenType | Default | 연출 타입 |
| LitMode | Default | 조명 영향 |
DamageSkinTweenTypeDefaultVolcanoBlade*Mini| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| DataRef | 攻击伤害RUID(上表) | 伤害数字皮肤RUID |
| Vector2 | (1, 1) | 数字大小 |
| float | 1 | 透明度 |
| float | 1 | 播放速度 |
| float | 0.05 | 多段伤害间隔(秒) |
| DamageSkinTweenType | Default | 动画类型 |
| LitMode | Default | 光照影响 |
DamageSkinTweenTypeDefaultVolcanoBlade*MiniDamageSkinSpawnerComponent
(피격자)
DamageSkinSpawnerComponentDamageSkinSpawnerComponent
(受击者)
DamageSkinSpawnerComponent| 속성 | 타입 | 기본값 |
|---|---|---|
| Vector2 | (0,0) |
| 属性 | 类型 | 默认值 |
|---|---|---|
| Vector2 | (0,0) |
11-2. 수동 모드 — DamageSkinService
DamageSkinService11-2. 手动模式 — DamageSkinService
DamageSkinService자동 모드로 잡히지 않는 케이스(힐, Miss/Guard, 비표준 데미지원)는 직접 호출.
_DamageSkinService_DamageSkinService:Play(targetEntity, skinRuid, delay, damages:List<int>, tweenType, isCritical, offset, scale, playRate, alpha, litMode)
_DamageSkinService:PlayTextDamage(targetEntity, skinRuid, textType, tweenType)
_DamageSkinService:PreloadAsync(skinRuid, callback(success)) -- ClientOnlyDamageSkinTextTypeMissGuardResistShotCounter⚠는_DamageSkinService:Play영역 — 서버 로직(HP 차감 등)에서 호출하려면Client메서드로 래핑하거나@ExecSpace("Client")프로퍼티 변경 후@Sync에서 트리거.OnSyncProperty
⚠의 필수 파라미터는 6개. 옵셔널 5개를 부분만 흘리면 LEA-3005Play()InvalidArgument
自动模式无法覆盖的场景(治疗、Miss/Guard、非标准伤害源),需直接调用。
_DamageSkinService_DamageSkinService:Play(targetEntity, skinRuid, delay, damages:List<int>, tweenType, isCritical, offset, scale, playRate, alpha, litMode)
_DamageSkinService:PlayTextDamage(targetEntity, skinRuid, textType, tweenType)
_DamageSkinService:PreloadAsync(skinRuid, callback(success)) -- ClientOnlyDamageSkinTextTypeMissGuardResistShotCounter⚠属于_DamageSkinService:Play执行空间 — 若在服务器逻辑(如HP扣减)中调用,需封装为Client方法,或修改@ExecSpace("Client")属性后在@Sync中触发。OnSyncProperty
⚠的必填参数为6个。若仅传递部分可选参数,会触发LEA-3005Play()InvalidArgument
11-3. 활용 레시피
11-3. 实用示例
(a) 크리티컬 강조 — 자동 모드 + 동적 스케일
(a) 暴击强化 — 自动模式 + 动态缩放
자동 모드는 면 빨강 폰트로 자동 처리. 추가 강조하려면 공격자 측 스케일을 일시 증대:
IsCritical=truelua
@ExecSpace("ServerOnly")
method int32 CalcDamage(Entity attacker, Entity defender, string attackInfo)
return 100
end
@ExecSpace("ServerOnly")
method boolean CalcCritical(Entity attacker, Entity defender, string attackInfo)
return math.random() < 0.3
end
method float GetCriticalDamageRate()
return 2.5 -- 100 → 250
endDamageSkinSettingComponent.TweenType = VolcanoBlade自动模式下会自动使用红色字体。若需进一步强化,可临时增大攻击者的缩放:
IsCritical=truelua
@ExecSpace("ServerOnly")
method int32 CalcDamage(Entity attacker, Entity defender, string attackInfo)
return 100
end
@ExecSpace("ServerOnly")
method boolean CalcCritical(Entity attacker, Entity defender, string attackInfo)
return math.random() < 0.3
end
method float GetCriticalDamageRate()
return 2.5 -- 100 → 250
end设置(扇形扩散)或(叠加),可在视觉上区分暴击与普通攻击。
DamageSkinSettingComponent.TweenType = VolcanoBlade(b) 힐 / 회복 — 수동 호출
(b) 治疗 / 恢复 — 手动调用
lua
local HEAL_RUID = "d58b67cf0f3a4eaf9fe1ad87c0ffac8a"
@ExecSpace("Client")
method void ShowHeal(Entity target, integer amount)
_DamageSkinService:Play(
target, HEAL_RUID, 0,
{ amount }, -- damages
DamageSkinTweenType.Default,
false, -- isCritical
Vector2(0, 0.5), -- offset (머리 위)
Vector2(1, 1), 1.0, 1.0, LitMode.Default
)
endlua
local HEAL_RUID = "d58b67cf0f3a4eaf9fe1ad87c0ffac8a"
@ExecSpace("Client")
method void ShowHeal(Entity target, integer amount)
_DamageSkinService:Play(
target, HEAL_RUID, 0,
{ amount }, -- damages
DamageSkinTweenType.Default,
false, -- isCritical
Vector2(0, 0.5), -- offset(头顶)
Vector2(1, 1), 1.0, 1.0, LitMode.Default
)
end(c) Miss / Guard / Resist 텍스트
(c) Miss / Guard / Resist文本
lua
local HIT_RUID = "02c22d93421b4038b3c413b3e40b57ec"
@ExecSpace("Client")
method void ShowMiss(Entity target)
_DamageSkinService:PlayTextDamage(
target, HIT_RUID, DamageSkinTextType.Miss, DamageSkinTweenType.Default
)
endAttackComponent:IsAttackTargetlua
local HIT_RUID = "02c22d93421b4038b3c413b3e40b57ec"
@ExecSpace("Client")
method void ShowMiss(Entity target)
_DamageSkinService:PlayTextDamage(
target, HIT_RUID, DamageSkinTextType.Miss, DamageSkinTweenType.Default
)
end当返回false时调用该方法,即可实现“Miss动画 + 0伤害”效果。
AttackComponent:IsAttackTarget(d) 멀티히트 — 한 번 호출로 N개 분할
(d) 多段伤害 — 一次调用显示N段
_DamageSkinService:PlaydamagesDelayPerAttacklua
_DamageSkinService:Play(target, ATTACK_RUID, 0, { 12, 8, 14, 11, 9 },
DamageSkinTweenType.Default, false, Vector2(0,0), Vector2(1,1), 1, 1, LitMode.Default)자동 모드도 (List)로 동일 동작 — 를 오버라이드해 분할 수를 제어한다.
HitEvent.DamagesGetDisplayHitCount(attackInfo)将List整体传递给的参数,会按照攻击者组件中的间隔依次显示:
_DamageSkinService:PlaydamagesDelayPerAttacklua
_DamageSkinService:Play(target, ATTACK_RUID, 0, { 12, 8, 14, 11, 9 },
DamageSkinTweenType.Default, false, Vector2(0,0), Vector2(1,1), 1, 1, LitMode.Default)自动模式下通过(List)也可实现相同效果 — 可通过重写控制拆分数量。
HitEvent.DamagesGetDisplayHitCount(attackInfo)(e) Preload — 첫 표시 끊김 방지
(e) Preload — 避免首次显示卡顿
스킨 RUID 첫 사용 시 텍스처 로드 지연이 있을 수 있다. 맵 진입 시 미리 로드:
lua
@ExecSpace("ClientOnly")
method void OnBeginPlay()
_DamageSkinService:PreloadAsync("3271c3e79bf04ecba9a107d55495970d", function(ok) end)
_DamageSkinService:PreloadAsync("02c22d93421b4038b3c413b3e40b57ec", function(ok) end)
_DamageSkinService:PreloadAsync("d58b67cf0f3a4eaf9fe1ad87c0ffac8a", function(ok) end)
end首次使用皮肤RUID时可能存在纹理加载延迟。可在进入地图时提前加载:
lua
@ExecSpace("ClientOnly")
method void OnBeginPlay()
_DamageSkinService:PreloadAsync("3271c3e79bf04ecba9a107d55495970d", function(ok) end)
_DamageSkinService:PreloadAsync("02c22d93421b4038b3c413b3e40b57ec", function(ok) end)
_DamageSkinService:PreloadAsync("d58b67cf0f3a4eaf9fe1ad87c0ffac8a", function(ok) end)
end(f) TweenType 사용 케이스
(f) TweenType适用场景
| TweenType | 추천 상황 |
|---|---|
| 일반 타격 |
| 크리티컬 / 광역 타격 (위로 흩뿌림) |
| 연속 베기 / 콤보 (숫자 겹침) |
| DoT(독/화상) 같은 작은 데미지 — 화면 점유 줄임 |
| TweenType | 推荐场景 |
|---|---|
| 普通攻击 |
| 暴击 / 范围攻击(向上扩散) |
| 连续攻击 / 连招(数字叠加) |
| DoT(中毒/灼烧)等小额伤害 — 减少屏幕占用 |
(g) 진영별 스킨 차별화
(g) 阵营皮肤差异化
플레이어 vs 적, PvP 진영 등에서 다른 스킨 RUID를 쓰려면 를 런타임에 교체:
DamageSkinSettingComponent.DamageSkinIdlua
self.Entity.DamageSkinSettingComponent.DamageSkinId = MY_TEAM_SKIN_RUID若需在玩家vs敌人、PvP阵营等场景使用不同皮肤RUID,可在运行时修改:
DamageSkinSettingComponent.DamageSkinIdlua
self.Entity.DamageSkinSettingComponent.DamageSkinId = MY_TEAM_SKIN_RUID12. 히트 이펙트 — HitEffectSpawnerComponent
HitEffectSpawnerComponent12. 击中特效 — HitEffectSpawnerComponent
HitEffectSpawnerComponent피격자에 부착만 하면 발생 시 자동으로 히트 이펙트 재생. property 없음, 에 컴포넌트 추가만.
HitEvent.model仅需挂载到受击者,当触发时自动播放击中特效。无属性设置,仅需在中添加组件即可。
HitEvent.model13. 완성형 전투 체크리스트
13. 完整战斗系统检查清单
- 공격자 모델: 상속 스크립트 (+ 선택:
AttackComponent)DamageSkinSettingComponent - 피격자 모델: +
HitComponent+ (선택:HitEffectSpawnerComponent+DamageSkinSpawnerComponent)DamageSkinComponent - HitComponent: ,
IsLegacy=false/ColliderType/BoxSize설정,CircleRadius설정CollisionGroup - 상태 모션: +
StateComponent에AvatarStateAnimationComponent.StateToAvatarBodyActionSheet/ATTACK/HIT등록DEAD - HP 처리: 플레이어는 , 몬스터는 커스텀
PlayerComponent.Hp@Sync Hp - 방향 판정: (Scale.x 금지)
LookDirectionX - 시간 기준: (os.clock 금지)
_UtilLogic.ElapsedSeconds - 이벤트 정리: 에서
OnEndPlay명시 해제DisconnectEvent - Body 규칙: Body 활성 엔티티에 직접 대입 금지
TransformComponent.Position
- 攻击者模型:继承的脚本(+ 可选:
AttackComponent)DamageSkinSettingComponent - 受击者模型:+
HitComponent+(可选:HitEffectSpawnerComponent+DamageSkinSpawnerComponent)DamageSkinComponent - HitComponent:设置,配置
IsLegacy=false/ColliderType/BoxSize,设置CircleRadiusCollisionGroup - 状态动作:+ 在
StateComponent中注册AvatarStateAnimationComponent.StateToAvatarBodyActionSheet/ATTACK/HIT等状态DEAD - HP处理:玩家使用,怪物使用自定义
PlayerComponent.Hp@Sync Hp - 方向判定:使用(禁止使用Scale.x)
LookDirectionX - 时间基准:使用(禁止使用os.clock)
_UtilLogic.ElapsedSeconds - 事件清理:在中显式调用
OnEndPlay断开事件DisconnectEvent - Body规则:禁止对有Body激活的实体直接赋值
TransformComponent.Position
14. 커스텀 구현이 필수
必须自定义实现的内容
Buff/Debuff · BT Decorator/Memory(Blackboard) · Aggro/Threat Table · 투사체 풀링 · 관통/최대 히트 수 · 경직 레벨 체계 · 자원(MP/Stamina/Rage) · 콤보·캔슬 윈도 · 가드/패링 · 세계→스크린 좌표 변환 · 월드스페이스 HP바
Buff/Debuff · BT Decorator/记忆(Blackboard) · 仇恨/威胁表 · 投射物池 · 穿透/最大命中数 · 僵直等级体系 · 资源(MP/耐力/怒气) · 连招/取消窗口 · 格挡/弹反 · 世界→屏幕坐标转换 · 世界空间HP条
비범위
非覆盖范围
- 플레이어 전반(HP/이동/카메라/코스튬 외):
msw-defaultplayer - mlua 일반 문법·라이프사이클:
msw-scripting - 저작 규칙·템플릿:
.modelmsw-general
- 玩家整体内容(HP/移动/相机/服装之外):
msw-defaultplayer - mlua通用语法·生命周期:
msw-scripting - 创作规则·模板:
.modelmsw-general