Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unsafe to instantiate GameManager before first scene load #3

Closed
cgaudino opened this issue Oct 5, 2023 · 3 comments · Fixed by #4
Closed

Unsafe to instantiate GameManager before first scene load #3

cgaudino opened this issue Oct 5, 2023 · 3 comments · Fixed by #4
Assignees
Labels
bug Something isn't working

Comments

@cgaudino
Copy link

cgaudino commented Oct 5, 2023

[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]

Most of the available values of the RuntimeInitializeOnLoadType enum are not safe to use to instantiate the GameManager instance in built players, including the default value of .BeforeSceneLoad shown in the example. Since GameManager derives from MonoBehaviour and must be attached to a GameObject, there must be a scene loaded for the new GameObject to be added to. Those values do work in the editor since there is already a scene loaded in the editor, but a GameObject instantiated before the first scene load in a built player will be leaked/lost after that first scene load, even if DontDestroyOnLoad is used.

The result of this is that all calls to GameManager.* throw a NullReferenceException in builds, but do work in the editor.

@Edvinas01
Copy link
Member

Hello, thank you for the bug report!

You're right on most RuntimeInitializeLoadType, only BeforeSceneLoad and AfterSceneLoad make sense. However, the issue is a bit nastier than it seems :D

The core issue seems to lie in GameManagerSettings. Since I've added a set of RuntimeInitializeOnLoadMethod, Unity goes through all of them one by one. In each of the OnBefore* methods in the GameManager class I'm trying to fetch an instance of GameManagerSettings. If you take a look inside, you'll notice that I cache it to currentSettings (I don't want to do resource lookups each time I retrieve settings). Due to the fact that the first call to RuntimeInitializeOnLoadMethod doesn't find any settings, it caches an empty settings instance which never instantiates a GameManager.

I'll try to think of something to workaround this.

@Edvinas01 Edvinas01 self-assigned this Oct 6, 2023
@Edvinas01 Edvinas01 added the bug Something isn't working label Oct 6, 2023
@Edvinas01
Copy link
Member

Edvinas01 commented Oct 6, 2023

@cgaudino I've created a PR at #4. It does limit the package a bit in terms of where you can put the settings file, though during my testing it seems to have resolved the issue. I will merge this in later today in about 4 hours and deploy if there are no objections.

@Edvinas01
Copy link
Member

Edvinas01 commented Oct 6, 2023

Found and implemented better solution using profiles, see https://github.com/chark/game-management/releases/tag/v0.0.2:

  • When the editor loads, a GameManagerSettings asset will be created automatically.
  • This asset will then be added to preloaded assets, duplicate check is also added.
  • Then during runtime Runtime.FindObjectsOfTypeAll<> can be used for the settings asset, as it is always preloaded. This way the settings asset can be moved and is not bound to a specific location.
  • In the case of missing Game Manager Prefab on a profile, a default Game Manager instance will be supplied to avoid NREs.
  • If all else fails, I added a more descriptive error as well.

Let me know if I created more bugs 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants