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

Unity Inspector中为PlayerClass创建护甲集下拉列表

问题

我是C#新手,正在自学并借助教程开发背包系统。我使用ScriptableObject按套装存储所有护甲,现在需要在PlayerClass ScriptableObject的Inspector面板中,为不同职业设置默认护甲时,能从Armor脚本中已创建的护甲列表选择(即让startingArmorSet变为下拉列表)。

我的Armor Collection代码:

public class ArmorCollection : ScriptableObject
{
    [System.Serializable]
    private class ArmorSet
    {
        public string armorSetName;
       //gear sprites and stats are below this in this nested class
    }

    [SerializeField] List<ArmorSet> armorSet;
    
    private Dictionary<int, string> setName; //not sure if it should be a List or Dictionary currently
    [HideInInspector] public Dictionary<int, string> SetName { get => setName; }

    private void OnValidate()
    {
        for (int i = 0; i < armorSet.Count; i++)

        {
            setName.Add(i+1,armorSet[i].armorSetName);
        }
    }
}

我的Player Class脚本当前卡在这部分:

public class PlayerClass : ScriptableObject
{

    [SerializeField] PlayerStats playerData;
    [SerializeField] PlayerGear gear;
    [SerializeField] ArmorCollection armor; 
    
    [Space]
    [SerializeField] string className;

    [Header("Gear")]
    [SerializeField] string startingArmorSet; //needs to be a dropdown list
}

我曾考虑用枚举,但枚举是只读的,不符合需求。我需要能根据不同ScriptableObject(默认职业护甲、普通护甲、稀有护甲等)动态变更下拉选项,目前纠结setName用List还是Dictionary,不知道如何在PlayerClass脚本中实现下拉列表功能,求帮助。


解决方案

1. 重构ArmorCollection逻辑

放弃Dictionary,改用List存储护甲套装名称更适配动态下拉需求,同时修复OnValidate的空引用问题:

public class ArmorCollection : ScriptableObject
{
    [System.Serializable]
    private class ArmorSet
    {
        public string armorSetName;
        // 保留原有装备精灵、属性等字段
    }

    [SerializeField] private List<ArmorSet> armorSets;
    [HideInInspector] public List<string> ArmorSetNames { get; private set; }

    private void OnValidate()
    {
        ArmorSetNames = new List<string>();
        foreach (var set in armorSets)
        {
            if (!string.IsNullOrEmpty(set.armorSetName))
            {
                ArmorSetNames.Add(set.armorSetName);
            }
        }
    }
}
  • 把armorSet改为armorSets(命名更规范)
  • 用List<string>存储套装名称,每次OnValidate触发时重新生成列表,避免重复添加的错误

2. 编写自定义Inspector下拉扩展

要实现动态下拉,需要创建两个脚本(放在Editor文件夹下,否则无法识别为编辑器扩展):

第一步:创建属性标记类

using UnityEngine;

public class ArmorSetDropdownAttribute : PropertyAttribute
{
}

第二步:创建PropertyDrawer实现下拉逻辑

using UnityEditor;
using UnityEngine;

[CustomPropertyDrawer(typeof(ArmorSetDropdownAttribute))]
public class ArmorSetDropdownDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        var playerClass = property.serializedObject.targetObject as PlayerClass;
        if (playerClass == null || playerClass.armor == null)
        {
            EditorGUI.PropertyField(position, property, label);
            return;
        }

        var armorNames = playerClass.armor.ArmorSetNames;
        if (armorNames == null || armorNames.Count == 0)
        {
            EditorGUI.PropertyField(position, property, label);
            return;
        }

        int selectedIndex = armorNames.IndexOf(property.stringValue);
        selectedIndex = selectedIndex < 0 ? 0 : selectedIndex;

        selectedIndex = EditorGUI.Popup(position, label, selectedIndex, armorNames.ToArray());
        property.stringValue = armorNames[selectedIndex];
    }
}

3. 修改PlayerClass脚本

给startingArmorSet添加自定义属性标记,启用下拉功能:

public class PlayerClass : ScriptableObject
{
    [SerializeField] PlayerStats playerData;
    [SerializeField] PlayerGear gear;
    [SerializeField] ArmorCollection armor; 
    
    [Space]
    [SerializeField] string className;

    [Header("Gear")]
    [ArmorSetDropdown] // 新增标记
    [SerializeField] string startingArmorSet;
}

关键注意点

  • 所有Editor脚本必须放在项目的Editor文件夹内,Unity才会将其识别为编辑器扩展代码
  • 确保ArmorCollection中的护甲套装名称唯一,否则下拉框会选中第一个匹配项
  • 当你修改ArmorCollection中的护甲套装时,PlayerClass的Inspector会自动刷新下拉选项(OnValidate触发更新)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 02:34:52