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

Unity中关联变量与枚举的更优方案?替代数组实现Inspector易读展示

可行的Inspector友好型实现方案

方案1:自定义可序列化抗性条目结构体(推荐)

直接把伤害类型和对应抗性值封装成可序列化结构体,用列表或数组存储,Inspector里每个条目会清晰显示对应的伤害类型和数值,完全无需注释。

代码示例:

using System.Collections.Generic;
using UnityEngine;

public enum SpecialDamageType
{
    Physical,
    Fire,
    Cold,
    Lightning,
    Hydro,
    Air,
}

// 可序列化的抗性条目结构体
[System.Serializable]
public struct ResistanceEntry
{
    public SpecialDamageType damageType;
    [Range(0f, 1f)] // 可选:限制抗性值范围(0=无抗性,1=免疫)
    public float resistanceValue;
}

public abstract class EnemyParent : ScriptableObject
{
    [Header("Enemy Details")]
    [SerializeField] public string enemyName;
    [SerializeField] public string enemyDesc;

    [Header("Enemy Stats")]
    [SerializeField] public float enemyMaxHealthf;
    [SerializeField] protected float enemyArmourf;
    [SerializeField] protected float enemyMaxShield;
    [SerializeField] protected float enemyWalkSpeed;
    [SerializeField] protected float enemyRunSpeed;

    [Header("Elemental Resistances")]
    [SerializeField] private List<ResistanceEntry> enemyResistances;

    // 提供获取抗性的方法
    public float GetResistance(SpecialDamageType damageType)
    {
        foreach (var entry in enemyResistances)
        {
            if (entry.damageType == damageType)
            {
                return entry.resistanceValue;
            }
        }
        return 0f; // 默认无抗性
    }
}

该方案优势:

  • Inspector中每个抗性条目明确显示类型与数值,直观易懂
  • 灵活支持新增/删除抗性条目,无需修改类结构
  • 可通过[Range]属性限制数值范围,避免不合理输入

方案2:为每个枚举类型定义单独字段

如果SpecialDamageType枚举不会频繁新增类型,直接给每个伤害类型定义对应抗性字段,Inspector里字段名直接对应抗性类型,可读性拉满。

代码示例:

public abstract class EnemyParent : ScriptableObject
{
    // 原有字段省略...

    [Header("Elemental Resistances")]
    [Range(0f, 1f)] public float physicalResistance;
    [Range(0f, 1f)] public float fireResistance;
    [Range(0f, 1f)] public float coldResistance;
    [Range(0f, 1f)] public float lightningResistance;
    [Range(0f, 1f)] public float hydroResistance;
    [Range(0f, 1f)] public float airResistance;

    // 获取抗性的方法
    public float GetResistance(SpecialDamageType damageType)
    {
        return damageType switch
        {
            SpecialDamageType.Physical => physicalResistance,
            SpecialDamageType.Fire => fireResistance,
            SpecialDamageType.Cold => coldResistance,
            SpecialDamageType.Lightning => lightningResistance,
            SpecialDamageType.Hydro => hydroResistance,
            SpecialDamageType.Air => airResistance,
            _ => 0f
        };
    }
}

该方案优势:

  • Inspector中无需额外理解,字段名直接对应抗性类型
  • 代码逻辑简单,无需遍历列表
    缺点:枚举新增类型时,需手动添加对应字段和switch分支

方案3:自定义PropertyDrawer(进阶)

如果想保留数组的高效性,同时让Inspector显示枚举名称,可自定义PropertyDrawer替换数组元素的显示方式(需写编辑器脚本,适合有编辑器开发经验的场景)。

核心思路:创建自定义PropertyDrawer,绘制数组元素时自动显示对应索引的枚举名称。

编辑器脚本(需放在Editor文件夹下):

using UnityEditor;
using UnityEngine;

[CustomPropertyDrawer(typeof(float), true)]
public class ResistanceArrayDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        // 匹配抗性数组字段(这里假设字段名为enemyResistances)
        if (property.name == "enemyResistances" && property.parent != null)
        {
            int index = int.Parse(property.propertyPath.Split('[')[1].Split(']')[0]);
            SpecialDamageType damageType = (SpecialDamageType)index;
            label.text = damageType.ToString();
        }
        EditorGUI.PropertyField(position, property, label);
    }
}

EnemyParent中定义数组:

[Header("Elemental Resistances")]
[SerializeField] private float[] enemyResistances = new float[System.Enum.GetValues(typeof(SpecialDamageType)).Length];

该方案优势:保留数组性能的同时,Inspector里每个数组元素标签显示对应枚举名称,解决原数组方案的可读性问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 14:41:25