射线检测主要用于像子弹是否打中物体,捡取物品等情况,本来面向百度想找例子看看, 不过没找到合适的,还是自己总结尝试吧。
以下测试Unity3D版本:2017.4.2f2
射线的检测步骤如下:
1.Ray
这个类为了产生一个射线,如果我们想要场景中某个物体产生一个射线,只需要定义一个ray,给予一个初始位置,以及方向便可以了。
public Ray(Vector3 origin, Vector3 direction);
2.RaycastHit
这个类就是为了存储发射射线后产生的碰撞信息。
Unity内部该类的代码,该函数可以存储如下信息:(中文是我个人翻译,仅供参考)
public struct RaycastHit
{
//The barycentric coordinate of the triangle we hit.//打中三角形的重心坐标
public Vector3 barycentricCoordinate { get; set; }
//The Collider that was hit.//打中的碰撞体
public Collider collider { get; }
//The distance from the ray's origin to the impact point.
//打中后与原始位置的距离
public float distance { get; set; }
//The uv lightmap coordinate at the impact point.
//在碰撞点处的uv坐标
public Vector2 lightmapCoord { get; }
// The normal of the surface the ray hit.//射线撞击处的表面法线
public Vector3 normal { get; set; }
//The impact point in world space where the ray hit the collider.
//打到碰撞体后,碰撞点的世界坐标
public Vector3 point { get; set; }
// The Rigidbody of the collider that was hit. If the collider is not attached to
// a rigidbody then it is null.
//达到的刚体,若没有刚体组件,返回空
public Rigidbody rigidbody { get; }
//The uv texture coordinate at the collision location.
//碰撞点的uv纹理坐标
public Vector2 textureCoord { get; }
[Obsolete("Use textureCoord2 instead")]
public Vector2 textureCoord1 { get; }
//The secondary uv texture coordinate at the impact point.
//碰撞点的第二个uv纹理坐标
public Vector2 textureCoord2 { get; }
//The Transform of the rigidbody or collider that was hit.
//打中刚体或者碰撞体的Transform
public Transform transform { get; }
//The index of the triangle that was hit.
//打中三角形的索引
public int triangleIndex { get; }
}
有了这个类存储信息,我们便能跟Ray结合起来一起用。怎么结合呢?这就需要找一个函数把Ray打中的物体信息存储到RaycastHit里面,那么就需要找到Physics.Raycast()函数。
3.Physics.Raycast()
这个函数返回bool类型,表示打没打中。有多种方法尝试,常见的如下;
public static bool Raycast(Ray ray, RaycastHit hitInfo, float maxDistance , int layerMask);
public static bool Raycast(Ray ray, float maxDistance , int layerMask);
public static bool Raycast(Vector3 origin, Vector3 direction, float maxDistance , int layerMask);
public static bool Raycast(Vector3 origin, Vector3 direction, RaycastHit hitInfo, float maxDistance ,int layerMask );
ray:射线;RaycastHit hitInfo 存储信息; float maxDistance 是射线检查碰撞的最大距离;int layerMask 表示碰撞第几层;
注:
- 这里 float maxDistance默认值无穷大;
- int layerMask默认值为DefaultRaycastLayers,所以两者均可不输入。
- 当然如果不想存打中物体的信息,只想判断打中过任意一个物体,也不用输入RaycastHit hitInfo。
4.例子
代码如下:
public class emitRay : MonoBehaviour {
public GameObject origin_1;
public GameObject target_1;
void Start () {
rayTest(origin_1.transform.position, target_1.transform.position);
}
void rayTest(Vector3 origin_pos, Vector3 target_pos)//初始位置,检测位置
{
Vector3 direction = direction = (target_pos - origin_pos).normalized; //方向
Ray r1 = new Ray(origin_pos, direction);
// Debug.DrawLine(origin_pos, origin_pos + direction_1 * 10, Color.red);
RaycastHit hit;
if(Physics.Raycast(r1, out hit, 10f))//out关键字主要为了不用初始给hit形参赋值
{
Debug.Log("打中");
GameObject m1 = hit.collider.gameObject;
//...这里就可以提取RaycastHit存储的信息做各种操作了
}
else
{
Debug.Log("未打中");
}
}
}