Unity3D技能编辑器架构设计与实现

设计思路

本技能系统采用"数据驱动+事件驱动"的混合架构,核心设计目标包括:

  1. 可视化配置:基于ScriptableObject实现技能参数配置
  2. 组件化设计:采用策略模式实现技能效果组件
  3. 时间轴控制:精确到帧的技能阶段管理
  4. 状态隔离:通过状态模式确保技能逻辑安全

核心架构

1. 技能数据结构

// 技能基础数据(ScriptableObject)
[CreateAssetMenu(fileName = "NewSkill", menuName = "Skill System/Skill Data")]
public class SkillData : ScriptableObject
{
    [Header("基础设置")]
    public string skillName;          // 技能名称
    public float cooldown = 1f;       // 冷却时间
    public Sprite icon;               // 技能图标
    
    [Header("阶段配置")] 
    public List<SkillPhase> phases = new List<SkillPhase>(); // 技能阶段列表
    
    [Header("资源引用")]
    public GameObject castVFX;        // 施法特效
    public AudioClip castSFX;         // 施法音效
}

// 技能阶段配置
[System.Serializable]
public class SkillPhase
{
    [Range(0, 5)] public float triggerTime; // 触发时间(秒)
    public SkillEffectType effectType;      // 效果类型
    public TargetSelectionStrategy targetStrategy; // 目标选择策略
    public EffectParams parameters;         // 效果参数
}

2. 技能系统核心

[RequireComponent(typeof(Animator))]
public class SkillSystem : MonoBehaviour
{
    private SkillData currentSkill;     // 当前释放的技能
    private float cooldownTimer;        // 冷却计时器
    private Coroutine castingCoroutine; // 施法协程
    
    // 开始释放技能
    public void StartCast(SkillData skill)
    {
        if(cooldownTimer > 0 || currentSkill != null) return;
        
        currentSkill = skill;
        castingCoroutine = StartCoroutine(CastingProcess());
    }

    // 施法过程协程
    private IEnumerator CastingProcess()
    {
        // 初始化状态
        PlayCastAnimation();
        SpawnVFX(currentSkill.castVFX);
        PlaySFX(currentSkill.castSFX);
        
        // 执行技能阶段
        foreach(var phase in currentSkill.phases)
        {
            yield return new WaitForSeconds(phase.triggerTime);
            
            // 获取目标
            var targets = SelectTargets(phase.targetStrategy);
            
            // 执行效果
            ExecuteEffect(phase.effectType, targets, phase.parameters);
        }
        
        // 结束处理
        currentSkill = null;
        cooldownTimer = currentSkill.cooldown;
    }

    // 目标选择策略
    private List<GameObject> SelectTargets(TargetSelectionStrategy strategy)
    {
        // 实现不同目标选择逻辑(示例:圆形范围选择)
        switch(strategy)
        {
            case TargetSelectionStrategy.Self:
                return new List<GameObject>{gameObject};
            case TargetSelectionStrategy.CircleRange:
                return Physics.OverlapSphere(transform.position, 5f)
                           .Select(c => c.gameObject).ToList();
            default:
                return new List<GameObject>();
        }
    }
}

3. 技能效果系统

// 效果接口
public interface ISkillEffect
{
    void Execute(GameObject caster, List<GameObject> targets, EffectParams parameters);
}

// 伤害效果实现
public class DamageEffect : ISkillEffect
{
    public void Execute(GameObject caster, List<GameObject> targets, EffectParams parameters)
    {
        foreach(var target in targets)
        {
            if(target.TryGetComponent<HealthSystem>(out var health))
            {
                float finalDamage = parameters.baseValue + 
                                  (parameters.isPercentDamage ? 
                                   health.maxHP * parameters.percentValue : 0);
                                   
                health.TakeDamage(finalDamage);
            }
        }
    }
}

// 投射物生成效果
public class SpawnProjectileEffect : ISkillEffect
{
    public void Execute(GameObject caster, List<GameObject> targets, EffectParams parameters)
    {
        var projectile = Instantiate(parameters.projectilePrefab, 
                                   caster.transform.position,
                                   caster.transform.rotation);
                                   
        var controller = projectile.GetComponent<ProjectileController>();
        controller.Initialize(caster, parameters);
    }
}

4. 投射物控制器

public class ProjectileController : MonoBehaviour
{
    private GameObject owner;
    private EffectParams effectParams;
    private Vector3 direction;
    
    public void Initialize(GameObject owner, EffectParams params)
    {
        this.owner = owner;
        this.effectParams = params;
        this.direction = owner.transform.forward;
        
        Destroy(gameObject, params.lifetime); // 自动销毁
    }

    private void Update()
    {
        // 移动逻辑
        transform.position += direction * effectParams.speed * Time.deltaTime;
    }

    private void OnTriggerEnter(Collider other)
    {
        if(other.gameObject == owner) return;
        
        // 触发命中效果
        var effect = SkillEffectFactory.Create(effectParams.effectType);
        effect.Execute(owner, new List<GameObject>{other.gameObject}, effectParams);
        
        Destroy(gameObject);
    }
}

关键设计解析

1. 时间轴管理

  • 使用协程的WaitForSeconds实现精确的阶段触发
  • 每个SkillPhase独立配置触发时间和效果参数
  • 支持前摇、持续效果、后摇等多阶段组合

2. 效果扩展机制

// 效果工厂(策略模式)
public class SkillEffectFactory
{
    private static Dictionary<SkillEffectType, ISkillEffect> effects = new Dictionary<SkillEffectType, ISkillEffect>()
    {
        {SkillEffectType.Damage, new DamageEffect()},
        {SkillEffectType.Heal, new HealEffect()},
        {SkillEffectType.SpawnProjectile, new SpawnProjectileEffect()}
    };

    public static ISkillEffect Create(SkillEffectType type)
    {
        return effects.ContainsKey(type) ? effects[type] : null;
    }
}

3. 数据验证系统

// 在SkillData中添加数据验证
private void OnValidate()
{
    // 自动排序阶段
    phases = phases.OrderBy(p => p.triggerTime).ToList();
    
    // 参数合法性检查
    foreach(var phase in phases)
    {
        if(phase.parameters.damage < 0) 
            phase.parameters.damage = 0;
    }
}

优化建议

  1. 对象池优化:对频繁生成的投射物和特效使用对象池
  2. 事件系统:通过事件总线上报技能状态(如OnSkillStart/OnSkillEnd)
  3. 性能分析:添加Profiler标记定位性能瓶颈
  4. 状态机整合:与Animator状态机深度集成,确保动画与逻辑同步
  5. 网络同步:添加Command/RPC方法实现多人同步

该实现方案具有以下技术特点:

  1. 通过ScriptableObject实现可视化配置
  2. 使用策略模式实现效果扩展
  3. 协程驱动的时间轴管理
  4. 组件化的目标选择策略
  5. 工厂模式管理效果实例

开发者可以通过继承ISkillEffect接口快速扩展新效果类型,配合Unity编辑器实现可视化的技能配置流程,满足大多数ARPG类游戏的技能系统需求。

你可能感兴趣的:(战斗系统设计,编辑器,开发语言)