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. Have a look at our Games Focus blog post series which will show what Unity is doing for all game developers – now, next year, and in the future.
    Dismiss Notice

Editor raycast against scene meshes without collider; Editor Select-object using GUI coordinate

Discussion in 'Scripting' started by IgorAherne, Jul 28, 2017.

  1. IgorAherne

    IgorAherne

    Joined:
    May 15, 2013
    Posts:
    382
    Here is a piece of code allowing you to do what the title says.
    Bwa!!

    Source:
    https://github.com/MattRix/UnityDecompiled/blob/master/UnityEditor/UnityEditor/HandleUtility.cs
    https://gist.github.com/MattRix/9205bc62d558fef98045
    I've improved it to include object picking as well


    Code (CSharp):
    1.  
    2. //powerful class, allows to detect intersection with mesh, without requiring any collider, etc
    3. //Works in editor only
    4. //
    5. // Main Author https://gist.github.com/MattRix
    6. // Igor Aherne improved it to include object picking as well   facebook.com/igor.aherne
    7. //https://github.com/MattRix/UnityDecompiled/blob/master/UnityEditor/UnityEditor/HandleUtility.cs
    8. [InitializeOnLoad]
    9. public static class EditorHandles_UnityInternal {
    10.     static Type type_HandleUtility;
    11.     static MethodInfo meth_IntersectRayMesh;
    12.     static MethodInfo meth_PickObjectMeth;
    13.  
    14.     static EditorHandles_UnityInternal() {
    15.         var editorTypes = typeof(Editor).Assembly.GetTypes();
    16.  
    17.         type_HandleUtility = editorTypes.FirstOrDefault(t => t.Name == "HandleUtility");
    18.         meth_IntersectRayMesh = type_HandleUtility.GetMethod("IntersectRayMesh",
    19.                                                               BindingFlags.Static | BindingFlags.NonPublic);
    20.         meth_PickObjectMeth = type_HandleUtility.GetMethod("PickGameObject",
    21.                                                             BindingFlags.Static | BindingFlags.Public,
    22.                                                             null,
    23.                                                             new [] {typeof(Vector2), typeof(bool)},
    24.                                                             null);
    25.     }
    26.  
    27.  
    28.     //get a point from interected with any meshes in scene, based on mouse position.
    29.     //WE DON'T NOT NEED to have to have colliders ;)
    30.     //usually used in conjunction with  PickGameObject()
    31.     public static bool IntersectRayMesh(Ray ray, MeshFilter meshFilter, out RaycastHit hit) {
    32.         return IntersectRayMesh(ray, meshFilter.mesh, meshFilter.transform.localToWorldMatrix, out hit);
    33.     }
    34.  
    35.     //get a point from interected with any meshes in scene, based on mouse position.
    36.     //WE DON'T NOT NEED to have to have colliders ;)
    37.     //usually used in conjunction with  PickGameObject()
    38.     public static bool IntersectRayMesh(Ray ray, Mesh mesh, Matrix4x4 matrix, out RaycastHit hit) {
    39.         var parameters = new object[] { ray, mesh, matrix, null };
    40.         bool result = (bool)meth_IntersectRayMesh.Invoke(null, parameters);
    41.         hit = (RaycastHit)parameters[3];
    42.         return result;
    43.     }
    44.  
    45.  
    46.  
    47. //select a gameObject in scene, based on mouse position.
    48.     //Object DOES NOT NEED to have to have colliders ;)
    49.     //If you DON'T want object to be included into  Selection.activeGameObject,
    50.     //(parameter works only in gui functions and scene view delegates) specify updateSelection = false
    51.     public static GameObject PickGameObject(Vector2 position, bool updateSelection = true, bool selectPrefabRoot = false) {
    52.  
    53.         if (updateSelection == false && Event.current != null) {
    54.             int blocking_ix = GUIUtility.GetControlID(FocusType.Passive);
    55.             HandleUtility.AddDefaultControl(blocking_ix);
    56.             GUIUtility.hotControl = blocking_ix; //tell unity that your control is active now, so it won't do selections etc.
    57.         }
    58.  
    59.         GameObject pickedGameObject = (GameObject)meth_PickObjectMeth.Invoke(null,
    60.                                                        new object[] { position, selectPrefabRoot });
    61.  
    62.         return pickedGameObject;
    63.     }
    64.  
    65. }
    66.  
     
    Last edited: Apr 11, 2018
    DrViJ, fherbst, Philip_Zhang and 9 others like this.
  2. Ziflin

    Ziflin

    Joined:
    Mar 12, 2013
    Posts:
    119
    It would be great if Unity could expose a more optimized version of this method. I'm not sure what all it's doing internally, but it is *quite* slow for larger meshes. It appears that PolyBrush uses their own custom ray-triangle intersection methods to avoid having to use reflection to get to this.
     
  3. 00christian00

    00christian00

    Joined:
    Jul 22, 2012
    Posts:
    991
    Did IntersectRayMesh stop working in unity 2020? It doesn't hit anything anymore for me. Was working fine in 2019.
     
  4. 00christian00

    00christian00

    Joined:
    Jul 22, 2012
    Posts:
    991
    It seem the issue is the code to convert the mouse position to a ray is not working properly anymore. Anybody got a working version? Right now the ray is quite offset from the mouse.
    EDIT
    Now it restarted working. I think some editor asset is screwing up something.
     
  5. _geo__

    _geo__

    Joined:
    Feb 26, 2014
    Posts:
    662
    Use with caution though. I've got this crashing the UnityEditor (2019 LTS) in a somewhat random manner (actually it crashes rarely but it does). Calling it from SceneView.duringSceneGui:

    Code (CSharp):
    1. 0x00007FF629795EE7 (Unity) HandleUtilityBindings::IntersectRayMesh
    2. 0x00007FF62977CB5E (Unity) HandleUtility_CUSTOM_IntersectRayMesh_Injected
    3. 0x0000017376549C8B (Mono JIT Code) (wrapper managed-to-native) UnityEditor.HandleUtility:IntersectRayMesh_Injected (UnityEngine.Ray&,UnityEngine.Mesh,UnityEngine.Matrix4x4&,UnityEngine.RaycastHit&)
    4. 0x000001737654941B (Mono JIT Code) UnityEditor.HandleUtility:IntersectRayMesh (UnityEngine.Ray,UnityEngine.Mesh,UnityEngine.Matrix4x4,UnityEngine.RaycastHit&)
    5. 0x0000017376549ACD (Mono JIT Code) (wrapper runtime-invoke) <Module>:runtime_invoke_bool_Ray_object_Matrix4x4_intptr& (object,intptr,intptr,intptr)
    6. 0x00007FFDD3CED6B0 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\mini\mini-runtime.c:2809] mono_jit_runtime_invoke
    7. 0x00007FFDD3C72912 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\metadata\object.c:2921] do_runtime_invoke
    8. 0x00007FFDD3C7BB42 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\metadata\object.c:3073] mono_runtime_invoke_checked
    9. 0x00007FFDD3C7C2D9 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\metadata\object.c:5264] mono_runtime_try_invoke_array
    10. 0x00007FFDD3C7BAD6 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\metadata\object.c:5142] mono_runtime_invoke_array_checked
    11. 0x00007FFDD3C20384 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\metadata\icall.c:3358] ves_icall_InternalInvoke
    12. 0x00000173272EBA86 (Mono JIT Code) (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
    13. 0x00000173272EA43B (Mono JIT Code) System.Reflection.MonoMethod:Invoke (object,System.Reflection.BindingFlags,System.Reflection.Binder,object[],System.Globalization.CultureInfo)
    14. 0x00000173272EA0FF (Mono JIT Code) System.Reflection.MethodBase:Invoke (object,object[])
    15. ...
    16. 0x000001737565D76E (Mono JIT Code) UnityEditor.SceneView:CallOnSceneGUI ()
    17. 0x0000017375659063 (Mono JIT Code) UnityEditor.SceneView:HandleSelectionAndOnSceneGUI ()
    18. 0x0000017375612EEB (Mono JIT Code) UnityEditor.SceneView:OnGUI ()
    19. 0x0000017326E613B8 (Mono JIT Code) (wrapper runtime-invoke) object:runtime_invoke_void__this__ (object,intptr,intptr,intptr)
    20. 0x00007FFDD3CED6B0 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\mini\mini-runtime.c:2809] mono_jit_runtime_invoke
    21. 0x00007FFDD3C72912 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\metadata\object.c:2921] do_runtime_invoke
    22. 0x00007FFDD3C7BB42 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\metadata\object.c:3073] mono_runtime_invoke_checked
    23. 0x00007FFDD3C7C2D9 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\metadata\object.c:5264] mono_runtime_try_invoke_array
    24. 0x00007FFDD3C7BAD6 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\metadata\object.c:5142] mono_runtime_invoke_array_checked
    25. 0x00007FFDD3C20384 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\metadata\icall.c:3358] ves_icall_InternalInvoke
    26. 0x00000173272EBA86 (Mono JIT Code) (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
    27. 0x00000173272EA43B (Mono JIT Code) System.Reflection.MonoMethod:Invoke (object,System.Reflection.BindingFlags,System.Reflection.Binder,object[],System.Globalization.CultureInfo)
    28. 0x00000173272EA0FF (Mono JIT Code) System.Reflection.MethodBase:Invoke (object,object[])
    29. 0x0000017329735CAB (Mono JIT Code) UnityEditor.HostView:Invoke (string,object)
    30. 0x0000017329735B1B (Mono JIT Code) UnityEditor.HostView:Invoke (string)
    31. 0x0000017351E8E2AB (Mono JIT Code) UnityEditor.HostView:InvokeOnGUI (UnityEngine.Rect,UnityEngine.Rect)
    32. 0x0000017351E8DD63 (Mono JIT Code) UnityEditor.DockArea:DrawView (UnityEngine.Rect,UnityEngine.Rect)
    33. 0x0000017351E7A55B (Mono JIT Code) UnityEditor.DockArea:OldOnGUI ()
    34. 0x0000017351E42B52 (Mono JIT Code) UnityEngine.UIElements.IMGUIContainer:DoOnGUI (UnityEngine.Event,UnityEngine.Matrix4x4,UnityEngine.Rect,bool,UnityEngine.Rect,System.Action,bool)
    35. 0x0000017351E405C3 (Mono JIT Code) UnityEngine.UIElements.IMGUIContainer:HandleIMGUIEvent (UnityEngine.Event,UnityEngine.Matrix4x4,UnityEngine.Rect,System.Action,bool)
    36. 0x00000173755CD093 (Mono JIT Code) UnityEngine.UIElements.IMGUIContainer:DoIMGUIRepaint ()
    37. 0x00000173755C8EA6 (Mono JIT Code) UnityEngine.UIElements.UIR.RenderChainCommand:ExecuteNonDrawMesh (UnityEngine.UIElements.UIR.DrawParams,bool,single,System.Exception&)
    38. 0x00000173755C2853 (Mono JIT Code) UnityEngine.UIElements.UIR.UIRenderDevice:EvaluateChain (UnityEngine.UIElements.UIR.RenderChainCommand,UnityEngine.Rect,UnityEngine.Matrix4x4,UnityEngine.UIElements.PanelClearFlags,UnityEngine.Texture,UnityEngine.Texture,UnityEngine.Texture,single,Unity.Collections.NativeArray`1<UnityEngine.UIElements.UIR.Transform3x4>,Unity.Collections.NativeArray`1<UnityEngine.Vector4>,System.Exception&)
    39. 0x00000173755B8D5B (Mono JIT Code) UnityEngine.UIElements.UIR.UIRenderDevice:DrawChain (UnityEngine.UIElements.UIR.RenderChainCommand,UnityEngine.Rect,UnityEngine.Matrix4x4,UnityEngine.UIElements.PanelClearFlags,UnityEngine.Texture,UnityEngine.Texture,UnityEngine.Texture,single,Unity.Collections.NativeArray`1<UnityEngine.UIElements.UIR.Transform3x4>,Unity.Collections.NativeArray`1<UnityEngine.Vector4>,System.Exception&)
    40. 0x00000173755937EB (Mono JIT Code) UnityEngine.UIElements.UIR.RenderChain:Render (UnityEngine.Rect,UnityEngine.Matrix4x4,UnityEngine.UIElements.PanelClearFlags)
    41. 0x000001737558F2FB (Mono JIT Code) UnityEngine.UIElements.UIRRepaintUpdater:DrawChain (UnityEngine.Rect,UnityEngine.Matrix4x4)
    42. 0x000001737558E2DE (Mono JIT Code) UnityEngine.UIElements.UIRRepaintUpdater:Update ()
    43. 0x000001732CA540DA (Mono JIT Code) UnityEngine.UIElements.VisualTreeUpdater:UpdateVisualTreePhase (UnityEngine.UIElements.VisualTreeUpdatePhase)
    44. 0x000001737558C5A3 (Mono JIT Code) UnityEngine.UIElements.Panel:UpdateForRepaint ()
    45. 0x000001737558BC8B (Mono JIT Code) UnityEngine.UIElements.Panel:Repaint (UnityEngine.Event)
    46. 0x000001732CA52EE1 (Mono JIT Code) UnityEngine.UIElements.UIElementsUtility:DoDispatch (UnityEngine.UIElements.BaseVisualElementPanel)
    47. 0x000001732CA5289B (Mono JIT Code) UnityEngine.UIElements.UIElementsUtility:ProcessEvent (int,intptr)
    48. 0x000001732CA520E3 (Mono JIT Code) UnityEngine.GUIUtility:ProcessEvent (int,intptr)
    49.  
     
  6. Sandler

    Sandler

    Joined:
    Nov 6, 2015
    Posts:
    118
    i get this crash error with unity 2019.4 LTS


    Stack Trace of Crashed Thread 14372:
    ERROR: SymGetSymFromAddr64, GetLastError: 'Es wurde versucht, auf eine unzulässige Adresse zuzugreifen.' (Address: 00000001415B39A7)
    0x00000001415B39A7 (Unity) (function-name not available)
    ERROR: SymGetSymFromAddr64, GetLastError: 'Es wurde versucht, auf eine unzulässige Adresse zuzugreifen.' (Address: 000000014159A84E)
    0x000000014159A84E (Unity) (function-name not available)
    0x00000000029584FB (UnityEditor) UnityEditor.HandleUtility.IntersectRayMesh_Injected()
     
  7. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,585
    I've only recently realized that there is already an exposed API for raycasting into scene since Unity 5: HandleUtility.RaySnap.

    P.S. My mistake. RaySnap doesn't work with scene geometry without colliders so it isn't really a solution to the original problem.
     
    Last edited: Jun 30, 2021
    _geo__ likes this.
  8. _geo__

    _geo__

    Joined:
    Feb 26, 2014
    Posts:
    662
    Nice find, thank you for sharing. Have you tested it with SceneView.duringSceneGui? I've had some problems with raycasting from there.
     
  9. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,585
    With the original solution, I've had this issue on 2019 LTS. Skipping Layout and Repaint events as suggested has worked for me (it has also worked well inside SceneView.duringSceneGui on Windows). Here's the code for reference:
    Code (CSharp):
    1. private static readonly MethodInfo intersectRayMeshMethod = typeof( HandleUtility ).GetMethod( "IntersectRayMesh", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static );
    2. private static GameObject lastGameObjectUnderCursor;
    3.  
    4. private void OnSceneGUI()
    5. {
    6.     if( RaycastAgainstScene( out RaycastHit hit ) )
    7.     {
    8.         // Use RaycastHit here
    9.         Handles.ArrowHandleCap( 0, hit.point, Quaternion.LookRotation( hit.normal ), HandleUtility.GetHandleSize( hit.point ), Event.current.type );
    10.     }
    11. }
    12.  
    13. public static bool RaycastAgainstScene( out RaycastHit hit )
    14. {
    15.     Ray ray = HandleUtility.GUIPointToWorldRay( Event.current.mousePosition );
    16.  
    17.     // First, try raycasting against scene geometry with or without colliders (it doesn't matter)
    18.     // Credit: https://forum.unity.com/threads/editor-raycast-against-scene-meshes-without-collider-editor-select-object-using-gui-coordinate.485502
    19.     GameObject gameObjectUnderCursor;
    20.     switch( Event.current.type )
    21.     {
    22.         // HandleUtility.PickGameObject doesn't work with some EventTypes in OnSceneGUI
    23.         case EventType.Layout:
    24.         case EventType.Repaint:
    25.         case EventType.ExecuteCommand: gameObjectUnderCursor = lastGameObjectUnderCursor; break;
    26.         default: gameObjectUnderCursor = HandleUtility.PickGameObject( Event.current.mousePosition, false ); break;
    27.     }
    28.  
    29.     if( gameObjectUnderCursor )
    30.     {
    31.         Mesh meshUnderCursor = null;
    32.         if( gameObjectUnderCursor.TryGetComponent( out MeshFilter meshFilter ) )
    33.             meshUnderCursor = meshFilter.sharedMesh;
    34.         if( !meshUnderCursor && gameObjectUnderCursor.TryGetComponent( out SkinnedMeshRenderer skinnedMeshRenderer ) )
    35.             meshUnderCursor = skinnedMeshRenderer.sharedMesh;
    36.  
    37.         if( meshUnderCursor )
    38.         {
    39.             // Remember this GameObject so that it can be used inside problematic EventTypes, as well
    40.             lastGameObjectUnderCursor = gameObjectUnderCursor;
    41.  
    42.             object[] rayMeshParameters = new object[] { ray, meshUnderCursor, gameObjectUnderCursor.transform.localToWorldMatrix, null };
    43.             if( (bool) intersectRayMeshMethod.Invoke( null, rayMeshParameters ) )
    44.             {
    45.                 hit = (RaycastHit) rayMeshParameters[3];
    46.                 return true;
    47.             }
    48.         }
    49.         else
    50.             lastGameObjectUnderCursor = null;
    51.     }
    52.  
    53.     // Raycast against scene geometry with colliders
    54.     object raycastResult = HandleUtility.RaySnap( ray );
    55.     if( raycastResult != null && raycastResult is RaycastHit )
    56.     {
    57.         hit = (RaycastHit) raycastResult;
    58.         return true;
    59.     }
    60.  
    61.     hit = new RaycastHit();
    62.     return false;
    63. }
     
    Last edited: Jun 30, 2021
    _geo__ likes this.
  10. _geo__

    _geo__

    Joined:
    Feb 26, 2014
    Posts:
    662
    Thank you for sharing!
    Back when I faced the reflections error I used a per triangle raycast. It works on any mesh and performance is decent (though I would prefer your native solution now).

    For the interested here is the code (maybe useful for selecting single triangles):

    Code (CSharp):
    1. /// <summary>
    2. /// Returns the distance to the mesh from the raycast origin. Returns float.NaN if no hit was found.
    3. /// </summary>
    4. /// <param name="ray"></param>
    5. /// <param name="objectWithMeshFilter"></param>
    6. /// <param name="maxDistance"></param>
    7. /// <returns>Distance as float or float.NaN</returns>
    8. private static float RayCastMesh(Ray ray, GameObject objectWithMeshFilter, float maxDistance = 1000f)
    9. {
    10.     if (objectWithMeshFilter != null)
    11.     {
    12.         float distance = float.NaN;
    13.         // check all triangles for hit with raycast
    14.         var meshFilter = objectWithMeshFilter.GetComponent<MeshFilter>();
    15.         if (meshFilter != null)
    16.         {
    17.             int[] triangles = meshFilter.sharedMesh.triangles;
    18.             Vector3[] vertices = meshFilter.sharedMesh.vertices;
    19.             int a, b, c;
    20.             for (int i = 0; i < triangles.Length; i = i + 3)
    21.             {
    22.                 a = triangles[i];
    23.                 b = triangles[i + 1];
    24.                 c = triangles[i + 2];
    25.                 /*
    26.                 Debug.DrawLine(meshFilter.transform.TransformPoint(vertices[a]), meshFilter.transform.TransformPoint(vertices[b]), Color.red, 3.0f);
    27.                 Debug.DrawLine(meshFilter.transform.TransformPoint(vertices[b]), meshFilter.transform.TransformPoint(vertices[c]), Color.red, 3.0f);
    28.                 Debug.DrawLine(meshFilter.transform.TransformPoint(vertices[c]), meshFilter.transform.TransformPoint(vertices[a]), Color.red, 3.0f); //*/
    29.                 distance = IntersectRayTriangle(
    30.                     ray,
    31.                     meshFilter.transform.TransformPoint(vertices[a]),
    32.                     meshFilter.transform.TransformPoint(vertices[b]),
    33.                     meshFilter.transform.TransformPoint(vertices[c]));
    34.                 if (!float.IsNaN(distance))
    35.                 {
    36.                     break;
    37.                 }
    38.             }
    39.         }
    40.         if (float.IsNaN(distance) == false)
    41.         {
    42.             if (distance < maxDistance)
    43.             {
    44.                 return distance;
    45.             }
    46.         }
    47.     }
    48.  
    49.     return float.NaN;
    50. }
    51.  
    52. const float kEpsilon = 0.000001f;
    53.  
    54. /// <summary>
    55. /// Thanks to: https://answers.unity.com/questions/861719/a-fast-triangle-triangle-intersection-algorithm-fo.html
    56. /// Ray-versus-triangle intersection test suitable for ray-tracing etc.
    57. /// Port of Möller–Trumbore algorithm c++ version from:
    58. /// https://en.wikipedia.org/wiki/Möller–Trumbore_intersection_algorithm
    59. /// </summary>
    60. /// <returns><c>The distance along the ray to the intersection</c> if one exists, <c>NaN</c> if one does not.</returns>
    61. /// <param name="ray">the ray</param>
    62. /// <param name="v0">A vertex 0 of the triangle.</param>
    63. /// <param name="v1">A vertex 1 of the triangle.</param>
    64. /// <param name="v2">A vertex 2 of the triangle.</param>
    65. public static float IntersectRayTriangle(Ray ray, Vector3 v0, Vector3 v1, Vector3 v2)
    66. {
    67.     // edges from v1 & v2 to v0.
    68.     Vector3 e1 = v1 - v0;
    69.     Vector3 e2 = v2 - v0;
    70.  
    71.     Vector3 h = Vector3.Cross(ray.direction, e2);
    72.     float a = Vector3.Dot(e1, h);
    73.     if ((a > -kEpsilon) && (a < kEpsilon))
    74.     {
    75.         return float.NaN;
    76.     }
    77.  
    78.     float f = 1.0f / a;
    79.  
    80.     Vector3 s = ray.origin - v0;
    81.     float u = f * Vector3.Dot(s, h);
    82.     if ((u < 0.0f) || (u > 1.0f))
    83.     {
    84.         return float.NaN;
    85.     }
    86.  
    87.     Vector3 q = Vector3.Cross(s, e1);
    88.     float v = f * Vector3.Dot(ray.direction, q);
    89.     if ((v < 0.0f) || (u + v > 1.0f))
    90.     {
    91.         return float.NaN;
    92.     }
    93.  
    94.     float t = f * Vector3.Dot(e2, q);
    95.     if (t > kEpsilon)
    96.     {
    97.         return t;
    98.     }
    99.     else
    100.     {
    101.         return float.NaN;
    102.     }
    103. }
     
    Last edited: Jun 30, 2021
    oleg_v likes this.
  11. sachithkp

    sachithkp

    Joined:
    Jun 7, 2021
    Posts:
    12
    Does this work in the Game window as well ?
     
    Last edited: Jun 30, 2021
  12. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,585
    HandleUtility.PickGameObject doesn't work inside Game window.
     
    sachithkp likes this.
  13. _geo__

    _geo__

    Joined:
    Feb 26, 2014
    Posts:
    662
    I don't think it works on the game scene while editing (it's hard to get any events from the game view if you're not in play mode). If you rather mean "in game view at run time" then I don't see why the manual (shared mesh + triangle check) should not work (as long as the mesh is readable). Though I have not tested it. Just give it a try.
     
    sachithkp likes this.
  14. sachithkp

    sachithkp

    Joined:
    Jun 7, 2021
    Posts:
    12
    Throwing up this error - The name 'kEpsilon' does not exist in the current context
     
  15. _geo__

    _geo__

    Joined:
    Feb 26, 2014
    Posts:
    662
    Ah sry, I just ripped it out of my code. It's just a float comparison delta value (added it above).
    Code (CSharp):
    1. const float kEpsilon = 0.000001f;
     
    sachithkp likes this.
  16. sachithkp

    sachithkp

    Joined:
    Jun 7, 2021
    Posts:
    12
    @geo: Thanks a lot for the code. It works fine. :)
     
    _geo__ likes this.
  17. sachithkp

    sachithkp

    Joined:
    Jun 7, 2021
    Posts:
    12
    @_geo__ : Can we modify this code to know if the Ray is hitting the Object or not ?

    Have any suggestions on this?
     
  18. _geo__

    _geo__

    Joined:
    Feb 26, 2014
    Posts:
    662
    That's what "RayCastMesh" from above does. If it returns float.NaN then the game object was not hit.
     
    sachithkp likes this.
  19. sachithkp

    sachithkp

    Joined:
    Jun 7, 2021
    Posts:
    12
    @_geo__:Is there a way to find the closest point from the mesh. I am unable to decode the code.

    If you can shed some light, that would be really grateful.

    This is what I have done:

    int[] triangles = meshFilter.sharedMesh.triangles;
    Vector3[] vertices = meshFilter.sharedMesh.vertices;
    int a, b, c;

    Vector3[] worldPOS = new Vector3[vertices.Length];
    for (int j = 0; j < vertices.Length; j++)
    {
    worldPOS[j] = objectWithMeshFilter.transform.TransformPoint(vertices[j]);

    if (temp == 0)
    {
    temp = Vector3.Distance(worldPOS[j], Player.transform.position);
    }
    else if (temp >Vector3.Distance(worldPOS[j], Player.transform.position))
    {
    temp = Vector3.Distance(worldPOS[j], Player.transform.position);
    temp_ = worldPOS[j];
    Debug.Log("Distance: "+ temp);

    }
    }

     
    Last edited: Jul 13, 2021
  20. Ziflin

    Ziflin

    Joined:
    Mar 12, 2013
    Posts:
    119
    Can someone from Unity please just expose whatever Middle-Mouse click does in the SceneView? We need a way to get the result of a ray-cast into the SceneView without requiring that everything have colliders. Trying to update visible and collision meshes at the same time as they're modified with our mesh editing tool is just too slow.
     
  21. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,585
    Last edited: Aug 3, 2021
  22. Ziflin

    Ziflin

    Joined:
    Mar 12, 2013
    Posts:
    119
    Thanks @yasirkula for the link. I've been using the reflected HandleUtility.IntersectRayMesh method for 6 months or so in our custom terrain editor and was hoping that someone from Unity would see this thread. It's annoying that some of these basic features of the scene view are not exposed so that we can make proper tools without relying on reflection. I personally do not want to release our tools to the asset store with them using non-public APIs. Nor do I wish to rewrite what Unity has already written.
     
    CDF likes this.
  23. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,585
    I agree. There are a lot of unused public functions inside Unsupported and UnityEditorInternal classes, HandleUtility.IntersectRayMesh could've easily been made public. But don't let it discourage you from using reflection in your Asset Store packages. Just make sure that the function's signature is the same on all Unity versions you're planning to support and if not, use preprocessor directives like
    #if UNITY_2019_3_OR_NEWER
    to handle these changes.
     
unityunity