淺析射線檢測 raycast 的使用!Cocos Creator 3D

哎呀?為什麼我設置了節點點擊回調沒反應呀?

淺析射線檢測 raycast 的使用!Cocos Creator 3D

記得在寫小雞拍拍的時候遇到一個問題,想要捕捉排球的點擊事件,按照 2d 的寫法,給3d 節點添加 node 事件,結果點了沒反應。代碼大概是以下的樣子。

this.node_volleyball.on(Node.EventType.TOUCH_START, () => {
console.log('不可能看見我')
}, this);

後來在論壇上找了個方法,稀裡糊塗的寫上去就完事了。

但是,最近我把版本升級到 v1.0.1 之後,發現之前的方法不管用了。還好,在最新官方文檔找到了解決方案。那 就 是 —— 射線檢測

淺析射線檢測 raycast 的使用!Cocos Creator 3D

什麼是射線檢測呢?上網查了一下,射線檢測是這樣子的。

淺析射線檢測 raycast 的使用!Cocos Creator 3D

這好像不是我想要的東西。於是,我就腦補了一下射線檢測是怎麼個邏輯。

首先,我們看到的視角是這樣子的。假設我們點擊其中屏幕中的一個位置(圖中的紅點點)。

淺析射線檢測 raycast 的使用!Cocos Creator 3D

因為這個視角是攝像機提供的,我們就把這個點點和攝像機組合一條射線。

淺析射線檢測 raycast 的使用!Cocos Creator 3D

接著,檢查這條射線穿過了那些物體,這些物體中可能就有我們點擊的對象。

也可以這麼理解,你用眼睛看著一塊區域,伸出手指。你可以看到手指頭擋住了一點視線,從你的視線做經過手指這個點畫一條射線,這個射線穿過的物體,就剛好是你想要點擊的物體。

淺析射線檢測 raycast 的使用!Cocos Creator 3D

講了大概原理(?),一起看看如何使用吧。

既然是射線檢測,當然要先創建一個射線。

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 提供了三種檢測方案,可以一起看看是如何使用的。

基於物理碰撞器的射線檢測:

我們先給需要檢測的物體添加碰撞器。

淺析射線檢測 raycast 的使用!Cocos 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 = '點了排球'
}
}
}

基於模型的射線檢測:

大致與物理模型檢測相同,使用的是模型組件。

淺析射線檢測 raycast 的使用!Cocos Creator 3D

檢測代碼如下。

//基於模型的射線檢測
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 = '點了文字';
}
}
}
淺析射線檢測 raycast 的使用!Cocos Creator 3D

一起看看最後的效果吧!

淺析射線檢測 raycast 的使用!Cocos Creator 3D


官方文檔寫的很詳細了,這裡只是稍做整理,如有錯誤,歡迎指出!希望對正在學習 Cocos Creator 3D 的朋友有點幫助。



分享到:


相關文章: