Computing precise mesh intersections is usually prohibitively expensive at runtime0, but it’s still useful for editor scripts and the like. Unity has a built in function for raycasting against a mesh:
UnityEditor.HandleUtility.IntersectRayMesh
Now, if you excuse the fact that it is
- editor-only1
- internal
- unsupported
- could move
- or change
- or break
- or disappear in any engine update, here’s how you conveniently use it:
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using UnityEngine;
using static System.Reflection.BindingFlags;
public static class MeshFilterExtensions
{
public static RaycastHit? IntersectRayMesh(this MeshFilter meshFilter, in Ray ray)
=> intersectRayMeshFunc(ray, meshFilter.sharedMesh, meshFilter.transform.localToWorldMatrix, out var result) ? result : null;
delegate bool IntersectRayMeshDelegate(Ray ray, Mesh mesh, Matrix4x4 matrix, out RaycastHit hit);
static readonly IntersectRayMeshDelegate intersectRayMeshFunc
=
#if UNITY_EDITOR
(IntersectRayMeshDelegate)
typeof(UnityEditor.HandleUtility)
.GetMethod("IntersectRayMesh", Static | NonPublic)
.CreateDelegate(typeof(IntersectRayMeshDelegate));
#else
null;
#endif
}
0
1
2
3
var ray = new Ray(/* ... */);
if (GetComponent<MeshFilter>().IntersectRayMesh(ray) is { distance: < 1f } hit)
Debug.Log(hit.collider);
-
If you want to do raycasts at runtime, you’ll want to use simplified collision meshes or approximate your object’s shape using several primitive colliders. Using high-poly mesh colliders will murder your physics engine. return ︿
-
This trick won’t work at runtime (in player builds).
The code compiles even inAssembly-CSharp
, but you might wanna put this whole thing inAssembly-CSharp-Editor
or somewhere instead return ︿