Files
heros/.qoder/repowiki/zh/content/英雄系统/技能系统/技能系统.md
panw 4235e3b776 refactor(game): 移除已弃用的事件常量
- 删除 UpdateHero 和 UpdateFightHero 事件
- 移除 MISSION_UPDATE 事件常量
- 优化游戏事件枚举定义
2025-10-28 16:15:47 +08:00

21 KiB
Raw Blame History

技能系统

**本文档中引用的文件** - [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts) - [SkillConComp.ts](file://assets/script/game/hero/SkillConComp.ts) - [SkillEnt.ts](file://assets/script/game/skill/SkillEnt.ts) - [SkillViewCom.ts](file://assets/script/game/skill/SkillViewCom.ts) - [AtkConCom.ts](file://assets/script/game/skill/AtkConCom.ts) - [HeroViewComp.ts](file://assets/script/game/hero/HeroViewComp.ts) - [Tooltip.ts](file://assets/script/game/skill/Tooltip.ts)

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构概览
  5. 详细组件分析
  6. 技能配置系统
  7. 技能控制机制
  8. 技能释放流程
  9. 异常处理与最佳实践
  10. 性能考虑
  11. 故障排除指南
  12. 总结

简介

技能系统是游戏战斗的核心机制负责管理角色的技能释放、冷却时间、目标选择、特效播放等关键功能。本系统采用ECS架构设计通过模块化的方式实现了技能的完整生命周期管理包括技能配置、控制、执行和特效展示。

项目结构

技能系统的文件组织遵循模块化原则,主要分为以下几个部分:

graph TB
subgraph "配置层"
A[SkillSet.ts<br/>技能配置表]
end
subgraph "控制层"
B[SkillConComp.ts<br/>技能控制组件]
end
subgraph "执行层"
C[SkillEnt.ts<br/>技能实体]
D[SkillViewCom.ts<br/>技能视图组件]
E[AtkConCom.ts<br/>攻击控制组件]
end
subgraph "支持层"
F[HeroViewComp.ts<br/>英雄视图组件]
G[Tooltip.ts<br/>提示系统]
end
A --> B
B --> C
C --> D
D --> E
B --> F
E --> G

图表来源

章节来源

核心组件

技能系统由以下核心组件构成:

技能配置表 (SkillSet)

负责定义技能的所有属性和行为规则,包括技能类型、目标群体、伤害类型、冷却时间等关键字段。

技能控制组件 (SkillConComp)

管理技能的触发逻辑、冷却时间计算、目标选择和定时器资源管理。

技能实体 (SkillEnt)

负责技能的实例化、特效加载和生命周期管理。

技能视图组件 (SkillViewCom)

处理技能的视觉表现、动画播放和位置计算。

攻击控制组件 (AtkConCom)

实现具体的攻击逻辑、碰撞检测和伤害计算。

章节来源

架构概览

技能系统采用分层架构设计,确保各组件职责清晰、耦合度低:

graph TD
subgraph "表现层"
A[技能视图组件<br/>SkillViewCom]
B[特效播放<br/>Animation/Particle]
end
subgraph "控制层"
C[技能控制组件<br/>SkillConComp]
D[攻击控制组件<br/>AtkConCom]
end
subgraph "数据层"
E[技能实体<br/>SkillEnt]
F[技能配置<br/>SkillSet]
end
subgraph "业务层"
G[英雄视图组件<br/>HeroViewComp]
H[目标选择<br/>selectTargets]
end
A --> C
C --> E
E --> F
C --> G
D --> A
G --> H
B --> D

图表来源

详细组件分析

技能配置系统 (SkillSet)

技能配置系统是整个技能体系的基础,定义了技能的所有属性和行为规则。

技能类型枚举 (SType)

类型 描述 用途
damage 0 伤害技能 对目标造成物理/魔法伤害
heal 1 治疗技能 恢复目标生命值
shield 2 护盾技能 为目标添加护盾
atk_speed 3 攻击速度提升 提升攻击速度
power_up 4 力量提升 提升攻击力
ap_up 5 法术强度提升 提升法术伤害
dod_up 6 闪避提升 提升闪避率
crit_up 7 暴击率提升 提升暴击率
crit_dmg_up 8 暴击伤害提升 提升暴击伤害
wfuny_up 9 连击率提升 提升连击触发概率
zhaohuan 10 召唤技能 召唤生物协助战斗
buff 11 增益技能 为目标添加增益效果

目标群体枚举 (TGroup)

群体 描述 适用场景
Self 0 自身 自身增益、治疗技能
Ally 1 所有敌人 团队治疗、辅助技能
Team 2 所有友方 团队增益、保护技能
Enemy 3 敌方单位 输出技能、控制技能
All 4 所有单位 全局效果、范围伤害

伤害类型枚举 (DTType)

类型 描述 特点
single 0 单体伤害 针对单一目标
range 1 范围伤害 对多个目标造成伤害

关键字段说明

classDiagram
class SkillConfig {
+number uuid
+string name
+string sp_name
+AtkedName AtkedName
+string path
+TGroup TGroup
+SType SType
+string act
+DTType DTType
+DType DType
+number ap
+number cd
+number t_num
+number hit_num
+number hit
+number hitcd
+number speed
+number cost
+number with
+BuffConf[] buffs
+NeAttrsConf[] neAttrs
+string info
+number hero
}
class BuffConf {
+Attrs buff
+BType BType
+number value
+number time
+number chance
}
class NeAttrsConf {
+NeAttrs neAttrs
+number value
+number time
}
SkillConfig --> BuffConf : "包含"
SkillConfig --> NeAttrsConf : "包含"

图表来源

章节来源

技能控制组件 (SkillConComp)

技能控制组件负责技能的整体管理和触发逻辑,是技能系统的核心控制器。

主要功能

  1. 冷却时间管理

    • 监控技能冷却进度
    • 自动重置冷却时间
    • 处理技能消耗检查
  2. 自动施法条件判断

    • 检查角色状态(眩晕、冰冻等)
    • 验证魔法值充足
    • 判断攻击状态冲突
  3. 多段技能连发机制

    • 实现wfuny连击系统
    • 控制技能释放间隔
    • 管理连击计数器
  4. 目标选择策略

    • 基于阵营的目标查询
    • 前排/后排目标优先级
    • 随机目标选择算法

核心方法分析

sequenceDiagram
participant Player as 玩家输入
participant SkillCon as 技能控制组件
participant HeroView as 英雄视图
participant SkillEnt as 技能实体
participant AtkCon as 攻击控制
Player->>SkillCon : 更新技能冷却
SkillCon->>SkillCon : 检查冷却时间
SkillCon->>HeroView : 检查角色状态
HeroView-->>SkillCon : 状态验证结果
SkillCon->>SkillCon : 选择目标
SkillCon->>HeroView : 播放技能特效
SkillCon->>SkillEnt : 创建技能实体
SkillEnt->>AtkCon : 初始化攻击组件
AtkCon->>AtkCon : 执行攻击逻辑

图表来源

章节来源

技能实体 (SkillEnt)

技能实体负责技能的实例化和生命周期管理,确保技能能够正确地在游戏中表现。

实体创建流程

flowchart TD
A[技能触发] --> B[加载技能配置]
B --> C{配置是否存在?}
C --> |否| D[输出错误日志]
C --> |是| E[检查施法者]
E --> F{施法者是否存在?}
F --> |否| D
F --> |是| G[加载特效预制体]
G --> H{预制体加载成功?}
H --> |否| D
H --> |是| I[实例化特效节点]
I --> J[设置节点属性]
J --> K[添加技能组件]
K --> L[技能实体就绪]
D --> M[结束]
L --> N[等待执行时机]
N --> O[执行技能逻辑]

图表来源

章节来源

技能视图组件 (SkillViewCom)

技能视图组件处理技能的视觉表现和动画播放,是技能外观效果的主要控制者。

动画类型支持

类型 描述 实现方式
linear 0 直线运动 线性插值移动
bezier 1 贝塞尔曲线 贝塞尔曲线轨迹
fixed 2 固定起点 起点固定,终点动态
fixedEnd 3 固定终点 终点固定,起点动态

章节来源

攻击控制组件 (AtkConCom)

攻击控制组件实现具体的攻击逻辑,包括碰撞检测、伤害计算和效果应用。

碰撞检测机制

flowchart TD
A[技能移动] --> B[检测碰撞]
B --> C{是否接触敌方}
C --> |否| D[继续移动]
C --> |是| E[检查穿透次数]
E --> F{达到最大穿透?}
F --> |是| G[销毁技能]
F --> |否| H[计算伤害]
H --> I[应用伤害效果]
I --> J[增加穿透计数]
J --> K{范围伤害?}
K --> |是| L[对范围内所有目标]
K --> |否| M[仅对当前目标]
L --> N[继续移动]
M --> N
D --> N
G --> O[结束]

图表来源

章节来源

技能配置系统

技能配置系统是技能系统的基础通过SkillSet.ts定义了所有技能的属性和行为规则。

配置表结构

技能配置表采用Record结构以技能UUID作为键SkillConfig接口作为值

export const SkillSet: Record<number, SkillConfig> = {
    6001: {
        uuid: 6001,
        name: "挥击",
        sp_name: "atk_s1",
        AtkedName: AtkedName.atked,
        path: "3036",
        TGroup: TGroup.Enemy,
        SType: SType.damage,
        act: "atk",
        DTType: DTType.single,
        DType: DType.ATK,
        ap: 100,
        cd: 1,
        t_num: 1,
        hit_num: 1,
        hit: 1,
        hitcd: 0.2,
        speed: 720,
        cost: 0,
        with: 0,
        buffs: [],
        neAttrs: [],
        info: "向最前方敌人扔出石斧,造成100%攻击的伤害"
    },
    // 更多技能配置...
}

关键配置字段详解

字段 类型 描述 默认值 说明
uuid number 技能唯一标识符 - 必需,用于技能识别
name string 技能名称 - 显示用名称
sp_name string 特效名称 - 对应特效资源文件名
TGroup TGroup 目标群体 - 技能作用目标类型
SType SType 技能类型 - 技能效果类型
cd number 冷却时间 - 技能冷却秒数
cost number 消耗值 - 魔法值或能量消耗
ap number 伤害倍率 - 伤害相对于攻击力的百分比
hit number 穿透次数 0 攻击可穿透的目标数量
hitcd number 持续伤害间隔 0 持续伤害的触发间隔

章节来源

技能控制机制

技能控制机制是技能系统的核心,负责技能的触发、冷却管理和执行逻辑。

冷却时间管理系统

冷却时间管理采用增量式计算,每帧更新技能的冷却进度:

flowchart TD
A[技能冷却开始] --> B[dt累积]
B --> C[检查冷却时间]
C --> D{是否达到冷却?}
D --> |否| E[继续累积]
D --> |是| F[检查魔法值]
F --> G{魔法值充足?}
G --> |否| H[等待补充]
G --> |是| I[触发技能]
E --> B
H --> F
I --> J[重置冷却时间]
J --> K[扣除魔法值]
K --> L[技能准备就绪]

图表来源

自动施法条件判断

系统在每次更新时检查多个条件:

  1. 战斗状态检查

    • 检查mission.play状态
    • 验证mission.pause状态
  2. 角色状态检查

    • 检查眩晕状态 (isStun())
    • 检查冰冻状态 (isFrost())
  3. 技能状态检查

    • 验证冷却时间是否完成
    • 检查魔法值是否足够
    • 确认攻击状态不冲突

多段技能连发机制

系统支持wfuny连击机制通过check_wfuny方法判断是否触发连击

sequenceDiagram
participant SkillCon as 技能控制
participant HeroView as 英雄视图
participant Timer as 定时器系统
SkillCon->>HeroView : 检查wfuny属性
HeroView-->>SkillCon : 返回连击概率
SkillCon->>SkillCon : 随机数生成
alt 触发连击
SkillCon->>Timer : 设置延迟执行
Timer->>SkillCon : 延迟后再次执行
SkillCon->>SkillCon : 递归调用doSkill
else 未触发连击
SkillCon->>SkillCon : 正常结束
end

图表来源

章节来源

技能释放流程

技能释放是一个复杂的多阶段过程,涉及预判、特效播放、实体生成等多个环节。

技能释放全过程

sequenceDiagram
participant Player as 玩家操作
participant SkillCon as 技能控制
participant HeroView as 英雄视图
participant SkillEnt as 技能实体
participant AtkCon as 攻击控制
participant Target as 目标对象
Player->>SkillCon : 发起技能请求
SkillCon->>SkillCon : 验证技能可用性
SkillCon->>HeroView : 播放技能动画
HeroView-->>SkillCon : 动画播放完成
SkillCon->>SkillCon : 创建技能实体
SkillCon->>SkillEnt : 加载技能配置
SkillEnt->>SkillEnt : 实例化特效节点
SkillEnt->>AtkCon : 添加攻击组件
AtkCon->>AtkCon : 初始化技能参数
AtkCon->>Target : 开始攻击逻辑
Target-->>AtkCon : 碰撞检测结果
AtkCon->>AtkCon : 计算伤害效果
AtkCon->>Target : 应用伤害效果
AtkCon->>AtkCon : 检查技能结束条件
alt 技能需要多段
AtkCon->>AtkCon : 继续下一段攻击
else 技能结束
AtkCon->>AtkCon : 销毁技能实体
end

图表来源

目标选择策略

目标选择是技能系统的重要组成部分,采用智能算法确定技能目标:

flowchart TD
A[开始目标选择] --> B[查询目标实体]
B --> C{是否有目标?}
C --> |否| D[返回默认位置]
C --> |是| E[确定前排目标]
E --> F[添加前排目标到列表]
F --> G{还需要更多目标?}
G --> |否| H[返回目标列表]
G --> |是| I[随机选择剩余目标]
I --> J[添加到目标列表]
J --> K{达到目标数量?}
K --> |否| G
K --> |是| H
D --> L[填充默认位置]
L --> H

图表来源

定时器资源管理

系统使用定时器管理技能的延迟执行,确保技能释放的精确控制:

定时器类型 用途 生命周期 清理方式
技能延迟定时器 技能特效延迟播放 技能生命周期内 技能结束后清理
连击延迟定时器 多段技能间隔 连击期间 连击结束时清理
冷却定时器 技能冷却倒计时 技能冷却期间 冷却完成时清理

章节来源

异常处理与最佳实践

技能系统在设计时充分考虑了各种异常情况,提供了完善的错误处理机制。

节点有效性检查

系统在关键操作前进行节点有效性检查,防止因节点被销毁导致的异常:

private doSkill(config: typeof SkillSet[keyof typeof SkillSet], is_wfuny: boolean = false, dmg: number = 0) {
    // 添加节点有效性检查
    if (!this.node || !this.node.isValid || !this.HeroView || !this.HeroView.node || !this.HeroView.node.isValid) {
        return;
    }
    
    // 技能执行逻辑
    
    // 再次检查节点有效性
    if (!this.node || !this.node.isValid || !this.HeroView || !this.HeroView.node || !this.HeroView.node.isValid) {
        return;
    }
}

异常处理策略

  1. 技能配置缺失处理

    load(startPos: Vec3, parent: Node, uuid: number, targetPos: any[], caster: HeroViewComp = null, dmg: number = 0) {
        const config = SkillSet[uuid];
        if (!config) {
            console.error("[Skill] 技能配置不存在:", uuid);
            return;
        }
    }
    
  2. 资源加载失败处理

    const prefab: Prefab = oops.res.get(path, Prefab);
    if (!prefab) {
        console.error("[Skill] 预制体加载失败:", path);
        return;
    }
    
  3. 战斗状态异常处理

    update(dt: number) {
        if (!smc.mission.play || smc.mission.pause) return;
        // 技能逻辑执行
    }
    

最佳实践建议

  1. 资源管理

    • 及时清理定时器资源
    • 正确释放技能实体
    • 避免内存泄漏
  2. 性能优化

    • 使用对象池管理技能实体
    • 减少不必要的对象创建
    • 优化碰撞检测频率
  3. 错误恢复

    • 提供默认行为处理异常
    • 记录详细的错误日志
    • 实现优雅降级机制

章节来源

性能考虑

技能系统在设计时充分考虑了性能优化,采用了多种策略确保流畅的游戏体验。

对象池管理

技能实体采用对象池模式,避免频繁的对象创建和销毁:

// 在SkillConComp中维护定时器映射
private _timers: { [key: string]: any } = {};

// 定时器资源管理
public clear_timer() {
    Object.values(this._timers).forEach(clearTimeout);
}

onDestroy() {
    // 清理所有定时器
    Object.values(this._timers).forEach(clearTimeout);
    this._timers = {};
}

内存优化策略

  1. 延迟加载

    • 技能特效按需加载
    • 避免一次性加载所有技能资源
  2. 引用管理

    • 使用浅拷贝传递技能属性
    • 避免深层复制造成的性能开销
  3. 生命周期管理

    • 及时销毁不需要的技能实体
    • 清理事件监听器和定时器

碰撞检测优化

攻击控制组件采用高效的碰撞检测算法:

// 范围伤害优化
public atk(args: any) {
    let targetsInRange: HeroViewComp[] = [];
    
    // 使用ECS查询优化目标查找
    ecs.query(ecs.allOf(HeroViewComp)).some(e => {
        const view = e.get(HeroViewComp);
        if (view.fac != this.fac) {
            const distance = Math.abs(this.node.position.x - view.node.position.x);
            if (distance <= dis) {
                targetsInRange.push(view);
            }
        }
    });
}

故障排除指南

常见问题及解决方案

技能无法触发

症状: 技能按下后没有反应 可能原因:

  1. 冷却时间未完成
  2. 魔法值不足
  3. 角色处于异常状态
  4. 技能配置缺失

解决步骤:

  1. 检查技能冷却时间
  2. 验证角色魔法值
  3. 确认角色状态正常
  4. 检查SkillSet配置

特效播放异常

症状: 技能释放但没有特效 可能原因:

  1. 特效资源加载失败
  2. 节点被提前销毁
  3. 动画组件配置错误

解决步骤:

  1. 检查资源路径和文件名
  2. 验证节点有效性
  3. 确认动画组件正确绑定

目标选择错误

症状: 技能攻击了错误的目标 可能原因:

  1. 目标查询逻辑错误
  2. 阵营判断失误
  3. 前排/后排判定错误

解决步骤:

  1. 检查阵营判断逻辑
  2. 验证目标位置计算
  3. 确认优先级设置

章节来源

总结

技能系统是一个复杂而精密的战斗机制,通过合理的架构设计和完善的异常处理,实现了高效、稳定的技能管理功能。

系统优势

  1. 模块化设计: 各组件职责清晰,易于维护和扩展
  2. 性能优化: 采用对象池和延迟加载策略,确保流畅运行
  3. 异常处理: 完善的错误检查和恢复机制
  4. 灵活性: 支持多种技能类型和效果组合

技术特点

  1. ECS架构: 基于组件式设计,提高代码复用性
  2. 事件驱动: 通过事件系统实现组件间的松耦合通信
  3. 配置驱动: 技能行为完全由配置文件控制
  4. 资源管理: 完善的资源加载和释放机制

扩展建议

  1. 技能树系统: 可以在此基础上扩展技能升级和解锁机制
  2. 连携技能: 支持多个角色协同释放的组合技能
  3. 动态平衡: 根据玩家表现动态调整技能效果
  4. AI适配: 为AI敌人提供专门的技能释放策略

技能系统作为游戏战斗的核心,其设计理念和实现方式为类似项目的开发提供了宝贵的参考价值。