unity中关于射线的有一个非常重要的函数类Physcics类,该类有Raycast和Linecast两种射线投射方式;第一种是以起点和射线方向为参数的投射,第二种是以起点和终点为参数的投射。既然是射线碰撞,那么被射物体必须有被碰撞组件(如BoxCollider等);下面是有关鼠标点击的射线碰撞检测(Raycast方式)(如:点物体选中,点地图行走)
Ray r = Camera.main.ScreenPointToRay(Input.mousePosition);//屏幕坐标设为射线目标位置
RaycastHit h; //射线碰撞信息
if(Physics.Raycast(r,out h,100,1<<LayerMask.NameToLayer("layer1")|1<<LayerMask.NameToLayer("layer2")))
{
if(h.collider.CompareTag("Enemy"))//敌人
{
//如果碰撞的对象是Enemy。。。
}
if(h.collider.CompareTag ("Ground"))//地形
{
//如果碰撞的对象是Ground。。。
}
}
第一行:从摄像机向鼠标点击的点发出一条射线;因为鼠标输入坐标其实就是在屏幕上的坐标,故使用ScreenPointToRay(“鼠标输入坐标”)即(屏幕坐标转射线目标位置);
第三行:if()括号里面一整块即Physics.Raycast()是bool值,满足碰撞条件即为true,即满足第4个参数;首先:参数1:r为射线;参数2:将碰撞信息存储到h,参数3:长度,太小会出现射线无法发射到目标;参数4:指定的层内碰撞器,需要先在Inspector面板的Layer设置好,即layer1和layer2,设置好之后,射线就只对拥有这些层标记的响应;
还有小问题要注意下,如果射线中间被其他物体挡住(即射线中途被拦截了),那么我们可以将可能会挡住射线的物体的Layer设为Ignore Raycast(在面板设置)。
好了,再来看看Linecast方式吧
RaycastHit hit;
if(Physics.Linecast(position1,position2,out hit))
{
if(hit.collider.gameObject.tag != null)//碰撞不为空(或自己指定碰撞体)
{
cameraPosition = hit.point;//将碰撞物体的坐标赋给相机
}
}
从坐标position1向坐标position2发射一条射线;
1:避免相机穿墙:如果是使用那种相机追随主角方式的,用这种方式,从主角向相机发射一条射线,如果中间碰撞墙,则改变相机坐标为hit.point(墙的坐标),即将相机移动到墙前面,避免穿墙;
2:攻击碰撞检测:如子弹(从子弹发出的射线要短);其他武器,如挥剑:剑移动前后两点设置射线(这个效果可能不是很精准,但也是种思路,可由此拓展)。