Unity的射线

2022-07-28,

Ray射线

今天我要总结的使Unity有关射线的相关东西,如有某些地方理解错误还望指正,谢谢!

1.什么Ray射线

首先,我们要知道射线构成的两大要素:起点和方向,所以实例化一条射线需要这两个参数。

射线的实例化:
关键字)Ray 变量名 = new (关键字)Ray(Vector3 origin,Vector3 direction);
第一个参数origin表示射线的起点,第二个参数direction表示射线的方向。

特殊的Camera.main.ScreenPointToRay(Vector3 targetPosition)
表示摄像机向目标位置发射射线其中targetPosition通常会使用屏幕坐标
Input.mousePosition,表示摄像机向鼠标位置发射射线。

2. RaycastHit类的介绍

作用:用于储存发射射线产生的碰撞信息。
常用的成员变量有:

point:射线与碰撞器的交点坐标

collider:与射线发生碰撞的物体的碰撞器

distance:射线起点到与碰撞物体交点的坐标

3.射线的调试(显示)

Debug.DrawRay(Vector3 start, Vector3 dir, Color color, float duration)

参数start:射线的起点
参数dir:射线的方向
参数color:调试中射线的颜色
参数duration:调试中射线的存在的时间

当然Debug.DrawRay函数有很多重载,比如我们可以不写Color color, float duration,那么我们的射线在编辑模式下,射线的颜色就默认是白色,存在时间默认是一帧;

把下面这个脚本放在一个物体,然后运行,在编辑模式就可看到以(0,0,0)为起点,方向为沿X轴正方向的红色 射线。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Shoot : MonoBehaviour
{
  
    void Update()
    {
        Vector3 origin = new Vector3(0, 0, 0);
        Vector3 direction = new Vector3(1f, 0, 0);
        Ray ray = new Ray(origin, direction);
        Debug.DrawRay(ray.origin, ray.direction * 100f, Color.red, 1f);
    }
}

4.射线的发射:bool Physics.Raycast(Ray ray, out RaycastHit hitInfo, float maxDistance, int layerMask,QueryTriggerInteraction );
参数start:射线的起点

参数ray:射线

参数hitInfo:储存被射线碰撞到的物体信息

参数maxDistance:射线的最大距离

参数layerMask:射线检测的图层,用int 十进制转化为二进制判断,(十进制)2->(二进制)10,表示 检 测第一层TransparentFX;

参数QueryTriggerInteraction :查询是否忽略is Trigger(触发器),忽略使用QueryTriggerInteraction.Ignore,检测使用QueryTriggerInteraction.Collide

函数描述:发射一条射线ray,这条射线的长度为maxDistance,如果这条射线在指定图层碰到了其它带有碰撞器的物体,则把该物体信息储存在hitInfo中,且返回true,如果没碰到物体就返回false;
当然这个函数还有其它重载,比如我们可以不写 float maxDistance, int layerMask,QueryTriggerInteraction 这三个参数,那么发射射线的最大距离默认为无限大,图层就默认检测除了2 图层Ignore Raycast外的其它图层,参数QueryTriggerInteraction 就为QueryTriggerInteraction.UseGlobal,也就是我们项目设置里面的默认设置。如果勾了就默认检测,否则就忽略;

然后我们在一个物体上添加如下脚本,并在射线经过的地方摆一个盒形碰撞器。然后运行并点击一下鼠标左键,然后你就会在控制台上发现射线碰撞到的物体的碰撞器的种类。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Rayshoot : MonoBehaviour
{
    bool isnoShoot;
   public Vector3 Direction;
   

    // Update is called once per frame
    void Update()
    {
        // Input.GetMouseButtonDown(0)点击鼠标左键返回true,否则返回false
        isnoShoot = Input.GetMouseButtonDown(0);
        // Shoot();
        if (isnoShoot)
        {
            Vector3 origin = new Vector3(0, 0, 0);
            Vector3 direction = new Vector3(1f, 0, 0);
            Ray ray = new Ray(origin, direction);
            //实例了一条以(0,0,0)为起点,方向为沿X轴正方向的射线
            Debug.DrawRay(ray.origin, ray.direction * 100f, Color.red, 1f);
            RaycastHit hit;
            Physics.Raycast(ray, out hit, 100f, 1, QueryTriggerInteraction.Collide);
            Debug.Log(hit.collider);
        }
    }  
}

射线的应用场景

射线的应用场景有很多,由于篇幅有限,我们就模拟一下人物射击。

首先我们需要在场景中创建一个球形碰撞器,然后通过拖动把它变成预制体,然后删除场景中的球形碰撞器,然后在在预制体上增加以下脚本。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class bullet : MonoBehaviour
{
    Vector3 shootdirection;
    float speed;
    // Start is called before the first frame update
    void Start()
    {
        speed = 6f;
    }

    // Update is called once per frame
    void Update()
    {
        transform.Translate(shootdirection*speed*Time.deltaTime,Space.World);
    }

    /// <summary>
    /// 初始化子弹移动的方向
    /// </summary>
    /// <param name="shoot"></param>
   public void startState(Ray shoot)
    {       
        
        shootdirection = shoot.direction;
    }
}

然后我们在场景中再创键一个球形碰撞器模拟人物,并在上面添加如下脚本。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class roleshoot : MonoBehaviour
{
    bool isnoShoot;
    public bullet bullets;
 
    // Update is called once per frame
    void Update()
    {
        isnoShoot = Input.GetMouseButtonDown(0);
        if(isnoShoot)
        {
            RoleShoot();
        }
    }
    void RoleShoot()
    {
        //摄像机向鼠标所在的地方发射射线
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;//定义一个RaycastHit接受被碰撞物体的信息
        
        //发射射线
       Physics.Raycast(ray, out hit, 100f, 1, QueryTriggerInteraction.Collide);
     
       
        Vector3 shootdirection = hit.point - transform.position;

        //实例主角应该发射的射线
        Ray roleray = new Ray(transform.position, shootdirection);

        //让射线在编辑模式中可见
        Debug.DrawRay(roleray.origin, roleray.direction*1000f, Color.red, 2f);
        //生成子弹,
        bullet bullet = Instantiate(bullets, transform.position, bullets.gameObject.transform.rotation);
        //初始化子弹方向
        bullet.startState(roleray);

    }
}

然后手动添加预制体.

然后点击地面就可以发射子弹了。

本文地址:https://blog.csdn.net/a15970673567/article/details/109273600

《Unity的射线.doc》

下载本文的Word格式文档,以方便收藏与打印。