Unity 基础 之 Ray 射线简单介绍和使用忽略碰撞层的时候的注意事项(记得添加距离,不然 layer mask 可能无效)
目录
一、简单介绍
Unity中的一些基础知识点。
射线是3D世界中一个点向一个方向发射无终点的线。在unity3d中我们发射的射线一旦与其他的碰撞器发生碰撞,射线将停止发射。在游戏制作过程中 我们可以通过判断射线是否发生了碰撞,并且可以判断射线和谁发生了碰撞。应用范围非常广泛,如射击类游戏中用它来判断是否射中目标。
二、射线的简单介绍
1、Physics.Raycast 光线投射 (重载的函数很多,这里简单介绍一个常用的)
static function Raycast (origin : Vector3, direction : Vector3, out hitInfo : RaycastHit, distance : float = Mathf.Infinity, layerMask : int = kDefaultRaycastLayers) : bool
在场景中投下可与所有碰撞器碰撞的一条光线,并返回碰撞的细节信息。
-
origin
The starting point of the ray in world coordinates.
在世界坐标,射线的起始点。 -
direction
The direction of the ray.
射线的方向。 -
distance
The length of the ray
射线的长度。 -
hitInfo
If true is returned, hitInfo will contain more information about where the collider was hit (See Also: RaycastHit).
如果返回true,hitInfo将包含碰到器碰撞的更多信息。 -
layerMask
A Layer mask that is used to selectively ignore colliders when casting a ray.
只选定Layermask层内的碰撞器,其它层内碰撞器忽略。
Returns
当光线投射与任何碰撞器交叉时为真,否则为假。
使用c#中out关键字传入一个空的碰撞信息类,然后碰撞后赋值。可以得到碰撞物体的transform,rigidbody,point等信息。
1)如图所示,每一个物体都有一个Tag和Layer标签,tag就是一个简单的标签,可以用来区分不同的物体,LayerMask的作用是可以选择性地过滤物体,例如当投射射线时,比如camera.cullingmask和光线投射时候。
2)如图,可以在TagManager中编辑tag和Layer
3)然后设置物体的Layer层级,在摄像机中设置camera.cullingmask,可以控制摄像机的渲染层级,用在射线上,可以控制射线碰撞什么,不碰撞什么。
//Raycast hit
RaycastHit hit;
LayerMask mask = 1 << 8;
说明:
1 << 9 打开第9层。
~(1 << 9) 打开除了第9之外的层。
~(1 << 0) 打开所有的层。
(1 << 10) | (1 << 8) 打开第10和第8的层。
或者使用层名称
1 << LayerMask.NameToLayer("Cube"); // 等价于 (1 << 9)
~(1 << LayerMask.NameToLayer("Cube"); // 等价于 ~(1 << 9)
以此类推
三、射线使用的一般步骤
1、创建一条射线的方法Ray (origin : Vector3, direction : Vector3)
Origin是射线的起点,direction是射线的方向。
例如:Ray ray=new Ray(Vector3.zero,transform.position); //定义一条射线,起点为Vector3.zero终点为物体坐标
常用点击屏幕发射射线如 Ray ray=Camera.main.ScreenPointToRay(Input.mousePosition);//定义一条射线
2、声明:RaycastHit hit; //定义一个光线投射碰撞
3、物理投射:Physics.Raycast(ray,out hit,100); //发射射线长度为100
4、(可忽略)辅助射线:Debug.DrawLine(ray.origin,hit.point); //在Scene中生成这条射线,起点为射线的起点,终点为射线与物体的碰撞点
四、注意事项
1、使用忽略碰撞层的时候,记得添加距离,不然 layer mask 可能无效
五、简单案例效果预览
六、简单案例实现步骤
1、打开Unity,新建一个空工程
2、添加两个 layer ,一个为 Cube ,一个为 NonCube
层前面的数字即为第几层
3、添加脚本实现相机屏幕点击发射射线,只碰撞 Cube 层
4、在场景中添加一个物体,作为射线碰撞效果使用,Cube 为 Cube 层,NonCube 为 NonCube 层,并添加材质颜色
5、把脚本挂载到场景中
6、运行场景,效果如下,射线只碰撞 Cube 层
七、关键代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RaycastMask : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButton(0))
{
CameraRaycast();
}
}
/// <summary>
/// 鼠标相机射线
/// </summary>
void CameraRaycast()
{
//从摄像机发出到点击坐标的射线
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hitInfo;
LayerMask mask = 1 << LayerMask.NameToLayer("Cube"); // 等价于 (1 << 8)
if (Physics.Raycast(ray, out hitInfo, 1000, mask))
{
//划出射线,只有在scene视图中才能看到
Debug.DrawLine(ray.origin, hitInfo.point);
GameObject gameObj = hitInfo.collider.gameObject;
Debug.Log("click object name is " + gameObj.name);
}
}
}