浅析射线检测 raycast 的使用 !Cocos Creator 3D !
哎呀?为什么我设置了节点点击回调没反应呀?

记得在写小鸡拍拍的时候遇到一个问题,想要捕捉排球的点击事件,按照 2d 的写法,给3d 节点添加 node 事件,结果点了没反应。代码大概是以下的样子。
this.node_volleyball.on(Node.EventType.TOUCH_START, () => {
console.log('不可能看见我')
}, this);
后来在论坛上找了个方法,稀里糊涂的写上去就完事了。
但是,最近我把版本升级到 v1.0.1 之后,发现之前的方法不管用了。还好,在最新官方文档找到了解决方案。那 就 是 —— 射线检测 。

什么是射线检测呢?上网查了一下,射线检测是这样子的。

这好像不是我想要的东西。于是,我就脑补了一下射线检测是怎么个逻辑。
首先,我们看到的视角是这样子的。假设我们点击其中屏幕中的一个位置(图中的红点点)。

因为这个视角是摄像机提供的,我们就把这个点点和摄像机组合一条射线。

接着,检查这条射线穿过了那些物体,这些物体中可能就有我们点击的对象。
也可以这么理解,你用眼睛看着一块区域,伸出手指。你可以看到手指头挡住了一点视线,从你的视线做经过手指这个点画一条射线,这个射线穿过的物体,就刚好是你想要点击的物体。

讲了大概原理(?),一起看看如何使用吧。
既然是射线检测,当然要先创建一个射线。
private _ray: geometry.ray = new geometry.ray();
触摸检测的就用全局系统事件。
systemEvent.on(SystemEventType.TOUCH_START, this.onTouchStart, this);
//onTouchStart(touch: Touch, event: EventTouch)
开始画射线,就要用到摄像机嘛!记得上面说的是由点击的点和摄像机决定这条射线的吧。
this.camera_3d.screenPointToRay(touch._point.x, touch._point.y, this._ray);
接下来就是检测这条线穿过了哪些物体啦。
creator 3d 提供了三种检测方案,可以一起看看是如何使用的。
基于物理碰撞器的射线检测:
我们先给需要检测的物体添加碰撞器。

在代码中调用物理碰撞器检测方法就可以啦。
//基于物理碰撞器的射线检测
if (PhysicsSystem.instance.raycast(this._ray)) {
const r = PhysicsSystem.instance.raycastResults;
for (let i = 0; i < r.length; i++) {
const item = r[i];
if (item.collider.node.uuid == this.node_volleyball.uuid) {
this.label_info.string = '点了排球'
}
}
}
基于模型的射线检测:
大致与物理模型检测相同,使用的是模型组件。

检测代码如下。
//基于模型的射线检测
const rs = director.getScene().renderScene;
if (rs.raycastSingleModel(this._ray, this.model_basketball.model)) {
const r = rs.rayResultSingleModel;
for (let i = 0; i < r.length; i++) {
const item = r[i];
if (item.node.uuid == this.model_basketball.node.uuid) {
this.label_info.string = '点了篮球'
}
}
}
基于 UITransform 组件的射线检测:
因为 canvas 有自己的相机实体,我们需要切换摄像机,代码如下。
//基于 UITransform 组件的射线检测
const uiCamera = this.canvas_2d.camera;
uiCamera.screenPointToRay(this._ray, touch._point.x, touch._point.y);
if (rs.raycastAllCanvas(this._ray)) {
const result = rs.rayResultCanvas;
for (let i = result.length; i--;) {
const item = result[i];
if (item.node.uuid == this.label_info.node.uuid) {
this.label_info.string = '点了文字';
}
}
}

一起看看最后的效果吧!

官方文档写的很详细了,这里只是稍做整理,如有错误,欢迎指出!希望对正在学习 Cocos Creator 3D 的朋友有点帮助。
浅析射线检测 raycast 的使用 !Cocos Creator 3D !的更多相关文章
- 反复横跳的瞄准线!从向量计算说起!基于射线检测的实现!Cocos Creator!
最近有小伙伴问我瞄准线遇到各种形状该怎么处理?如何实现反复横跳的瞄准线?最近刚好在<Cocos Creator游戏开发实战>中看到物理系统有一个射线检测,于是,基于这个射线检测,写了一个反 ...
- cocos creator 3D | 蚂蚁庄园运动会星星球
上一篇文章写了一个简易版的蚂蚁庄园登山赛,有小伙伴留言说想要看星星球的,那么就写起来吧! 效果预览 配置环境 cocos creator 3d 1.0.0 小球点击 3d里节点无法用 cc.Node. ...
- cocos creator 3D | 拇指投篮 | 3D项目入门实战
你的命中率是多少呢?文章底部试玩! 效果预览 配置环境: Cocos Creator 3D v1.0.1 玩法说明: 触摸屏幕,向上滑动投篮!注意篮板是会移动的哦!看看你的命中率是多少! 实现原理 为 ...
- cocos creator 3D | 拇指射箭
拇指射箭!你能射中靶心么? 效果预览 配置环境: cocos creator 3d v1.0.0 玩法介绍: 长按屏幕,拖动瞄准,放手发射.风向.重力和距离影响最终结果!越靠近中心得分越高!最高分10 ...
- Unity3D_(API)射线检测Raycast()
Unity射线检测官方文档: 传送门 一.检测前方是否有游戏物体(射线无限长度) 二.检测前方是否有游戏物体(射线长度为1m) 三.检测前方游戏物体碰撞信息(射线无限长度): 四.指定检测碰撞Tag层 ...
- Cocos Creator 3D 打砖块图文教程(一)
在线体验链接: http://example.creator-star.cn/block3d/ 上面图中是打砖块游戏的主要 3D 节点元素,Shawn 这两天在学习 Unity 与 Creator3D ...
- Cocos Creator 3D 打砖块教程(二) | 子弹发射与摄像机平滑移动
在线体验链接: http://example.creator-star.cn/block3d/ 前面一篇文章,我们讲了[打砖块]游戏中的3D物体的场景布局.材质资源.物理刚体与碰撞组件,接下来本篇文章 ...
- Unity - Raycast 射线检测
本文简要分析了Unity中射线检测的基本原理及用法,包括: Ray 射线 RaycastHit 光线投射碰撞信息 Raycast 光线投射 SphereCast 球体投射 OverlapSphere ...
- 【Unity3D】枪战游戏—发射子弹、射线检测
一.子弹的碰撞检测: 因为子弹的移动速度非常的快,那么如果为子弹添加一个collider,就有可能检测不到了. 因为collider是每一帧在执行,第一帧子弹可能在100米处,那么下一帧就在900米处 ...
随机推荐
- sizeof运算符、字节对齐考点(面宝P50)
记住几句话: 结构体的长度一定是最长的数据元素类型的整数倍: 某数据元素的起始地址能被该类型所占的字节数整除: 静态变量是存放在全局数据区,而sizeof计算栈中分配的大小,不包括static变量: ...
- vuex , 简单入(liao)门(jie)
vuex什么 ? 官方的说法就是 vuex是专门为vue.js应用程序开发的 状态管理模式 .并采用集中式存储 , 管理应用的所有组件的状态 ,并以相同的规则保证状态以一种可预估的方式发生变化. 自己 ...
- Rust学习-阶段1学习总结
学习Rust已经两周了,基本上是断断续续的在学,或者是在上下班坐公交时,或者是在ODC没事做时.现在已经学习了Rust程序设计语言的前5章,是时候做一个总结了.关于数据类型或者if else这种内容我 ...
- Harbor ($docker login) Error saving credentials
$ sudo apt-get install $ sudo apt-get install gnupg2 pass 问题解决!
- Oracle 表锁定
--锁表查询SQL SELECT object_name, machine, s.sid, s.serial# FROM gv$locked_object l, dba_objects o, gv$s ...
- 插入排序,选择排序,冒泡排序等常用排序算法(java实现)
package org.webdriver.autotest.Study; import java.util.*; public class sort_examp{ public static voi ...
- CF603E Pastoral Oddities 优先队列+结论+LCT维护生成树
首先,一个神奇的结论:一个合法的方案存在的条件是每一个联通块的节点数都是偶数个的. 这个可以用数学归纳法简单证一证. 证出这个后,我们只需动态加入每一个边,并查看一下有哪些边能够被删除(删掉后联通块依 ...
- touch:创建文件及修改文件时间戳
touch 命令不光可以用来创建文件(当指定操作文件不存在时,该命令会在当前位置建立一个空文件),此命令更重要的功能是修改文件的时间参数(但当文件存在时,会修改此文件的时间参数). Linux 系统中 ...
- Python3学习笔记(十六):随机数模块random
一.random模块 1.random.random(): 返回0-1之间的随机浮点数 import random print(random.random()) 0.9348690085059901 ...
- JS框架_(Vue.js)带有星期日期的数字时钟
百度云盘 传送门 密码:tv1v 数字时钟效果: <!doctype html> <html> <head> <meta charset="utf- ...