fix(android): normalize MotionEvent deviceId so a gesture cannot split across two Unity input devices - #1057
Open
AhmedYAbbas wants to merge 2 commits into
Conversation
…tor crash UnityAppController does not implement applicationDidReceiveMemoryWarning:, so forwarding the iOS memory-warning notification unconditionally throws an unrecognized-selector NSException and aborts the app the first time a warning fires while a heavy Unity scene loads. Guard the call with responds(to:).
…t across two Unity input devices
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes an Android input freeze where all 3D object interaction inside Unity goes
permanently silent after a drag, while UGUI keeps responding.
Root cause
CustomUnityPlayer.onTouchEventonly rewrotedeviceIdwhen it was exactly0:Android does not guarantee a stable
deviceIdacross a single gesture in thispath. Measured on device, one drag arrived as
DOWN(deviceId=5)followed byUP(deviceId=0)with the samedownTime. With the conditional rewrite, thepress went to Unity input device
5and the release went to device-1, sodevice
5's touch was never released.<Touchscreen>/Presslatched pressedforever and every action bound to it stopped firing, while
<Pointer>-boundUGUI was unaffected — which is why the symptom looks like "3D interaction broke
but the UI still works".
Fix
Rewrite
deviceIdunconditionally to a singleNORMALIZED_DEVICE_ID = -1, so agesture's
DOWN/MOVE/UPalways land on one Unity input device.-1is thevalue the original Flutter workaround already used and is known to be picked up
by Unity's Input System.
Also fixed: double-recycle of the incoming event
The old code called
event.recycle()on the event handed toonTouchEvent.View.onTouchEventdoes not take ownership —ViewRootImplstill owns thatevent and recycles it after dispatch. Recycling here returned it to the pool
twice, so a later
MotionEvent.obtain()could hand the same instance to twoowners. That was a real bug, though on-device measurement showed it was not
the cause of this freeze. The
recycle()call is removed.modifiedEventis intentionally left unrecycled: Unity may retain it past thecall, and recycling it here would reintroduce a genuine use-after-free. An
un-recycled
obtain()is only a missed pool return.Scope
One file, Android only:
android/.../CustomUnityPlayer.kt(+35 / -8). No publicAPI change, no Dart/iOS changes.