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

[Editor Camera Raycasting] Can't get it to work!

Discussion in 'Scripting' started by Isbanan, Sep 8, 2013.

  1. Isbanan

    Isbanan

    Joined:
    Sep 12, 2012
    Posts:
    13
    Hello everyone!

    After looking through a series of threads, trying different methods and made a lot of thinking I have concluded that I'm not gonna get very longer on my own.

    What I am trying to do:
    I want to RayCast from the Editor Camera using a mouse-click in order to place an object wherever the ray hits.


    - I have seen people using this but I really have no idea how to use it or what it's for.
    *int ControlID = GUIUtility.GetControlID(FocusType.Passive);


    - After all threads I've seen this seem to use this method for casting a ray from the editor camera. But whenever I use it I get an object null reference. Why?
    Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);


    Here is my current code (not working).

    Code (csharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System.Collections;
    4.  
    5.  
    6. [CustomEditor(typeof(PlaceObject))]
    7. public class PlaceObject : Editor {
    8.    
    9.  public  void  OnSceneGUI()
    10.     {
    11.         Event current = Event.current;
    12.         int ControlID = GUIUtility.GetControlID(FocusType.Passive);
    13.        
    14.        if(Event.current.type == EventType.mouseDown)
    15.             {
    16.                 Ray mRay = HandleUtility.GUIPointToWorldRay(current.mousePosition);
    17.                 RaycastHit rHit;
    18.                 if (Physics.Raycast(mRay, out rHit, Mathf.Infinity))
    19.                 {
    20.                    // Create object at hit.pos
    21.                    
    22.                     Event.current.Use();
    23.                 }
    24.             }
    25.        
    26.         HandleUtility.AddDefaultControl(ControlID);
    27.     }
    28. }  



    Since I have seen so many threads on this thing I will payback our community with making a tutorial about this issue if I ever come to clarity with it.


    Thanks in advance!

    / Stefan Jonsson
     
  2. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    Heres a snippet from one of my scene raycastings
    Code (csharp):
    1.  
    2.     void OnSceneGUI ( SceneView sceneView ) {
    3.         Event e = Event.current;
    4.         Ray ray = SceneView.lastActiveSceneView.camera.ScreenPointToRay( new Vector3( e.mousePosition.x, Screen.height - e.mousePosition.y - 36, 0 ) ); //Upside-down and offset a little because of menus
    5.         RaycastHit hit;
    6.         if ( e.type == EventType.mouseDown ) {
    7.             if ( Physics.Raycast( ray, out hit, 100.0f, ( 1 << 8 ) ) ) {
    8.                 Debug.Log(hit);
    9.             }
    10.         }
    11.     }
    12.  
    13.  
    So as you can see, not alot different. The trick (for me at least) was to push this to the OnSceneGUIDelegate's somewhere
    SceneView.onSceneGUIDelegate += this.OnSceneGUI;
     
    isyuuba likes this.
  3. Isbanan

    Isbanan

    Joined:
    Sep 12, 2012
    Posts:
    13
    I couldn't get it to work, I get this error:
    Code (csharp):
    1.  
    2. TargetParameterCountException: parameters do not match signature
    3. System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at /Applications/buildAgent/work/b59ae78cff80e584/mcs/class/corlib/System.Reflection/MonoMethod.cs:188)
    4. System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) (at /Applications/buildAgent/work/b59ae78cff80e584/mcs/class/corlib/System.Reflection/MethodBase.cs:115)
    5. UnityEditor.SceneView.CallOnSceneGUI () (at C:/BuildAgent/work/cac08d8a5e25d4cb/Editor/Mono/SceneView/SceneView.cs:1392)
    6. UnityEditor.SceneView.HandleSelectionAndOnSceneGUI () (at C:/BuildAgent/work/cac08d8a5e25d4cb/Editor/Mono/SceneView/SceneView.cs:872)
    7. UnityEditor.SceneView.OnGUI () (at C:/BuildAgent/work/cac08d8a5e25d4cb/Editor/Mono/SceneView/SceneView.cs:761)
    8.  
    And also I did not understand this OnSceneGUIDelegate thing. I'm all new to these kind of scripts.
     
  4. Isbanan

    Isbanan

    Joined:
    Sep 12, 2012
    Posts:
    13
    I got it working now but it only returns 0,0,0 for the hit.transform.position.

    EDIT: Funny thing is though that the Raycasthit actually hits something cause when I cast it towards infinity it doesn't pass through the if(Physics.Raycast ...) So It's like the ray hits the terrain in my example but doesn't return where it hit the terrain.
     
    Last edited: Sep 8, 2013
  5. Isbanan

    Isbanan

    Joined:
    Sep 12, 2012
    Posts:
    13
    Here is my current version of the code:

    Code (csharp):
    1.     void OnSceneGUI()
    2.     {
    3.         Event e = Event.current;
    4.        
    5.         // We use hotControl to lock focus onto the editor (to prevent deselection)
    6.         int controlID = GUIUtility.GetControlID(FocusType.Passive);
    7.        
    8.         switch (Event.current.GetTypeForControl(controlID))
    9.         {
    10.             case EventType.MouseDown:
    11.                 GUIUtility.hotControl = controlID;
    12.                 Debug.Log("Mouse Down!");
    13.                 Ray ray = SceneView.lastActiveSceneView.camera.ScreenPointToRay(e.mousePosition);
    14.                 RaycastHit hit;
    15.            
    16.                      if ( Physics.Raycast( ray, out hit, Mathf.Infinity))
    17.                         {
    18.  
    19.                          Debug.Log(hit.transform.position);
    20.  
    21.                         }
    22. //              PlaceObject();
    23.                 Event.current.Use();
    24.                 break;
    25.            
    26.             case EventType.MouseUp:
    27.                 GUIUtility.hotControl = 0;
    28.                 Event.current.Use();
    29.                 break;
    30.            
    31.         }
     
  6. Isbanan

    Isbanan

    Joined:
    Sep 12, 2012
    Posts:
    13
    OH MY GOD! I used

    hit.transform.position instead of hit.point

    Now it works! haha! Thanks a lot hpjohn!

    EDIT:

    BAH! Just noticed, it kind of works. I'm getting a weird offset now.
     
    Last edited: Sep 8, 2013
  7. Isbanan

    Isbanan

    Joined:
    Sep 12, 2012
    Posts:
    13
    FINALLY it works!

    Here's the final solution

    Code (csharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System.Collections;
    4.  
    5. [CustomEditor(typeof(IceEditor))]
    6. public class IceEditorPlaceObject : Editor {
    7.    
    8.    
    9.      
    10.    
    11.    
    12.        
    13.     void OnSceneGUI()
    14.     {
    15.         Event e = Event.current;
    16.        
    17.         // We use hotControl to lock focus onto the editor (to prevent deselection)
    18.         int controlID = GUIUtility.GetControlID(FocusType.Passive);
    19.        
    20.         switch (Event.current.GetTypeForControl(controlID))
    21.         {
    22.             case EventType.MouseDown:
    23.                 GUIUtility.hotControl = controlID;
    24.                 Debug.Log("Mouse Down!");
    25.                 Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
    26.                 RaycastHit hit;
    27.            
    28.                      if ( Physics.Raycast( ray, out hit, Mathf.Infinity))
    29.                         {
    30.                             Vector3 myPos = hit.point;
    31.                             PlaceObject(myPos);
    32.                         }
    33.  
    34.                 Event.current.Use();
    35.                 break;
    36.            
    37.             case EventType.MouseUp:
    38.                 GUIUtility.hotControl = 0;
    39.                 Event.current.Use();
    40.                 break;
    41.            
    42.         }
    43.     }
    44.    
    45.    
    46.    
    47.    
    48.    
    49.        
    50.     void PlaceObject(Vector3 myPos)
    51.     {
    52.         GameObject go = Resources.Load("Prefabs/BlockWalls/Block_x1") as GameObject;
    53.         Instantiate (go, myPos, Quaternion.identity);
    54.     }
    55.    
    56.    
    57. }
     
    IDmikael and Ashley_Seric like this.
  8. spilat12

    spilat12

    Joined:
    Feb 10, 2015
    Posts:
    33
    This is still useful in the end of 2021! :) Thanks