Inject dependencies into dynamically instantiated avatar buttons#507
Open
Shombith03 wants to merge 5 commits into
Open
Inject dependencies into dynamically instantiated avatar buttons#507Shombith03 wants to merge 5 commits into
Shombith03 wants to merge 5 commits into
Conversation
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.
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.
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
Reflex.CoreandReflex.Injectorsusing statementsContainerintoProfileIconSelectViewBuildAvatarGrid()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