如何根据所述数组的长度重命名数组中的元素? (在 Unity 检查器中)

Posted

技术标签:

【中文标题】如何根据所述数组的长度重命名数组中的元素? (在 Unity 检查器中)【英文标题】:How to rename elements in an array based on the length of said array? (In the Unity Inspector) 【发布时间】:2021-05-21 03:52:57 【问题描述】:

我正在尝试创建一个程序动画引擎。因为我使用叉积来计算身体的方向,所以腿需要在数组中按特定顺序排列。

我想确保它对任何使用它的人来说都是直观的,所以理想情况下,我希望它根据数组的长度重命名检查器中的元素。

示例: ideal example

【问题讨论】:

【参考方案1】:

这种东西是通过实现CustomEditor或者CustomPropertyDrawer来实现的

让我们例如说你的班级看起来像

public class DynamicLegList : MonoBehaviour

    public LegStepper[] Legs;

然后你可以实现你通过例如展示的东西

// Since the UnityEditor namespace is completely stripped of during the build process 
// this should be placed in a folder called "Editor"
// or if using Assemblies this should be placed in a separate Assembly which
// is excluded from any platform except the UnityEditor itself
[CustomEditor(typeof(DynamicLegList))]
internal class DynamicLegListEditor : Editor

    private SerializedProperty legs;

    private void OnEnable()
    
        legs = serializedObject.FindProperty(nameof(DynamicLegList.Legs));
    

    private readonly Dictionary<int, Dictionary<int, string>> legNames = new Dictionary<int, Dictionary<int, string>>
    
        
            2, new Dictionary<int, string>()
            
                0, "RightLeg",
                1, "LeftLeg",
            
        ,
        
            4, new Dictionary<int, string>()
            
                0, "FrontRightLeg",
                1, "FrontLeftLeg",
                2, "BackRightLeg",
                3, "BackLeftLeg"
            
        
    ;


    private int count;

    public override void OnInspectorGUI()
    
        DrawScriptField();

        serializedObject.Update();

        legs.isExpanded = EditorGUILayout.Foldout(legs.isExpanded, legs.displayName, true);
        if (legs.isExpanded)
        
            EditorGUI.indentLevel++;
            
                EditorGUI.BeginChangeCheck();
                
                    count = EditorGUILayout.IntField("Size", legs.arraySize);
                
                if (EditorGUI.EndChangeCheck())
                
                    if (count == 1 || legNames.ContainsKey(count))
                    
                        legs.arraySize = count;
                    
                

                if (legs.arraySize == 1)
                
                    var leg = legs.GetArrayElementAtIndex(0);
                    EditorGUILayout.PropertyField(leg, new GUIContent("Leg"));
                
                else
                
                    if (legNames.TryGetValue(legs.arraySize, out var names))
                    
                        for (var i = 0; i < legs.arraySize; i++)
                        
                            var leg = legs.GetArrayElementAtIndex(i);
                            EditorGUILayout.PropertyField(leg, new GUIContent(names[i]));
                        
                    
                
            
            EditorGUI.indentLevel--;
        

        serializedObject.ApplyModifiedProperties();
    

    private void DrawScriptField()
    
        EditorGUI.BeginDisabledGroup(true);
        
            EditorGUILayout.ObjectField("Script", MonoScript.FromMonoBehaviour((DynamicLegList) target), typeof(DynamicLegList), false);
        
        EditorGUI.EndDisabledGroup();
    

结果:

【讨论】:

这太棒了!我的最后一个问题(而不是菜鸟问题)是我如何从另一个脚本中使用它,而不是“动态腿列表” @FaffyWaffles 你不会 ;) 你需要为每个不同的组件类型再次实现这个。或者如前所述,您可以将其设为PropertyDrawer,然后您可以在多个组件中拥有相同的字段类型

以上是关于如何根据所述数组的长度重命名数组中的元素? (在 Unity 检查器中)的主要内容,如果未能解决你的问题,请参考以下文章

试图了解如何在 Go 中重命名字节数组

重命名 PHP 数组键并维护元素数据

Java数组元素去重(不使用集合)

Java数组元素去重(不使用集合)

如何增加数组长度和删去数组中的某个元素?

重命名数组中的子文档字段