Search Unity

Resolved Event.current return null after first time in callback

Discussion in 'Scripting' started by stephen_ho, Jan 27, 2024.

  1. stephen_ho

    stephen_ho

    Joined:
    May 11, 2020
    Posts:
    4
    Hi guys, recently I'm working on an editor script that allow me to open a context menu in scene view and move a game object to the position
    Here my script for this

    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3.  
    4. [InitializeOnLoad]
    5. public static class RightClickMenuSceneView
    6. {
    7.     static RightClickMenuSceneView()
    8.     {
    9.         SceneView.duringSceneGui += SceneInteract;
    10.         menu = new GenericMenu();
    11.         menu.AddItem(new GUIContent("Move here"),false,Callback,1);
    12.     }
    13.  
    14.     private static GenericMenu menu;
    15.    
    16.     private static void SceneInteract(SceneView sceneView)
    17.     {
    18.         //Right-click
    19.         if (Event.current.button == 1)
    20.         {
    21.             if (Event.current.type == EventType.MouseDown)
    22.             {
    23.                 menu.ShowAsContext();
    24.             }
    25.         }
    26.     }
    27.  
    28.     private static void Callback(object obj)
    29.     {
    30.         var mousePos = Event.current.mousePosition;
    31.         var worldPos = HandleUtility.GUIPointToWorldRay(mousePos);
    32.         LevelManager.Instance.SetPosition(worldPos.origin);
    33.     }
    34. }
    As you can see in the Callback method, I was trying to access to Event.current but the result is I can only have it available only 1 time (after I compile my scripts), other times it returns null. But if I request it inside SceneInteract method, it will be fine
    Any idea on this behavior ?
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,859
    Where is the actual null error? Stack trace?

    I have a feeling you should be
    new()
    -ing the GenericMenu each time, rather than holding onto a cached instance.
     
  3. stephen_ho

    stephen_ho

    Joined:
    May 11, 2020
    Posts:
    4
    Code (CSharp):
    1. NullReferenceException: Object reference not set to an instance of an object
    2. RightClickMenuSceneView.Callback (System.Object obj) (at Assets/Editor/RightClickMenuSceneView.cs:30)
    3. UnityEditor.GenericMenu.CatchMenu (System.Object userData, System.String[] options, System.Int32 selected) (at <ac8a1d1a125546cf82b0ec17802fc7c2>:0)
    4.  
    Here my log for the null error
     
  4. stephen_ho

    stephen_ho

    Joined:
    May 11, 2020
    Posts:
    4
    Actually my first version is like this, I instance the GenericMenu whenever mouse down. But it still have the same issue
     
  5. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,859
    So doing some googling tells me that
    Event.current
    is null outside of
    OnGUI
    callbacks.

    So you will have to get the mouse position within the same method where you register the right click.
     
    Bunny83 and stephen_ho like this.
  6. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,147
    Event.current
    is only valid in the editor when it's processing events which is basically whenever it's handling the UI.
    OnGUI
    ,
    OnSceneGUI
    ,
    SceneView.duringSceneGui
    , etc. If you need the data from the event you have to copy it into fields to access it in other methods.
     
    stephen_ho, CodeSmile and spiney199 like this.
  7. stephen_ho

    stephen_ho

    Joined:
    May 11, 2020
    Posts:
    4
    Thanks guys I change my code and it works
    Here are the work code:

    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3.  
    4. [InitializeOnLoad]
    5. public static class RightClickMenuSceneView
    6. {
    7.     static RightClickMenuSceneView()
    8.     {
    9.         SceneView.duringSceneGui += SceneInteract;
    10.         menu = new GenericMenu();
    11.         menu.AddItem(new GUIContent("Move here"),false,Callback,1);
    12.     }
    13.  
    14.     private static Vector2 m_mousePos;
    15.     private static GenericMenu menu;
    16.    
    17.     private static void SceneInteract(SceneView sceneView)
    18.     {
    19.         //Right-click
    20.         if (Event.current.button == 1)
    21.         {
    22.             if (Event.current.type == EventType.MouseDown)
    23.             {
    24.                 m_mousePos = Event.current.mousePosition;
    25.                 menu.ShowAsContext();
    26.             }
    27.         }
    28.     }
    29.  
    30.     private static void Callback(object obj)
    31.     {
    32.         var worldPos = HandleUtility.GUIPointToWorldRay(m_mousePos);
    33.         LevelManager.Instance.SetPosition(worldPos.origin);
    34.     }
    35. }
     
    Bunny83 likes this.