#if SDK_WECHAT_WASM using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using WeChatWASM; using Touch = UnityEngine.Touch; class TouchData { public Touch touch; public long timeStamp; } /** * 由于Unity WebGL发布的多点触控存在问题, 导致在微信中多点触控存在粘连的情况 * 所以需要使用WX的触控接口重新覆盖Unity的BaseInput关于触控方面的接口 * 通过设置StandaloneInputModule.inputOverride的方式来实现 */ [RequireComponent(typeof(StandaloneInputModule))] public class WechatTouchInputOverride : BaseInput { private bool _isInitWechatSDK; private readonly List _touches = new List(); private StandaloneInputModule _standaloneInputModule = null; protected override void Awake() { base.Awake(); _standaloneInputModule = GetComponent(); } protected override void OnEnable() { base.OnEnable(); InitWechatTouchEvents(); if (_standaloneInputModule) { _standaloneInputModule.inputOverride = this; } } protected override void OnDisable() { base.OnDisable(); UnregisterWechatTouchEvents(); if (_standaloneInputModule) { _standaloneInputModule.inputOverride = null; } } private void InitWechatTouchEvents() { if (!_isInitWechatSDK) { WX.InitSDK((code) => { _isInitWechatSDK = true; Debug.LogFormat("WX.InitSDK:{0}", code); RegisterWechatTouchEvents(); }); } else { RegisterWechatTouchEvents(); } } private void RegisterWechatTouchEvents() { WX.OnTouchStart(OnWxTouchStart); WX.OnTouchMove(OnWxTouchMove); WX.OnTouchEnd(OnWxTouchEnd); } private void UnregisterWechatTouchEvents() { WX.OffTouchStart(OnWxTouchStart); WX.OffTouchMove(OnWxTouchMove); WX.OffTouchEnd(OnWxTouchEnd); } private void OnWxTouchStart(OnTouchStartCallbackResult touchEvent) { foreach (var wxTouch in touchEvent.changedTouches) { var data = FindOrCreateTouchData(wxTouch.identifier); data.touch.phase = TouchPhase.Began; data.touch.position = new Vector2(wxTouch.clientX, wxTouch.clientY); data.touch.rawPosition = data.touch.position; data.timeStamp = touchEvent.timeStamp; // Debug.Log($"OnWxTouchStart:{wxTouch.identifier}, {data.touch.phase}"); } } private void OnWxTouchMove(OnTouchStartCallbackResult touchEvent) { foreach (var wxTouch in touchEvent.changedTouches) { var data = FindOrCreateTouchData(wxTouch.identifier); UpdateTouchData(data, new Vector2(wxTouch.clientX, wxTouch.clientY), touchEvent.timeStamp, TouchPhase.Moved); } } private void OnWxTouchEnd(OnTouchStartCallbackResult touchEvent) { foreach (var wxTouch in touchEvent.changedTouches) { var data = FindOrCreateTouchData(wxTouch.identifier); UpdateTouchData(data, new Vector2(wxTouch.clientX, wxTouch.clientY), touchEvent.timeStamp, TouchPhase.Ended); } } private void Update() { RemoveEndedTouches(); } private void RemoveEndedTouches() { if (_touches.Count > 0) { _touches.RemoveAll(touchData => { var touch = touchData.touch; return (touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled); }); } } private TouchData FindOrCreateTouchData(long identifier) { foreach (var touchData in _touches) { var touch = touchData.touch; if (touch.fingerId == identifier) { return touchData; } } var data = new TouchData(); data.touch.pressure = 1.0f; data.touch.maximumPossiblePressure = 1.0f; data.touch.type = TouchType.Direct; data.touch.tapCount = 1; data.touch.fingerId = (int)identifier; data.touch.radius = 0; data.touch.radiusVariance = 0; data.touch.altitudeAngle = 0; data.touch.azimuthAngle = 0; data.touch.deltaTime = 0; _touches.Add(data); return data; } private static void UpdateTouchData(TouchData data, Vector2 pos, long timeStamp, TouchPhase phase) { data.touch.phase = phase; data.touch.deltaPosition = pos - data.touch.position; data.touch.position = pos; data.touch.deltaTime = (timeStamp - data.timeStamp) / 1000000.0f; } public override bool touchSupported { get { return true; } } public override int touchCount { get { return _touches.Count; } } public override Touch GetTouch(int index) { return _touches[index].touch; } } #endif