3D-点击事件的实现(射线与碰撞检测)

1、背景

  因为点击星球上的建筑后,需要有相应的跳转操作,所以需要我们做出点击的效果。

2、原理:射线与碰撞检测(接口讲解:https://docs.cocos.com/creator3d/manual/zh/physics/physics-raycast.html?h=%E5%B0%84%E7%BA%BF)

3、功能实现

  首先要开启3D物理引擎

  

 

 

  a、引擎设置层面

    1.首先创建一个3d柱体(cocos的自带柱体,会自动绑定一个 模型组件 MeshRenderer,这个模型组件会自带一个默认 材质)

      canvas下,右键,创建一个立方体,如图:

      

 

 

       

      点击创建的立方体,查看右侧 属性检查器 

      

 

 

 

    2.创建一个透明材质,然后将默认材质更换成透明材质(或者可以尝试不用绑定材质,直接让材质为空,也能实现透明效果)

      asset目录下,右键创建材质

      

 

      

 

       点击创建的材质,按照下图,选择对应的配置。

      

 

 

       然后将这个材质替换到刚才创建的立方体材质上,以实现透明。

    3.绑定 刚体组件,用于射线碰撞,用来出发事件。如下图:

      

 

 

 

  b、代码层面

      //主摄像机的绑定

        @property(Camera)
        mainCamera: Camera = null!;
    //产生移动距离后,物理点击判断失效
        private runH: number = 0;

    首先绑定手指抬起事件

    systemEvent.on(SystemEventType.TOUCH_END, this.onTouchEnd, this);

    //创建射线

    private _ray: geometry.Ray = new geometry.Ray();

    //手指抬起事件触发后

 private onTouchEnd(touch: any, event: EventTouch): void {
        let sf = this;
        if (sf.runH >= 10) {
            sf.runH = 0
            return;
        }
        sf.runH = 0;
        let location = event.getLocation();
        sf._ray = sf.mainCamera.screenPointToRay(location.x, location.y);
        //基于物理碰撞器的物理检测
        //当点击node_touch_1时,控制台打印:点击了外链按钮1
        if (PhysicsSystem.instance.raycast(sf._ray)) {
            const r = PhysicsSystem.instance.raycastResults;
            for (let index = 0; index < r.length; index++) {
                const element = r[index];
                sf.goIn(element.collider.node.name);
                break;
            }
        }
    }
 private goIn(str: string): void {
 根据 str 的不同判断做出相应的逻辑。
}
 
3.4版本后的写法
  //主摄像机的绑定

    @property(Camera)
    mainCamera: Camera = null!;
    //产生移动距离后,物理点击判断失效
    private runH: number = 0;
    //首先绑定手指抬起事件
    start(): void {
        input.on(Input.EventType.TOUCH_END, this.onTouchEnd, this);
    }
    //创建射线
    private _ray: geometry.Ray = new geometry.Ray();
    //手指抬起事件触发后
    private onTouchEnd(event: EventTouch): void {
        let sf = this;
        if (sf.runH >= 10) {
            sf.runH = 0
            return;
        }
        sf.runH = 0;
        let location = event.getLocation();
        sf._ray = sf.mainCamera.screenPointToRay(location.x, location.y);
        //基于物理碰撞器的物理检测
        //当点击node_touch_1时,控制台打印:点击了外链按钮1
        if (PhysicsSystem.instance.raycast(sf._ray)) {
            const r = PhysicsSystem.instance.raycastResults;
            for (let index = 0; index < r.length; index++) {
                const element = r[index];
                sf.goIn(element.collider.node.name);
                break;
            }
        }
    }
    private goIn(str: string): void {
        //根据 str 的不同判断做出相应的逻辑。
    }

  

posted @ 2022-03-15 16:53  jiaxin2015  阅读(533)  评论(0)    收藏  举报