You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于继承实现回合制战术游戏脚本化技能的最优方案

回合制战术游戏技能系统实现方案

针对你遇到的Unity技能序列化与类型识别问题,这里有几个实用的解决思路:

方案一:用ScriptableObject实现技能(推荐)

ScriptableObject天生适合做可复用的技能模板,而且支持[SerializeReference]特性,能完美保留子类类型信息。

  1. 定义技能基类(继承ScriptableObject)
using UnityEngine;

public abstract class AbilitySO : ScriptableObject
{
    // 技能名称、图标等公共属性
    public string abilityName;
    public Sprite icon;

    // 抽象激活方法,传入施法单位、目标等上下文
    public abstract void ActivateAbility(Unit caster, GameObject target = null);
}
  1. 实现具体技能子类
[CreateAssetMenu(fileName = "Fireball", menuName = "Abilities/Fireball")]
public class FireballAbility : AbilitySO
{
    public int damage = 20;
    public float radius = 3f;

    public override void ActivateAbility(Unit caster, GameObject target)
    {
        // 实现火球技能逻辑:AOE伤害、特效播放等
        Collider[] hitTargets = Physics.OverlapSphere(target.transform.position, radius);
        foreach (Collider col in hitTargets)
        {
            if (col.TryGetComponent<Health>(out Health health))
            {
                health.TakeDamage(damage);
            }
        }
    }
}
  1. 单位脚本中配置技能列表
using UnityEngine;
using System.Collections.Generic;

public class Unit : MonoBehaviour
{
    // 用[SerializeReference]让Unity序列化时保留子类类型
    [SerializeReference]
    public List<AbilitySO> abilities = new List<AbilitySO>();

    // 绑定UI按钮的方法,通过索引触发技能
    public void CastAbility(int abilityIndex)
    {
        if (abilityIndex >= 0 && abilityIndex < abilities.Count)
        {
            // 这里需要传入施法单位和目标(可以根据游戏逻辑获取选中目标)
            abilities[abilityIndex].ActivateAbility(this, GetSelectedTarget());
        }
    }

    private GameObject GetSelectedTarget()
    {
        // 实现获取当前选中目标的逻辑
        return null;
    }
}

在编辑器里,你可以右键创建Fireball等技能资产,直接拖入Unit组件的abilities列表,Unity会正确显示技能的子类类型和专属参数。

方案二:MonoBehaviour技能+主动收集子类组件

如果必须用MonoBehaviour挂载技能,可以放弃序列化列表,改为在初始化时主动收集所有技能组件,利用多态执行逻辑。

  1. 技能基类(MonoBehaviour)
using UnityEngine;

public abstract class AbilityBase : MonoBehaviour
{
    public string abilityName;
    public Sprite icon;

    public abstract void ActivateAbility(Unit caster, GameObject target = null);
}
  1. 具体技能子类
public class HealAbility : AbilityBase
{
    public int healAmount = 15;

    public override void ActivateAbility(Unit caster, GameObject target)
    {
        if (target.TryGetComponent<Health>(out Health health))
        {
            health.Heal(healAmount);
        }
    }
}
  1. 单位脚本收集技能
using UnityEngine;
using System.Collections.Generic;

public class Unit : MonoBehaviour
{
    private List<AbilityBase> abilities = new List<AbilityBase>();

    private void Awake()
    {
        // 收集所有子物体上的AbilityBase子类组件
        abilities.AddRange(GetComponentsInChildren<AbilityBase>(true));
    }

    // UI按钮触发技能
    public void CastAbility(int abilityIndex)
    {
        if (abilityIndex >= 0 && abilityIndex < abilities.Count)
        {
            abilities[abilityIndex].ActivateAbility(this, GetSelectedTarget());
        }
    }

    private GameObject GetSelectedTarget()
    {
        // 实现获取目标逻辑
        return null;
    }
}

把每个技能脚本挂在Unit的子GameObject上,Awake时会自动收集所有技能,调用ActivateAbility时会自动执行子类的重写逻辑,不需要关心类型转换。

方案三:自定义编辑器扩展(可选)

如果需要在编辑器里直接给Unit添加指定类型的技能,可以写个自定义编辑器:

using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(Unit))]
public class UnitEditor : Editor
{
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
        Unit unit = (Unit)target;

        if (GUILayout.Button("Add Fireball Ability"))
        {
            GameObject child = new GameObject("Fireball Ability");
            child.transform.parent = unit.transform;
            child.AddComponent<FireballAbility>();
        }

        if (GUILayout.Button("Add Heal Ability"))
        {
            GameObject child = new GameObject("Heal Ability");
            child.transform.parent = unit.transform;
            child.AddComponent<HealAbility>();
        }
    }
}

这样在编辑器里就能一键给单位添加指定技能,避免手动创建子物体的麻烦。

内容的提问来源于stack exchange,提问作者novawhelk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 21:55:44