用反射物理射线的方法,把这个脚本放到Editor下
/**
* Author: YinPeiQuan
**/
using UnityEngine;
using UnityEditor;
using System;
using System.Linq;
using System.Reflection;
[InitializeOnLoad]
public class RayHitRefrelection
{
public static Type type_HandleUtility;
protected static MethodInfo meth_IntersectRayMesh;
static RayHitRefrelection()
{
var editorTypes = typeof(Editor).Assembly.GetTypes();
type_HandleUtility = editorTypes.FirstOrDefault(t => t.Name == "HandleUtility");
meth_IntersectRayMesh = type_HandleUtility.GetMethod("IntersectRayMesh", (BindingFlags.Static | BindingFlags.NonPublic));
}
public static bool IntersectRayMesh(Ray ray, MeshFilter meshFilter, out RaycastHit hit)
{
return IntersectRayMesh(ray, meshFilter.mesh, meshFilter.transform.localToWorldMatrix, out hit);
}
static object[] parameters = new object[4];
public static bool IntersectRayMesh(Ray ray, Mesh mesh, Matrix4x4 matrix, out RaycastHit hit)
{
parameters[0] = ray;
parameters[1] = mesh;
parameters[2] = matrix;
parameters[3] = null;
bool result = (bool)meth_IntersectRayMesh.Invoke(null, parameters);
hit = (RaycastHit)parameters[3];
return result;
}
}
使用方法,从scene视图中心发条射线检测,获取射线射中的点
public static Vector3 GetSceneViewPosition()
{
if (null == SceneView.lastActiveSceneView)
{
return Vector3.zero;
}
Ray ray = SceneView.lastActiveSceneView.camera.ScreenPointToRay(new Vector3(SceneView.lastActiveSceneView.camera.pixelWidth / 2, SceneView.lastActiveSceneView.camera.pixelHeight / 2, 0));
MeshFilter[] componentsInChildren = GameObject.FindObjectsOfType<MeshFilter>();
float num = float.PositiveInfinity;
Vector3 point = Vector3.zero;
foreach (MeshFilter meshFilter in componentsInChildren)
{
Mesh sharedMesh = meshFilter.sharedMesh;
RaycastHit hit;
if (sharedMesh
&& RayHitRefrelection.IntersectRayMesh(ray, sharedMesh, meshFilter.transform.localToWorldMatrix, out hit)
&& hit.distance < num)
{
point = hit.point;
num = hit.distance;
}
}
return point;
}