Unity: как создать панель свойств материала для пользовательского типа активов?

#unity3d

#unity3d

Вопрос:

У меня есть пользовательский ресурс типа

 [System.Serializable]
public class Ranges: ScriptableObject
{
  public Vector4[] minPoints;
  public Vector4[] ranges;
}
  

Для соответствующего шейдера определены две формы

 half4 _coeffMins[25];
half4 _coeffRanges[25];
  

Я могу установить форму с помощью Material.SetVectorArray , однако я хотел бы иметь возможность напрямую перетаскивать свой пользовательский ресурс в слот в инспекторе свойств материалов с помощью шейдера.

Существует MaterialPropertyDrawer, однако кажется, что свойство материала, которое передается функции OnGUI, не поддерживает массивы.

Существует MaterialPropertyBlock, который поддерживает массивы, но я не понял, как это можно использовать для создания ящика пользовательских свойств.

Итак, как я могу создать свойство материала и соответствующую панель свойств, которая принимает в качестве типа мой пользовательский скриптовый объект?

Ответ №1:

Мой подход состоял бы в том, чтобы создать пользовательский редактор для панели свойств материала, а затем добавить новое поле объекта, которое будет принимать ваш объект, и привязать данные об изменении к этому материалу, чтобы изменить Материал.SetVectorArray на основе этих данных.

     [CustomEditor(typeof(Material))]
    public class MyMaterialEditor : UnityEditor.Editor
    {
        Ranges source = new Ranges();

        public override void OnInspectorGUI()
        {
            var material = ((Material) serializedObject.targetObject);
            if (material.name == "DryWallPainted_Mat") // or other way to identify your material in editor
            {
                source = (Ranges) EditorGUILayout.ObjectField((Object) source, typeof(Ranges), true);
                if (source != null amp;amp; source.ranges != null amp;amp; source.minPoints != null)
                {
                    material.SetVectorArray("minPoints", source.minPoints);
                    material.SetVectorArray("ranges", source.ranges);
                    EditorUtility.SetDirty(material); //important
                }
            }
            DrawDefaultInspector();
        }
    }
  

Результат:

введите описание изображения здесь