Unity中射线Ray和RaycastHit的简单介绍(以j经营类游戏降中物体的拖动和降落伞为例)

1.鼠标点击触发事件;

在这里介绍几个函数
private void OnMouseDown() //在Collider上面点击并且拖拽时候触发
private void OnMouseDrag() //移入Collider后触发一次
private void OnMouseEnter() //移出Collider后触发,无论点击或者未点击
private void OnMouseExit() //在Collider上面放置一直触发
private void OnMouseOver() //在Collider上面点击抬起后触发
private void OnMouseUp() //在Collider上面点击并且松手触发

2.射线触发事件;

射线是在三维世界中从一个点沿一个方向发射的一条无限长的线。在射线的轨迹上,一旦与添加了碰撞器的模型发生碰撞,将停止发射。我们可以利用射线实现子弹击中目标的检测,鼠标点击拾取物体等功能。
官方给的格式是:

public static bool Raycast(Vector3 origin, Vector3 direction, float maxDistance = Mathf.Infinity, int layerMask = DefaultRaycastLayers, QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction.UseGlobal);

(括弧里分别对着,射线的发射点,射线的方向,射线的最大距离,检测带不带碰撞器,无碰撞器打不着另一个物体)
其中后三个是可以忽略的(在需要时添加即可);

Ray:在程序中可以理解为射线,就是以某个位置(origin)朝某个方向(direction)的一条射线;

RaycastHit,它是用于存储射线碰撞到的第一个物体的信息,所以需要提前创建这个对象,用于信息的碰撞信息的存储;
ray:射线结构体的信息,包括起点,方向;也就是一条射线
hitinfo:这条射线所碰撞物体的相关信息;
maxDistance:这条射线的最大距离;
这个函数的意思就是:以射线ray经过的maxDistance长度之内,与第一个对象进行的物理碰撞的信息,存储在hitInfo中;如果有碰撞物体,返回true, 反之false;
基础知识介绍完了 我们开始一个实战吧
我们可以以射线实现鼠标接触物体触发事件;

public GameObject Cube;
public Camera MainCamera = null;
private void Update()
    {
     Ray r = MainCamera.ScreenPointToRay(Input.mousePosition);//创建射线(从摄像机到鼠标位置)
     RaycastHit HitInformation;//传递参数;
     if(Physics.Raycast (r,out HitInformation, 1000))
        {
            if(HitInformation.collider.tag == "Floor")
            {
                Destroy(Cube.gameObject);
            }
        }
    }

给上面的MainCamera和Cube赋值
然后就可以在unity中运行了即可
我们可以看到 当鼠标移到物体上的时候物体消失

3.创建降落伞的动画;

创建动画unity比较基础的知识,大家如果有不懂的可以参考我前面的博客;
在这里我们创建两个动画 分别是降落伞打开和降落伞关闭
简单来说就是降落伞体积变大 和变小;

4.创建物体;

在这里我们以一个Cube作为下落物体;
以一个Sphere作为降落伞;
首先把Sphere设置成为Cube的子物体
然后添加刚体;
使这个物体可以自由下落;

5.降落伞思路

降落伞我们都知道 是在某一个速度下落
开伞之后速度降低 起缓冲的作用;
在unity中我们只能是创建射线 通过改变射线的长度 改变开伞的高度;
我们让射线接触地面之后就开始减速 并且开伞;
开伞 就是开伞动画;减速 只要改变rigidbody 的阻力即可
在物体本身接触地面的时候
播放关闭伞的动画;

6.添加脚本

在这个物体下创建一个脚本 就叫做Down
我先把代码写出来然后分析;

public GameObject DownObject;    
 public Animation ani;     
 public Rigidbody rigidbodyObject;     
 private bool isDown = false ;//是否下落在地面上  默认为没有下落在地面
    private float Distance = 10;
      private void Start()
    {
        ani.GetComponent<Animation>();
        rigidbodyObject = GetComponent<Rigidbody>();
    }
    
    private void Update()
    {
        
        Ray DownRay = new Ray(DownObject.transform.position, Vector3.down);
        RaycastHit HitInformation;//碰撞返回的参数;
        if(!isDown)
        {
            if (Physics.Raycast(DownRay, out HitInformation  , Distance))//创建射线,最大距离为Distance=10;
            {
                if(HitInformation.collider.tag == "envrionment")
                {
                    Downt();
                }
            }
        }
    }
    private void Downt()
    {
        isDown = true;//下落在地面
        rigidbodyObject.drag = 8;//阻力为8;
        ani.Play("Open");//开伞动画
    }
    private void OnCollisionEnter()
    {
        ani.Play("Close");//关伞动画;
    }

以上代码就是创建射线;
private float Distance = 10;
根据上面我给的介绍 可以知道Distance是这个射线的长度;
public Animation ani; 这个是声明动画(不清楚的话可以到我前面的博客看);
注意把地面的标签设置为envrionment;

7.实现经营类游戏中物体的拖动

在unity中创建场景中创建Cube
在他上面添加脚本

    public GameObject Cube;
    public Camera MainCamera;
    private void OnMouseDrag()
    {
        MoveObject();//调用下面函数
    }
    void MoveObject()
    {
        Ray r = MainCamera.ScreenPointToRay(Input.mousePosition);//创建射线
        RaycastHit HitInformation;//传递参数
        if(Physics .Raycast (r,out HitInformation, 1000,1))//检测
        {
         Cube.transform.position = new Vector3(HitInformation.point.x, HitInformation.point.y+0.5f, HitInformation.point.z);
            //让Cube坐标在鼠标的位置上(实现拖动);
            Debug.DrawLine(r.origin, HitInformation.point, Color.red);
        }
    }

基本上所要讲的就是这些 代码注释中基本都写清楚了;
就这样;
祝大家学习顺利。

  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值