Skip to content

Inject dependencies into dynamically instantiated avatar buttons#507

Open
Shombith03 wants to merge 5 commits into
bleeding-edgefrom
claude/fix-profile-avatar-selection-FlM5n
Open

Inject dependencies into dynamically instantiated avatar buttons#507
Shombith03 wants to merge 5 commits into
bleeding-edgefrom
claude/fix-profile-avatar-selection-FlM5n

Conversation

@Shombith03

Copy link
Copy Markdown
Contributor

Summary

Added dependency injection support for dynamically instantiated profile icon select buttons. This ensures that any dependencies required by the button prefab are properly resolved through the Reflex container.

Key Changes

  • Added Reflex.Core and Reflex.Injectors using statements
  • Injected the Reflex Container into ProfileIconSelectView
  • Added recursive dependency injection call when instantiating avatar icon buttons in BuildAvatarGrid()

Implementation Details

When avatar buttons are instantiated dynamically in the grid, they now have their dependencies automatically resolved via GameObjectInjector.InjectRecursive(). This ensures that any injected fields or constructor dependencies on the button prefab and its children are properly populated from the container, maintaining consistency with the rest of the dependency injection setup.

https://claude.ai/code/session_011jNgqq76vXFETJoc2esCEV

claude added 5 commits April 30, 2026 19:00
ProfileIconSelectButton.OnClick threw NullReferenceException because
audioSystem was never injected — buttons are Instantiated at runtime by
ProfileIconSelectView.BuildAvatarGrid, and Reflex does not auto-inject
runtime-spawned objects. Inject the container into the view and run
GameObjectInjector.InjectRecursive on each instantiated button, matching
the pattern used by PlayerSpawner / VesselSpawner / MenuMiniGameHUD.
…viewView

- ProfileImage was subscribed to legacy PlayerDataController.OnProfileLoaded /
  OnPlayerAvatarUpdated, which the UGS path (PlayerDataService.SetAvatarId)
  never raises — so the home-screen avatar stayed stale after a profile
  change. Switch to [Inject] PlayerDataService and listen to
  OnProfileChanged, the same channel the rest of the app uses.

- Remove the HangarOverviewView legacy stub (a no-op View subclass kept
  only so the legacy fallback in HangarScreen had something to point at)
  and drop the matching field + usages from HangarScreen. The active
  flow is gridPanel + detailPanel (HangarVesselDetailView); the
  inspector "Overview View" slot was a dead reference that confused
  scene wiring.
…anged

ProfileModal owns the home-screen profileIconImage / profileNameLabel
(scene refs at Menu_Main fileID 653179561 + 231317289). It was wired
only to the legacy PlayerDataController.OnProfileLoaded event, which
the modern UGS write path never raises — so picking a new icon in
ProfileIconSelectView updated cloud save but the home-screen avatar
stayed on the previous sprite until a full app reload.

Subscribe to PlayerDataService.OnProfileChanged in Start and unsubscribe
in OnDestroy. On each event update profileNameLabel + the input field
(unless focused) and re-resolve the sprite from the SO_ProfileIconList,
matching the existing RefreshAvatarSprite logic but keyed off
PlayerProfileData.avatarId instead of the legacy ProfileIconId.

The earlier ProfileImage.cs change is dead code — that script isn't
referenced anywhere in the scene — but keep it converted to the modern
service so it's correct if anything starts using it.
HangarLink was rendering as inactive at runtime even though the scene
asset has m_IsActive: 1 and nothing in code calls SetActive(false) on
it. Source of the toggle isn't traceable from a clean checkout —
likely a local editor edit or a prefab override on a downstream branch.

Walk NavBar.children once in ScreenSwitcher.Start and SetActive(true)
on any that come up disabled. This is a belt-and-suspenders guard, not
a fix for the root cause; if a script is genuinely disabling a link
later in the frame this won't help, but for a stale inspector toggle
it will.
Avatar refresh:
ProfileModal's MonoBehaviour starts disabled in Menu_Main.unity (the
PrefabInstance modification block sets m_Enabled: 0 on script GUID
d03b222767521fb46b35a956ee450a8b). Unity skips Start() on disabled
components, so the OnProfileChanged subscription added in the previous
commit never wired up — picking a new icon updated UGS but the
home-screen Image stayed stale. Awake DOES run on disabled components
of active GameObjects, and PlayerDataService is a Bootstrap-scene
singleton (DontDestroyOnLoad), so its Instance is set well before
Menu_Main loads. Subscribe in Awake via PlayerDataService.Instance
with an idempotent guard, also retry from Start() in case the modal
gets enabled later.

Navbar re-enable:
The earlier Start-only EnsureNavBarChildrenActive guard didn't hold —
something is deactivating HangarLink between ScreenSwitcher.Start and
the first navigation, so by the time the user sees the menu it's gone
again. Call EnsureNavBarChildrenActive at the top of every
UpdateNavBar (i.e. on every screen switch) and log a warning whenever
we have to re-enable a child, so the next play session shows in the
console which frame the toggle is happening on. Still belt-and-
suspenders — root cause is unknown — but at least the link won't stay
hidden.
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.

2 participants