Ваша проблема использует DrawDefaultInspector();
Это приводит к тому, что поле появляется не только за пределами Element 0
, но и после всех записей в Инспекторе.
Вместо этого я бы сделал CustomPropertyDrawer
для WeaponTextureMaps
.Огромное преимущество: вам не нужно снова реализовывать пользовательский редактор каждый раз, когда вы используете в скрипте поле 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
результат
![enter image description here](https://i.stack.imgur.com/bjC5Y.png)
Для вашего 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