Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Custom OnSceneGUI-editor not working for ScriptableObjects?

Discussion in 'Immediate Mode GUI (IMGUI)' started by pixi2, Feb 3, 2017.

  1. pixi2

    pixi2

    Joined:
    Dec 22, 2013
    Posts:
    14
    Hello Internet,

    I have a ScriptableObject...

    [CreateAssetMenuAttribute]
    public class PickupPosition : ScriptableObject
    {
    public Vector3 _position;
    }


    I want to visually edit the _position attribute within my scene. Preferably with a transform-handle:

    [CustomEditor(typeof(PickupPosition))]
    public class AreaEditor : Editor
    {
    public override void OnInspectorGUI()
    {
    Debug.Log("The Inspector-GUI gets called");
    }

    void OnSceneGUI()
    {
    Debug.Log("why is the SceneGUI not called?");
    }
    }


    Defining the OnSceneGUI works for MonoBehaviours but not for ScriptableObjects.
    Editing properties of ScriptableObjects within the 3d-scene would be quiet convenient, but I can't find any documentation if or how this would be possible.

    On a side note: I have a difficult time figuring out why some methods (like `OnInspectorGUI()`) needs to be overridden whereas others ( `OnSceneGUI()` , `OnEnable()`, etc.) just need to be defined. I find this distinction quite arbitrary. Is there any documentation on that topic?

    Any ideas or suggestions are highly welcome.
     
  2. flashframe

    flashframe

    Joined:
    Feb 10, 2015
    Posts:
    789
    I think you can register your method to the OnSceneGUIDelegate in the SceneView class. (eg. register in OnEnable, unregister in OnDisable)

    Code (CSharp):
    1. SceneView.onSceneGUIDelegate += this.OnSceneGUI;
    Don't think this is documented, nor is the editor functionality particularly well documented in general. Lots of trial and error :)
     
    karl_jones likes this.
  3. BMayne

    BMayne

    Joined:
    Aug 4, 2014
    Posts:
    186
    Hey,

    As flash frame was saying you can use the delegate to get the results you wanted. He is correct in saying scriptable objects don't have that callback. The exist outside the runtime world so they have a limited set of callbacks. The have the following.
    Code (CSharp):
    1. void OnEnable();
    2. void OnDisable();
    3. void OnDestroy();
    Cheers,
    Byron
     
  4. pixi2

    pixi2

    Joined:
    Dec 22, 2013
    Posts:
    14
    Hi,

    thanks for your answer. This is exactly was I have been looking for. I will give it a try tonight.

    cheers,
    tom
     
  5. loosecanonstudios

    loosecanonstudios

    Joined:
    Mar 16, 2016
    Posts:
    4
    This finally solved my problem, after two days of screaming at my monitor, and approximately 50,000 Google searches. Thank you.
     
    karl_jones likes this.
  6. ChrisNavarre

    ChrisNavarre

    Joined:
    Oct 30, 2016
    Posts:
    1
    Yup this solution was able to work for me. Here's roughly what my editor code looks like. SceneLoadout is a scriptable object that stores a bunch of data about objects I want to spawn on scene load.

    Code (CSharp):
    1. [CustomEditor(typeof(SceneLoadout))]
    2. public class SceneLoadoutEditor : OdinEditor
    3. {
    4.     public SceneLoadout sceneLoadout;
    5.  
    6.     protected override void OnEnable()
    7.     {
    8.         base.OnEnable();
    9.         SceneView.onSceneGUIDelegate += OnSceneGUI;
    10.     }
    11.  
    12.     protected override void OnDisable()
    13.     {
    14.         base.OnDisable();
    15.         SceneView.onSceneGUIDelegate -= OnSceneGUI;
    16.     }
    17.  
    18.     private void OnSceneGUI(SceneView sceneView)
    19.     {
    20.         sceneLoadout = (SceneLoadout)target;
    21.  
    22.         if (sceneLoadout == null)
    23.         {
    24.             return;
    25.         }
    26.  
    27.         int controlId = 0;
    28.  
    29.         foreach (StatefulInstance<Player, PlayerData> stateful in sceneLoadout.players)
    30.         {
    31.             TransformData data = stateful.statefulData.transformData;
    32.             Handles.DrawWireCube(data.position, data.scale);
    33.         }
    34.  
    35.         foreach (StatefulInstance<PickupItem, PickupItemData> statefulItem in sceneLoadout.pickupItems)
    36.         {
    37.             TransformData data = statefulItem.statefulData.transformData;
    38.             Handles.DrawWireCube(data.position, data.scale);
    39.         }
    40.     }
    41. }
     
    AndersonMarquess likes this.
  7. Sciman101

    Sciman101

    Joined:
    Jan 7, 2014
    Posts:
    7
    I was looking for something exactly like this, thank you!
     
  8. conceptfac

    conceptfac

    Joined:
    Feb 15, 2018
    Posts:
    23
    target not exists in scriptable objects