Skip to content

Fix: Prevent FriendsListToggle null reference after scene changes#1297

Open
JessTello wants to merge 8 commits into
developmentfrom
bug/eosu-1391-friends-list-toggle-null-ref
Open

Fix: Prevent FriendsListToggle null reference after scene changes#1297
JessTello wants to merge 8 commits into
developmentfrom
bug/eosu-1391-friends-list-toggle-null-ref

Conversation

@JessTello

Copy link
Copy Markdown
Contributor
  • Clear static Friends tab UI callbacks on scene unload to avoid retaining old listeners.
  • Safely invoke Friends tab expand/collapse callbacks, skipping destroyed Unity targets.
  • Guard optional UIFriendInteractionSource usage to prevent calls into missing or destroyed references during UI refresh.

- Clear static Friends tab UI callbacks on scene unload to avoid retaining old listeners.
- Safely invoke Friends tab expand/collapse callbacks, skipping destroyed Unity targets.
- Guard optional UIFriendInteractionSource usage to prevent calls into missing or destroyed references during UI refresh.
@JessTello
JessTello requested review from a team and Pong-Epic June 11, 2026 21:35
Comment thread Assets/Scripts/StandardSamples/UI/Lobbies/UIActions.cs Outdated
Comment thread Assets/Scripts/StandardSamples/UI/Lobbies/UIActions.cs Outdated
Comment thread Assets/Scripts/StandardSamples/UI/Lobbies/UIActions.cs Outdated
Comment thread Assets/Scripts/StandardSamples/UI/Lobbies/UIActions.cs Outdated
Comment thread Assets/Scripts/StandardSamples/UI/Lobbies/UIActions.cs Outdated
Comment thread Assets/Scripts/StandardSamples/UI/Lobbies/UIActions.cs Outdated
Comment thread Assets/Scripts/StandardSamples/UI/Lobbies/UIActions.cs Outdated

@ricardoamores-epic ricardoamores-epic left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

matt-clarke
matt-clarke previously approved these changes Jul 22, 2026

foreach (Action handler in action.GetInvocationList())
{
if (handler.Target is UnityEngine.Object target && target == null)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we get a comment here on why is this needed? Why a handler could ever be null?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the actually null check fix, the handler.Target became null because the GameObject have been destroyed when scene change (from "Lobbies" to other), and the action may still referencing that destroyed object here so NRE before the fix

and here cannot just directly if (handle.Target == null) because handle.Target just plain System.object and have to become a UnityEngine.Object to check the destroyed object as null here.

@Pong-Epic Pong-Epic Jul 24, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So maybe there a bit context :

This fix is likely null check guard before Invoke a function, and remove the reference point found it became null (got destroyed elsewhere), that mean the subscribe/unsubscribe to this Action isn't clean up completed in some flow.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So there's two options here I think:

  1. We remove this check and wherever we find that code isn't unsubscribing properly we fix that
  2. We add a comment to the code saying why this check exists (as Pong says due to the way that Unity marks GameObjects for destruction)

I'm leaning towards option 1, it leads to better code because you're aware of when an event hasn't been unsubscribed from properly

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that doable, I would check the unsubscribing logic where is missing as well check how bad is it, I remember I may noted when report to Apex before.

@Pong-Epic

Copy link
Copy Markdown

Finially fixed the add/remove listener in correct pair in OnEnable/OnDisable

Comment on lines +100 to +104
// We add the listener to the Action first in OnEnable. Then, if StartsHidden = true, it will be set to Disabled to remove the listener.
UIActions.OnCollapseFriendsTab += EnableInterferingUIForFriendsTab;
UIActions.OnExpandFriendsTab += DisableInterferingUIForFriendsTab;

base.OnEnable();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work? Looking at the base class it looks like it will work when it's hidden at the start, but I didn't look into when it's shown later.

Suggested change
// We add the listener to the Action first in OnEnable. Then, if StartsHidden = true, it will be set to Disabled to remove the listener.
UIActions.OnCollapseFriendsTab += EnableInterferingUIForFriendsTab;
UIActions.OnExpandFriendsTab += DisableInterferingUIForFriendsTab;
base.OnEnable();
base.OnEnable();
if (!Hidden)
{
UIActions.OnCollapseFriendsTab += EnableInterferingUIForFriendsTab;
UIActions.OnExpandFriendsTab += DisableInterferingUIForFriendsTab;
}

@Pong-Epic Pong-Epic Jul 24, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checking Hidden not work when It's shown, the flag update after SetActive(true), so I changed to the actually Unity activeSelf for that gameObject seem suitable for this case

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.

4 participants