Repository navigation
Update NetworkCollider/2D entered state once per tick, not once per c… - #1085
Open
jimdroberts wants to merge 1 commit into
Open
jimdroberts wants to merge 1 commit into
jimdroberts wants to merge 1 commit into
Conversation
…ollider The enter/stay/exit bookkeeping ran inside foreach (_colliders) while every iteration shared one per-tick HashSet. With more than one matching collider the set was returned to CollectionCaches while still in use, and twice; hits on later colliders got no callbacks, and hits on the first got OnEnter every tick and never OnExit. Close the loop after the overlap queries and run the bookkeeping once per tick on the union of hits. Applies to NetworkCollider and NetworkCollider2D.
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.
Problem
When a
NetworkTrigger/NetworkCollision(or the 2D versions) is on an object with more than one enabled collider of the matching kind, for example a trigger made of two box colliders, callbacks go wrong:OnEnter,OnStayorOnExit.OnEnterevery tick. It never getsOnStay, and it never getsOnExitwhen it leaves.HashSetis pushed intoCollectionCaches<Collider>twice per tick while still in use. Two laterRetrieveHashSet()callers anywhere in the process can then receive the same instance.Objects with a single matching collider are not affected. We found this in a production MMO project.
Cause
Runtime/Generated/Component/Prediction/NetworkCollider.cson main,CheckCollidersL143-250 (NetworkCollider2D.csL141-248 is identical). The enter/stay/exit bookkeeping sits insideforeach (Collider col in _colliders), butcurrentis a single set shared by the whole loop. On the second matching collider:current._enteredColliders.TryGetValue(localTick)now findscurrentitself, which the first iteration stored. It is passed toCollectionCaches.Store, which clears it and pushes it onto the cache, and then removed.currentis now empty, so theelsebranch stores it into the cache a second time.lastTickentry, so the next tick always sees "no colliders last tick" and invokesOnEnter.Fix
Close the
foreachafter the overlap queries, so thatcurrentholds the union of all colliders' hits. Then run the existing bookkeeping block once per tick. No logic inside the block changed. The diff is mostly re-indentation (view with whitespace ignored: +1/-1 lines per file).This does not touch
NetworkCollision2D.cs, so it does not conflict with #1074. It builds on thelastTickkey fix from #1041.Evidence
repro.pyis a line-by-line model ofCheckCollidersand ofCollectionCaches.Store, which clears the set and pushes it onto aStack. It runs an object with colliders A and B for five ticks. Y overlaps both colliders and X overlaps only B, for ticks 1-3; both leave at tick 4:The client-side (non-server) run produces the same sequences. The model is not Unity; that the Unity code behaves the same way is verified by reading. Compiled against Unity 6000.4 with no new errors or warnings.
Behavior change
isTrigger.OnExitfires for whatever was entered on the previous tick. Previously the tick was skipped and those colliders never receivedOnExit.