Skip to content

Use the 2D collision matrix for NetworkCollider2D when Layers is nothing - #1100

Open
jimdroberts wants to merge 1 commit into
FirstGearGames:mainfrom
jimdroberts:fix/networkcollider2d-layer-fallback
Open

jimdroberts wants to merge 1 commit into
FirstGearGames:mainfrom
jimdroberts:fix/networkcollider2d-layer-fallback

Conversation

@jimdroberts

Copy link
Copy Markdown
Contributor

Problem

When Layers is nothing, NetworkTrigger2D (and NetworkCollision2D, see #1074) derive their query mask from the 3D collision matrix (Project Settings > Physics). They should use the 2D one (Physics 2D). Their queries go through PhysicsScene2D, so the 2D matrix is the one the user configured for these colliders. In a typical 2D project the 3D matrix is left at its default of every layer colliding with every other layer. A 2D trigger left at nothing then reports objects on every layer and ignores the 2D matrix completely. When both matrices are edited and differ, the trigger also misses layers that the 2D matrix enables.

Cause

  • Runtime/Generated/Component/Prediction/NetworkColliderBase.cs L138-152 on main: when Layers is nothing, TryPrepareColliderCheck uses GameKit.Dependencies.Utilities.Layers.GetInteractableLayersValue(gameObject.layer). The base class has no notion of 2D or 3D. The only split is the subclass, NetworkCollider or NetworkCollider2D, so the same lookup serves both.
  • Runtime/Plugins/GameKit/Dependencies/Utilities/Layers.cs L19-38 builds that lookup from Physics.GetIgnoreLayerCollision, which reads the 3D matrix only.
  • NetworkCollider2D.cs L152-157, L270 and L282 pass the resulting mask to PhysicsScene2D.OverlapCollider/OverlapCircle/OverlapBox.

Fix

  • Layers.GetInteractableLayersValue2D(int layer): the same table and the same lazy initialization as the 3D method, built from Physics2D.GetIgnoreLayerCollision.
  • NetworkColliderBase gets protected virtual int GetInteractableLayersValue(int layer). It returns the existing 3D lookup and is called where the lookup was called before. NetworkCollider2D overrides it to return the 2D lookup.

NetworkCollider and anything else that derives from NetworkColliderBase keep the 3D lookup. A user-defined 2D subclass of NetworkColliderBase can now override the method as well.

Not changed: both lookups are built once per domain and cached in a static. A later Physics.IgnoreLayerCollision / Physics2D.IgnoreLayerCollision call at runtime is therefore never seen by a collider that relies on the fallback. With domain reload disabled, the same is true of matrix edits made between play sessions. That behavior predates this PR and also applies to the 3D path, so I left it out. Fixing it means either rebuilding per query (32×32 native calls) or adding an invalidation API. Callers that change the matrix at runtime can set Layers explicitly.

Merges. This branch merges cleanly (git merge-tree --write-tree) with #1074 (restores NetworkCollision2D.cs), #1085 (NetworkCollider/2D per-tick bookkeeping, which rewrites the CheckColliders body) and #1093 (GetLayers/SetLayers on NetworkColliderBase), each on its own and with all three together. The combined tree compiles with no new diagnostics. The edits sit outside the hunks those PRs change: the override goes after OnDestroy in NetworkCollider2D, and the virtual goes after TryPrepareColliderCheck in the base. The PRs do not depend on each other. With #1093, SetLayers(0) resets the layer cache, and the next check goes through the new virtual and picks the right matrix.

Evidence

Compiled against Unity 6000.4 with no new errors or warnings, both on its own and merged with #1074, #1085 and #1093. Not run in play mode.

Behavior change

  • NetworkCollider2D components whose Layers is nothing now use the 2D collision matrix. Projects whose two matrices agree see no difference.
  • Explicit Layers values and all 3D components are unchanged.
  • New API: Layers.GetInteractableLayersValue2D and the protected virtual NetworkColliderBase.GetInteractableLayersValue.

With Layers left at nothing, NetworkColliderBase derived the query mask from
Layers.GetInteractableLayersValue, which reads Physics.GetIgnoreLayerCollision,
the 3D matrix. NetworkTrigger2D and NetworkCollision2D query Physics2D, so they
used the wrong matrix and missed or added layers whenever the two matrices
differ. Add Layers.GetInteractableLayersValue2D, built from
Physics2D.GetIgnoreLayerCollision, and a protected virtual
GetInteractableLayersValue on NetworkColliderBase that NetworkCollider2D
overrides to use it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant