0

我正在使用 Unity 2018.3.14f1,我正在尝试创建新的ScriptableObject. 这是我的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Items;
using System;
#if UNITY_EDITOR
using UnityEditor;
#endif

[CreateAssetMenu(fileName = "New Weapon", menuName = "Ingame Item/Weapon")]
public class Weapon : ScriptableObject
{
    public GameObject modelMesh;
    public WeaponType weaponType;
    public SlotType slotType;
    public WeaponTextureMaps[] weaponTextureMaps;


}

[Serializable]
public struct WeaponTextureMaps
{
    public Material material;
    public Texture normalMap;
    public Texture albedoMap;
    public Texture metalicMap;
    public Texture ambientOcullsionMap;
    public bool hasEmission;
    [HideInInspector]
    public Texture emissionMap;
}

#if UNITY_EDITOR
[CustomEditor(typeof(Weapon))]
public class Weapon_Editor : Editor
{
    Weapon script;
    GameObject model;
    SerializedProperty m_weaponTextureMaps;

    public void OnEnable()
    {
        script = (Weapon)target;
        model = script.modelMesh;
    }

    public override void OnInspectorGUI()
    {

        DrawDefaultInspector(); // for other non-HideInInspector fields
        if (GUI.changed)
        {
            if (model.name != script.modelMesh.name)
            {
                model = script.modelMesh;
                int totalMaterials = model.GetComponent<MeshRenderer>().sharedMaterials.Length;
                Array.Resize(ref script.weaponTextureMaps, totalMaterials);
                int i = -1;
                foreach (Material mat in model.GetComponent<MeshRenderer>().sharedMaterials)
                {
                    i++;
                    script.weaponTextureMaps[i].material = mat;
                }

            }
        }
        int ii = -1;
        foreach(WeaponTextureMaps wtm in script.weaponTextureMaps)
        {
            ii++;
            if (wtm.hasEmission == true)
            {
                script.weaponTextureMaps[ii].emissionMap = EditorGUILayout.ObjectField("Emission Map", script.weaponTextureMaps[ii].emissionMap, typeof(Texture), true) as Texture;
            }
        }
    }
}
#endif

在此处输入图像描述

当我单击“已发射”时,隐藏字段应出现在“已发射”按钮下方的“元素 0”内。

然而,它出现在“元素 0”之外,而不是在里面。我该如何解决?

如何使隐藏字段出现在它的元素内?

4

1 回答 1

0

你的问题是使用DrawDefaultInspector();

这导致该字段不仅出现在 Inspector 之外,Element 0而且出现在 Inspector 中的所有条目之后。


相反,我会CustomPropertyDrawerWeaponTextureMaps. WeaponTextureMaps巨大的优势:每次在脚本中使用字段时,您不必再次实现自定义编辑器。

    [Serializable]
    public struct WeaponTextureMaps
    {
        public Material material;
        public Texture normalMap;
        public Texture albedoMap;
        public Texture metalicMap;
        public Texture ambientOcullsionMap;
        public bool hasEmission;

        public Texture emissionMap;
    }

#if UNITY_EDITOR
    [CustomPropertyDrawer(typeof(WeaponTextureMaps))]
    public class WeaponTextureMapsDrawer : PropertyDrawer
    {
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            var material = property.FindPropertyRelative("material");
            var normalMap = property.FindPropertyRelative("normalMap");
            var albedoMap = property.FindPropertyRelative("albedoMap");
            var metalicMap = property.FindPropertyRelative("metalicMap");
            var ambientOcullsionMap = property.FindPropertyRelative("ambientOcullsionMap");
            var hasEmission = property.FindPropertyRelative("hasEmission");

            var emissionMap = property.FindPropertyRelative("emissionMap");

            // Using BeginProperty / EndProperty on the parent property means that
            // prefab override logic works on the entire property.
            EditorGUI.BeginProperty(position, label, property);

            // Draw label
            position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);

            EditorGUI.PropertyField(new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight), material);
            position.y += EditorGUIUtility.singleLineHeight;

            EditorGUI.PropertyField(new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight), normalMap);
            position.y += EditorGUIUtility.singleLineHeight;

            EditorGUI.PropertyField(new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight), albedoMap);
            position.y += EditorGUIUtility.singleLineHeight;

            EditorGUI.PropertyField(new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight), metalicMap);
            position.y += EditorGUIUtility.singleLineHeight;

            EditorGUI.PropertyField(new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight), ambientOcullsionMap);
            position.y += EditorGUIUtility.singleLineHeight;

            EditorGUI.PropertyField(new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight), hasEmission);
            position.y += EditorGUIUtility.singleLineHeight;

            if (hasEmission.boolValue)
            {
                EditorGUI.PropertyField(new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight), emissionMap);
            }

            EditorGUI.EndProperty();
        }

        public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
        {
            var hasEmission = property.FindPropertyRelative("hasEmission");

            return EditorGUIUtility.singleLineHeight * (hasEmission.boolValue ? 8 : 7);
        }
    }
#endif

结果

在此处输入图像描述


对于您Weapon_Editor,我建议不要SerializedProperty与直接访问和更改target. 而是做

[CustomEditor(typeof(Weapon))]
public class Weapon_Editor : Editor
{
    SerializedProperty model;
    SerializedProperty weaponType;
    SerializedProperty slotType;
    SerializedProperty weaponTextureMaps;

    // Link all script fields
    public void OnEnable()
    {
        model = serializedObject.FindProperty("modelMesh");
        weaponType = serializedObject.FindProperty("weaponType");
        slotType = serializedObject.FindProperty("slotType");
        weaponTextureMaps = serializedObject.FindProperty("weaponTextureMaps");
    }

    public override void OnInspectorGUI()
    {
        // Draw the Script field
        EditorGUI.BeginDisabledGroup(true);
        {
            EditorGUILayout.ObjectField("Script", MonoScript.FromScriptableObject((Weapon)target), typeof(Weapon), false);
        }
        EditorGUI.EndDisabledGroup();

        // load current values into the serialized fields
        serilaizedObject.Update();

        EditorGUI.BeginChangeCheck();
        {
            EditorGUILayout.PropertyField(model);
        }
        // runs everytime the model is changed
        if (EditorGUI.EndChangeCheck())
        {
            if(model.objectReferenceValue == null)
            {
                weaponTextureMaps.arraySize = 0;
            }
            else
            {
                // get the renderer fromt he SerializedProperty
                var renderer = ((GameObject)model.objectReferenceValue).GetComponent<Renderer>();

                if(renderer == null)
                {
                     weaponTextureMaps.arraySize = 0;
                }
                else
                {
                    int totalMaterials = renderer.sharedMaterials.Length;

                    weaponTextureMaps.arraySize = totalMaterials;

                    // set the material references
                    for (var i = 0; i < totalMaterials; i++)
                    {
                        weaponTextureMaps.GetArrayElementAtIndex(i).FindPropertyRelative("material").objectReferenceValue = renderer.sharedMaterials[i];
                    }
                }
            }
        }

        EditorGUILayout.PropertyField(weaponType);EditorGUILayout.PropertyField(slotType);

        // Note you have to pass true in order to see sub-fields
        EditorGUILayout.PropertyField(weaponTextureMaps, true);

        // Note that without that any changes to SerializedProperties does absolutely nothing
        serializedObject.ApplyModifiedProperties();
    }
}
#endif
于 2019-06-26T20:20:55.900 回答