Search Unity

Custom PropertyDrawer for ScriptableObject type property

Discussion in 'Editor & General Support' started by Rukas90, Aug 29, 2019.

  1. Rukas90

    Rukas90

    Joined:
    Sep 20, 2015
    Posts:
    169
    Hello,
    I am trying to create a custom PropertyDrawer for a ScriptableObject type property. Unfortunately I am unable to get this working.

    I have a lot of different ScriptableObject type classes and I do not want to create a custom PropertyDrawer for every class, but instead have a single custom PropertyDrawer script for a ScriptableObject class itself and affect every property that is in ScriptableObject type.

    Is this even possible to accomplish?

    Example PropertyDrawer:
    Code (CSharp):
    1. using System;
    2. using UnityEditor;
    3. using UnityEngine;
    4.  
    5. [CustomPropertyDrawer(typeof(ScriptableObject))]
    6. public class ScriptableObject_PropertyDrawer : PropertyDrawer
    7. {
    8.     public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    9.     {
    10.         var rect = EditorGUI.PrefixLabel(position, label);
    11.  
    12.         rect.width -= 50;
    13.         EditorGUI.PropertyField(rect, property);
    14.  
    15.         Rect buttonRect = new Rect(rect.x + rect.width, rect.y, 50, rect.height);
    16.         var pressed = GUI.Button(buttonRect, new GUIContent("Create"), EditorStyles.miniButton);
    17.  
    18.         if (pressed)
    19.         {
    20.             property.objectReferenceValue = CreateAsset(property.GetType());
    21.         }
    22.     }
    23.  
    24.     private UnityEngine.Object CreateAsset(Type type)
    25.     {
    26.         // ..
    27.         //return ..;
    28.     }
    29. }
     
  2. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,281
    The problem is that ScriptableObjects are treated as object reference fields, so a property drawer would not work. You would need to use a custom editor and then embed that editor in every Editor that uses it, a fair bit of work.
    However you could try wrapping the reference up inside of a Serialized class/struct and having a PropertyDrawer for that class.
    E.G

    Code (csharp):
    1. [Serializable]
    2. public class MyScriptableObjectWrapper
    3. {
    4.     public ScriptableObject obj;
    5. }
    Code (csharp):
    1. [CustomPropertyDrawer(typeof(MyScriptableObjectWrapper))]
    2. public class ScriptableObject_PropertyDrawer : PropertyDrawer{
    3. ...
    This apprach is actually quite nice as it gives you more conrol over what type of ScriptableObject you want referenced and still supports custom editors for the ScriptableObject. Inside your property drawer you can do Editor.CreateEditor for the referenced object and then embed that into the PropertyDrawer. :)
    We do something similiar in the Localization package
     
    aarthificial and Rukas90 like this.
  3. marcospgp

    marcospgp

    Joined:
    Jun 11, 2018
    Posts:
    194
    I am in the process of creating a property drawer for a ScriptableObject and it seems to be working so far, I'm curious as to why it's not supposed to - should I change my approach?
     
  4. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,281
    This was 3 years ago so my memory is a little fuzzy. A property drawer for Scriptable object is fine, it's showing the property drawer when you have it embeded Into another object. It will show an object reference field, not the property drawer.
     
    Last edited: Sep 23, 2022
    marcospgp likes this.
  5. mkawick

    mkawick

    Joined:
    Feb 11, 2014
    Posts:
    8
    Juts curious about an approach to making a "Custom editor" for scriptable objects. I am building a tile editor and I have groups of tiles organized like so:

    Code (CSharp):
    1. [CreateAssetMenu(fileName = "TileGroup", menuName = "Data/TileGroup", order = 1)]
    2. public class TileGroupData : ScriptableObject
    3. {
    4.     public string prefabName;
    5.     public GroupType groupType;
    6.  
    7.     public GameObject [] tiles;
    8.  
    9.     public enum GroupType
    10.     {
    11.         Unorganized,
    12.         GroupOf14,
    13.         ProgressiveColors,
    14.         Roads,
    15.         Water
    16.     }
    17. }
    The labels for the tiles should appeardifferently depending on the GroupType. There seems to be a few different approaches, but I wonder if I can simply have something in the editor that let's me view the ScriptableObjects in a custom way; in other words, this view might be different for each group type. Can I have a PropertyDrawer that views ScriptableObjects independent of what contains them?

    upload_2022-11-10_8-8-18.png
     
  6. SkandYxyz

    SkandYxyz

    Joined:
    Mar 13, 2015
    Posts:
    83
    I try to implement a property drawer for ScriptableObjects with UIToolkit.
    upload_2023-2-3_23-16-1.png
    Does anyone know, why the childPropertyField is not drawing? The same called in OnGUI with IMGUI works:
    upload_2023-2-3_23-20-28.png

    Thanks in advance!
     
  7. LightRuno

    LightRuno

    Joined:
    May 2, 2018
    Posts:
    7
    I have a timer class Scriptable Object with serializefield.

    upload_2023-12-14_16-16-14.png

    I have scriptable object with list of them
    upload_2023-12-14_16-16-53.png

    And property drawer that was copied from docs with only edited property name according
    upload_2023-12-14_16-17-46.png

    It's just don't work at all.
    Unity 2022.3.10f1.

    If it's OnGUI method - it's just don't renders. If it's using UI Toolkit - it's just shows "No GUI Implemented"