Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
108 views
in Technique[技术] by (71.8m points)

c# - I'm trying to draw list items in the Inspector but it's not working how can I replace the element0,element1....with my own string?

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(PickupObjects))]
public class PickupObjectsEditor : Editor
{
    private static List<GameObject> pickeditems = new List<GameObject>();
    private static bool picked = false;
    private SerializedProperty _serializedpickeditems;

    [MenuItem("GameObject/Generate as Pickup Item", false, 30)]
    public static void GeneratePickupItems()
    {
        if (Selection.gameObjects.Length > 0)
        {
            for (int i = 0; i < Selection.gameObjects.Length; i++)
            {
                if (Selection.gameObjects[i].GetComponent<TestScript>() == null)
                {
                    Selection.gameObjects[i].AddComponent<BoxCollider>();
                    Selection.gameObjects[i].AddComponent<TestScript>();
                }

                Selection.gameObjects[i].layer = 9;
                Selection.gameObjects[i].tag = "Pickup Item";

                pickeditems.Add(Selection.gameObjects[i]);
            }

            picked = true;
        }
    }

    public override void OnInspectorGUI()
    {
        serializedObject.Update();

        PickupObjects myTarget = (PickupObjects)target;

        DrawDefaultInspector();

        if (picked == true)
        {
            for (int i = 0; i < pickeditems.Count; i++)
            {
                myTarget.pickUpObjects.Add(pickeditems[i]);

                var item = _serializedpickeditems.GetArrayElementAtIndex(i);
                var serializedItem = new SerializedObject(item.objectReferenceValue);
                serializedItem.Update();

                EditorGUILayout.PropertyField(item, new GUIContent("Picked Item " + i + " " + item.name));
                serializedItem.ApplyModifiedProperties();
            }

            pickeditems.Clear();
            picked = false;
            serializedObject.ApplyModifiedProperties();
        }
    }

    private void OnEnable()
    {
        _serializedpickeditems = serializedObject.FindProperty("pickUpObjects");
    }
}

And the mono script

using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class PickupObjects : MonoBehaviour
{
    public List<GameObject> pickUpObjects = new List<GameObject>();
}

I tried to use serialize and PropertyField but still it's showing the List with Element0,Element1,Element2.... And I want it to be :

Picked Item Box
Picked Item Can
Picked Item Cube
Picked Item Dock_Pod
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your

EditorGUILayout.PropertyField(item, new GUIContent("Picked Item " + i + " " + item.name));

sits within a code block that is only executed once.

What you see currently is actually only the list drawn by

DrawDefaultInspector();

since the rest is disappeared after 1 frame/draw call.


You would rather want to separate the pick "method" from the drawing like e.g.

public override void OnInspectorGUI()
{
    serializedObject.Update();

    if (picked)
    {
        for (var i = 0; i < pickeditems.Count; i++)
        {
            // NOTE: Never mix serializedProperties and direct access/modifications on the target!
            // This messes up the marking dirty and saving these changes!
            // Rather always go through the SerializedProperties so the editor handles everything automatically
            _serializedpickeditems.arraySize++;
            _serializedpickeditems.GetArrayElementAtIndex(i).objectReferenceValue = pickeditems[i];
        }

        picked = false;
        pickeditems.Clear();
    }

    for (var i = 0; i < _serializedpickeditems.arraySize; i++)
    {
        var item = _serializedpickeditems.GetArrayElementAtIndex(i);

        // little bonus from me: Color the field if the value is null ;)
        var color = GUI.color;
        if(!item.objectReferenceValue) GUI.color = Color.red;
        {
            EditorGUILayout.PropertyField(item, new GUIContent("Picked Item " + i + " " + (item.objectReferenceValue ? item.objectReferenceValue.name : "null")));
        }
        GUI.color = color;

        // The only case you would need to go deeper here and use 
        // your new SerializedObject would be if you actually make changes
        // to these objects/components like e.g. directly allow to edit their name
    }

    serializedObject.ApplyModifiedProperties();
}

Note you should also clear the pickeditems list before adding new items:

[MenuItem("GameObject/Generate as Pickup Item", false, 30)]
public static void GeneratePickupItems()
{
    if (Selection.gameObjects.Length > 0)
    {
        pickeditems.Clear();

        for (int i = 0; i < Selection.gameObjects.Length; i++)
        {
            if (Selection.gameObjects[i].GetComponent<Whilefun.FPEKit.FPEInteractablePickupScript>() == null)
            {
                Selection.gameObjects[i].AddComponent<BoxCollider>();
                Selection.gameObjects[i].AddComponent<Whilefun.FPEKit.FPEInteractablePickupScript>();
            }

            Selection.gameObjects[i].layer = 9;
            Selection.gameObjects[i].tag = "Pickup Item";

            pickeditems.Add(Selection.gameObjects[i]);
        }

        picked = true;
    }
}

enter image description here


In general I always recommend to use a ReorderableList!

It's a bit tricky at first to get into it but as soon as you have set it up it is an amazing tool. even if you don't make it actually reorderable it is still a huge advantage to be e.g. able to dynamically remove an item from the middle ;)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...