Search Unity

  1. Check out the Unite LA keynote for updates on the Visual Effect Editor, the FPS Sample, ECS, Unity for Film and more! Watch it now!
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Improved Prefab workflow (includes Nested Prefabs!), 2D isometric Tilemap and more! Get the 2018.3 Beta now.
    Dismiss Notice
  4. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice
  5. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Custom OnSceneGUI-editor not working for ScriptableObjects?

Discussion in 'Extensions & OnGUI' 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:
    334
    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. }