Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Button in scene view

Discussion in 'Scripting' started by nbg_yalta, Jul 31, 2014.

  1. nbg_yalta

    nbg_yalta

    Joined:
    Oct 3, 2012
    Posts:
    378
    Hi, I;m tryin to make a clickable scene button, but it wont work

    Code (csharp):
    1.  
    2. void OnDrawGizmos () {
    3.      Handles.BeginGUI();
    4.  
    5.      if (GUI.Button(new Rect(10, 10, 100, 50), "Button"))
    6.      {
    7.        Debug.Log("Pressed");
    8.      }
    9.    
    10.      Handles.EndGUI();
    11.    }
    12.  
     
  2. smitchell

    smitchell

    Joined:
    Mar 12, 2012
    Posts:
    702
    Because your trying to call it on draw gizmos
     
  3. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,716
    Does it show up? Because I think you can only draw Gizmos in the OnDrawGizmos.
     
  4. smitchell

    smitchell

    Joined:
    Mar 12, 2012
    Posts:
    702
    You need to place the code in a window on your OnSceneGUI function, something like this:

    Code (CSharp):
    1.  
    2.        GUILayout.Window(0, new Rect(10, 10, 100, 100), (id)=> {
    3.             GUILayout.Button("A Button");
    4.         },
     
  5. nbg_yalta

    nbg_yalta

    Joined:
    Oct 3, 2012
    Posts:
    378
    I dont need any windows, I just need a scene view button, and yes it draws with OnDrawGizmos...
    I've tryied this way:
    Code (csharp):
    1.  
    2. void OnDrawGizmos () {
    3.      Handles.BeginGUI();
    4.  
    5.      Rect rect = new Rect(10, 10, 100, 50);
    6.  
    7.      GUI.Button(rect, "Button");
    8.  
    9.      if(Event.current.type == EventType.MouseDown)
    10.      {
    11.        Debug.Log("press");
    12.      }
    13.  
    14.      Handles.EndGUI();
    15.    }
    16.  
    And it works everywhere except the button's rect... wtf? How can I do the opposite? :D

    I can make this work this way, but without button... looks like button blocking click event...
    Code (csharp):
    1.  
    2. void OnDrawGizmos () {
    3.      Handles.BeginGUI();
    4.  
    5.      Rect rect = new Rect(10, 10, 100, 50);
    6.  
    7.      if(Event.current.type == EventType.MouseDown && rect.Contains(Event.current.mousePosition))
    8.      {
    9.        Debug.Log("press");
    10.      }
    11.  
    12.      Handles.EndGUI();
    13.    }
    14.  
    Help, I need this to work with a button, not just with rect!
     
    Last edited: Jul 31, 2014
  6. smitchell

    smitchell

    Joined:
    Mar 12, 2012
    Posts:
    702
    try it on OnSceneGUI () { }
    see if that makes a difference. It really hurts my brain that you're doing it in gizmos space ha
     
  7. nbg_yalta

    nbg_yalta

    Joined:
    Oct 3, 2012
    Posts:
    378
    It wont work inside OnSceneGUI at all ...
     
  8. smitchell

    smitchell

    Joined:
    Mar 12, 2012
    Posts:
    702
    I just tested in OnSceneGUI and it worked..
     
  9. smitchell

    smitchell

    Joined:
    Mar 12, 2012
    Posts:
    702
    Exact same code I used. Except I drew a box to visualise it.
     
  10. smitchell

    smitchell

    Joined:
    Mar 12, 2012
    Posts:
    702
    Might be a stupid question but are you sure you're clicking in the right area?
     
  11. nbg_yalta

    nbg_yalta

    Joined:
    Oct 3, 2012
    Posts:
    378
    Hey, It works with GUI.Box but not with a Button... Is there a way to draw a GUI.Box like a button, GUIStyle or something?
     
  12. smitchell

    smitchell

    Joined:
    Mar 12, 2012
    Posts:
    702
    yeah use GUI Style, although I'm curious as to why it's not working for you. Even without a box it works for me. Although I do have other stuff going on.

    Try adding SceneView.RepaintAll (); somewhere in your on scene gui function. That's the only thing my brain can think of that might be causing the issue
     
  13. nbg_yalta

    nbg_yalta

    Joined:
    Oct 3, 2012
    Posts:
    378
    Can you post your version pls?
     
  14. smitchell

    smitchell

    Joined:
    Mar 12, 2012
    Posts:
    702
    I can't post my whole script, but here's what I used to test your issue:

    Code (CSharp):
    1.  
    2.    void OnSceneGUI () {
    3.         Handles.BeginGUI();
    4.              
    5.         Rect rect = new Rect(10, 10, 100, 50);
    6.  
    7.         if(Event.current.type == EventType.MouseDown && rect.Contains(Event.current.mousePosition))
    8.             Debug.Log("press");
    9.      
    10.         Handles.EndGUI();
    11.  
    12.         SceneView.RepaintAll ();
    13.     }
     
    IgorAherne likes this.
  15. nbg_yalta

    nbg_yalta

    Joined:
    Oct 3, 2012
    Posts:
    378
    Just nothing....

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using UnityEditor;
    4. using System.Collections;
    5.  
    6. public class Test : Editor {
    7.  
    8.    void OnSceneGUI () {
    9.      Handles.BeginGUI();
    10.    
    11.      Rect rect = new Rect(10, 10, 100, 50);
    12.      GUI.Box(rect, "Button");
    13.      if(Event.current.type == EventType.MouseDown && rect.Contains(Event.current.mousePosition))
    14.        Debug.Log("press");
    15.    
    16.      Handles.EndGUI();
    17.    
    18.      SceneView.RepaintAll ();
    19.    }
    20. }
    21.  
    No box, no click detection...
     
  16. smitchell

    smitchell

    Joined:
    Mar 12, 2012
    Posts:
    702
    hmm I'm stumped bro. I'm not sure why it's not working for you. It must be something obvious..

    You have hooked up the editor script to your base script right? the editor class is in the editor folder?
     
  17. nbg_yalta

    nbg_yalta

    Joined:
    Oct 3, 2012
    Posts:
    378
    Ok, here is what I have for now:

    Script:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class testScript : MonoBehaviour {
    6.  
    7.    public GameObject selected;
    8. }
    9.  
    Editor Script:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using UnityEditor;
    4. using System.Collections;
    5.  
    6. [CustomEditor(typeof(testScript))]
    7. public class Test : Editor {
    8.  
    9.    testScript myScript;
    10.  
    11.    void OnEnable()
    12.    {
    13.      myScript = (testScript) target;
    14.    }
    15.  
    16.    void OnSceneGUI () {
    17.      Handles.BeginGUI();
    18.      
    19.      Rect rect = new Rect(10, 10, 100, 50);
    20.      GUI.Box(rect, "Button");
    21.      if(Event.current.type == EventType.MouseDown && rect.Contains(Event.current.mousePosition))
    22.        Selection.activeGameObject = myScript.selected;
    23.      Handles.EndGUI();
    24.      
    25.      SceneView.RepaintAll ();
    26.    }
    27. }
    28.  
    The problem is GUI.Box is drawing only if the object with Script is selected(I need it to be drawn allways)... The other problem when I click this box, selection object goes to the myScript.selected gameobject, and immediately goes null.
     
  18. smitchell

    smitchell

    Joined:
    Mar 12, 2012
    Posts:
    702
    Ok so I've tested this out. And it's working now. The issue was that the event.current wasn't being used. Fixed it with event.current.Use ();

    I've cleaned it up a little:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System.Collections;
    4.  
    5. [CustomEditor(typeof(testScript))]
    6. public class Test : Editor {
    7.  
    8.     testScript TestScript {
    9.         get { return (testScript) target;}
    10.     }
    11.  
    12.     void OnSceneGUI () {
    13.         Event e = Event.current;
    14.  
    15.         Handles.BeginGUI();
    16.      
    17.         Rect rect = new Rect(10, 10, 100, 50);
    18.         GUI.Box(rect, "Button");
    19.         if(e.type == EventType.MouseDown && rect.Contains(e.mousePosition)) {
    20.             Selection.activeGameObject = TestScript.selected;
    21.             Debug.Log("work whore!!");
    22.         }
    23.  
    24.         Handles.EndGUI();
    25.  
    26.         e.Use ();
    27.     }
    28. }
    29.  
     
    mchts likes this.
  19. smitchell

    smitchell

    Joined:
    Mar 12, 2012
    Posts:
    702
    It goes null because you're only setting the object when the mouse is down and is within that rect
     
  20. smitchell

    smitchell

    Joined:
    Mar 12, 2012
    Posts:
    702
    Set it to EventType.MouseUp
     
  21. nbg_yalta

    nbg_yalta

    Joined:
    Oct 3, 2012
    Posts:
    378
    Maybe the problem is my unity version (4.5.1f3), becouse I got the same problems...
    -Click event and box draw works only if testScript gameobject is selected..
    -selection.activegameobject goes null after I releasing mouse button...
     
  22. nbg_yalta

    nbg_yalta

    Joined:
    Oct 3, 2012
    Posts:
    378
    MouseUp wont work at all :eek:
     
  23. smitchell

    smitchell

    Joined:
    Mar 12, 2012
    Posts:
    702
    this isn't a error. This is just how is (I think). You need to lock the inspector for the scene view code to work
     
  24. smitchell

    smitchell

    Joined:
    Mar 12, 2012
    Posts:
    702
    really?! I think Unity doesn't like you my friend ha. Have you tried right clicking? Because sometimes my mouse (magic mouse) doesn't register left clicks in editor mouse up but does for right click
     
  25. nbg_yalta

    nbg_yalta

    Joined:
    Oct 3, 2012
    Posts:
    378
    Ok. maybe there is a way to ignore mouseUp or something?
     
  26. nbg_yalta

    nbg_yalta

    Joined:
    Oct 3, 2012
    Posts:
    378
    Hm.. strange, but mouse up detection almost works now... it works with Debug, but wont work with selection object change...
    Code (csharp):
    1.  
    2. if(current.type == EventType.mouseUp)
    3.      {
    4.        if(rect.Contains(Event.current.mousePosition))
    5.        {
    6.          Selection.activeObject = selected;
    7.          Debug.Log("Up");
    8.        }
    9.      }
    10.  
    "Up" word appears in my console, but selection never changes or assign.. My brains are blown up...
     
  27. nbg_yalta

    nbg_yalta

    Joined:
    Oct 3, 2012
    Posts:
    378
    any ideas?
     
  28. CurtisMcGill

    CurtisMcGill

    Joined:
    Aug 7, 2012
    Posts:
    67
    Have you tried the following?

    For anyone who comes across this from google, just wanted to update it.


    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. [ExecuteInEditMode]
    4. public class testScript : MonoBehaviour
    5. {
    6.     public GameObject selected;
    7. }

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3.  
    4. [CustomEditor(typeof(testScript))]
    5. public class Test : Editor
    6. {
    7.     void OnSceneGUI()
    8.     {
    9.         Handles.BeginGUI();
    10.         if (GUI.Button(new Rect(10, 10, 100, 50), "Button"))
    11.             Debug.Log("Clicked the button with text");
    12.         Handles.EndGUI();
    13.     }
    14. }
     
  29. shawnblais

    shawnblais

    Joined:
    Oct 11, 2012
    Posts:
    324
    To pay it forward, here is the idea, evolved a bit.

    The idea is you might want to jump between multiple gameObjects, with a persistent menu.

    First, declare a base editor class that each shortcut target can share.
    Code (CSharp):
    1. public class GameShortcutsEditor : Editor
    2.     {
    3.         protected void OnSceneGUI()
    4.         {
    5.             float btnHeight = 50;
    6.             float btnPadding = 10;
    7.             float btnY = btnPadding;
    8.  
    9.             Rect GetRect(float y) => new Rect(btnPadding, y, 100, 50);
    10.  
    11.             void AddBtn(string v, Action pressed)
    12.             {
    13.                 if (GUI.Button(GetRect(btnY), v))
    14.                 {
    15.                     pressed();
    16.                 }
    17.                 btnY += (btnHeight + btnPadding);
    18.             }
    19.  
    20.             Handles.BeginGUI();
    21.             AddBtn("Select Foo", () => Select<Foo>());
    22.             AddBtn("Select Bar", () => Select<Bar>());
    23.             Handles.EndGUI();
    24.         }
    25.  
    26.         private void Select<T>() where T : UnityEngine.Object
    27.         {
    28.             {
    29.                 Selection.activeObject = FindObjectOfType<T>();
    30.             }
    31.         }
    32.     }
    ^ This just stacks some vertical btns, and when one is clicked, selects a GameObject of some type.

    Then, just declare some concrete instances, that call base.OnSceneGui()

    Code (CSharp):
    1.  [CustomEditor(typeof(Foo))]
    2.     public class FooShortcuts : GameShortcutsEditor
    3.     {
    4.         new private void OnSceneGUI() => base.OnSceneGUI();
    5.     }
    6.  
    7.     [CustomEditor(typeof(Bar))]
    8.     public class BarShortcuts : GameShortcutsEditor
    9.     {
    10.         new private void OnSceneGUI() => base.OnSceneGUI();
    11.     }
    Getting you this :) Can switch back and forth, and the menu stays put.
     
    lukeiszed likes this.
  30. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    714
    work whore!!