安卓三指下滑截图后没有收到对应的TOUCH_END

引擎版本3.7.1 手机型号redmi k40 pro 微信版本8.0.32

如题,三指下滑可以截图,但是截图后回到游戏看日志,发现没有收到这三个触点的TOUCH_END消息

引擎组的大佬来看看嘛,同样的代码,在3.7.1就收不到TOUCH_CANCEL和TOUCH_END
但是在2.4.8就可以

可以在项目设置里看一下 Macro Config(引擎宏配置)中 ENABLE_MULTI_TOUCH 是否勾选了?

1赞

当然勾选了,我们游戏有拖动地图和地图缩放的功能

三指下滑截图的时候,收到了3个TOUCH_START,但是截图回到游戏后,没有收到TOUCH_CANCEL和TOUCH_END,打印引擎里的触点数量也是3,这个时候三个手指依次接触屏幕并滑动(避免触发截图),然后依次放开,发现手指触摸的时候再次收到3个TOUCH_START,依次松开的时候收到了3个TOUCH_END,打印引擎里的触点数量也变成了0,一切就正常了,直到下次触发三指下滑截图

不仅是截图的时候不行,如果一个手指按住屏幕,来了电话,挂掉电话回到游戏,依然没有收到TOUCH_END,打印引擎触点数量也保持是1,同样的再次触摸后松开,就会收到TOUCH_START后再收到TOUCH_END,引擎的触点数量也就回到0了

感觉是切出游戏的时候,引擎的触点状态错乱了,再次触摸的时候这个触点被重新使用,状态也就正常了

忘记说了,这些问题都是微信小游戏里出现的,浏览器预览的时候没有问题

蹲一个官方

有了新的发现,在三只下滑截图的时候,wx.onTouchStart触发了3次,截图成功后wx.onTouchCancel触发了一次,其中touches有2个,changedTouches有一个

再次点击屏幕的时候,发现 wx.onTouchStart触发了一次,但是touches变成了1,也就是有两个触点在没有通知的情况下自己消失了

由于是系统层事件中断,目前微信小游戏上也没有类似接口回调能触发,暂时没办法处理。

我已经有解决方案了,这个问题是微信自己悄悄销毁了两个触点而没有触发回调来告诉引擎,解决办法就是发现微信销毁了触点时,引擎自己也要销毁对应的触点

修改1

找到engine/pal/input/minigame/touch-input.ts 修改TouchInputSource的_createCallback函数,在匿名函数的最后加入剔除无效触点的代码

            const err_tids: Touch[] = [];
            const this_tids:number[] = []
            event.touches.forEach((t)=>{
                this_tids.push(t.identifier)
            })
            touchManager.get_all_tid().forEach((tid)=>{
                if(this_tids.indexOf(tid) < 0){
                    const touch = touchManager.getTouch(tid, 0, 0);
                    if (touch) {
                        touchManager.releaseTouch(tid);
                        err_tids.push(touch);
                    }
                }
            })
            if (err_tids.length > 0) {
                const eventTouch = new EventTouch(err_tids, false, InputEventType.TOUCH_CANCEL,
                    macro.ENABLE_MULTI_TOUCH ? touchManager.getAllTouches() : err_tids);
                this._eventTarget.emit(InputEventType.TOUCH_CANCEL, eventTouch);
            }

修改2

找到pal/input/touch-manager.ts,给TouchManager类添加方法

    public get_all_tid (): number[] {
        const l: number[] = [];
        this._touchMap.forEach((touch) => {
            touch && l.push(touch.getID());
        });
        return l;
    }

注意,这个修改只测试了引擎版本3.7.1在微信小游戏上可以完美运行

1赞