zer0Kerbal / PreciseManeuver

Precise Maneuver plugin provides a window for more precise maneuver node editing. For Kerbal Space Program (KSP).
https://forum.kerbalspaceprogram.com/index.php?/topic/207261-*/
BSD 2-Clause "Simplified" License
8 stars 3 forks source link

[Bug 🐞]: UnityException on load #36

Closed Rodg88 closed 1 year ago

Rodg88 commented 2 years ago

Brief description of your issue

Ive set up a instance of KSP in debug mode to use the unity profiler, and on loading it gives this error:

UnityException: LoadAsset_Internal is not allowed to be called from a MonoBehaviour constructor (or instance field initializer), call it in Awake or Start instead. Called from MonoBehaviour 'PreciseManeuver' on game object 'PreciseManeuver'.
See "Script Serialization" page in the Unity Manual for further details.
  at (wrapper managed-to-native) UnityEngine.AssetBundle.LoadAsset_Internal(UnityEngine.AssetBundle,string,System.Type)
  at UnityEngine.AssetBundle.LoadAsset (System.String name, System.Type type) [0x00042] in <a9264133a4524197a3c0792ae9dbf981>:0 
  at UnityEngine.AssetBundle.LoadAsset[T] (System.String name) [0x00001] in <a9264133a4524197a3c0792ae9dbf981>:0 
  at KSPPreciseManeuver.MainWindow..ctor () [0x00029] in <07542a723ebc46c0bdb912d19d14e699>:0 
  at KSPPreciseManeuver.PreciseManeuver..ctor () [0x00000] in <07542a723ebc46c0bdb912d19d14e699>:0 
UnityEngine.DebugLogHandler:Internal_LogException(Exception, Object)
UnityEngine.DebugLogHandler:LogException(Exception, Object)
ModuleManager.UnityLogHandle.InterceptLogHandler:LogException(Exception, Object)
UnityEngine.Logger:LogException(Exception, Object)
UnityEngine.Debug:CallOverridenDebugHandler(Exception, Object)
UnityEngine.GameObject:Internal_AddComponentWithType(Type)
UnityEngine.GameObject:AddComponent(Type)
AddonLoader:StartAddon(LoadedAssembly, Type, KSPAddon, Startup)
AddonLoader:StartAddons(Startup)
AddonLoader:OnLevelLoaded(GameScenes)
AddonLoader:OnSceneLoaded(Scene, LoadSceneMode)
UnityEngine.SceneManagement.SceneManager:Internal_SceneLoaded(Scene, LoadSceneMode)

and I'm also getting constant NREs from this mod in flight, and the window doesn't show up. First this error shows in the log

ArgumentException: Value does not fall within the expected range.
  at KSPPreciseManeuver.PreciseManeuver.Start () [0x00000] in <07542a723ebc46c0bdb912d19d14e699>:0 
UnityEngine.DebugLogHandler:Internal_LogException(Exception, Object)
UnityEngine.DebugLogHandler:LogException(Exception, Object)
ModuleManager.UnityLogHandle.InterceptLogHandler:LogException(Exception, Object)
UnityEngine.Logger:LogException(Exception, Object)
UnityEngine.Debug:CallOverridenDebugHandler(Exception, Object)

than this repeats

NullReferenceException: Object reference not set to an instance of an object
  at KSPPreciseManeuver.PreciseManeuver.Update () [0x00008] in <07542a723ebc46c0bdb912d19d14e699>:0 
UnityEngine.DebugLogHandler:Internal_LogException(Exception, Object)
UnityEngine.DebugLogHandler:LogException(Exception, Object)
ModuleManager.UnityLogHandle.InterceptLogHandler:LogException(Exception, Object)
UnityEngine.Logger:LogException(Exception, Object)
UnityEngine.Debug:CallOverridenDebugHandler(Exception, Object)

Player log here: (game wasn't exited) https://cdn.discordapp.com/attachments/966275238851653732/997942712038867034/Player_-_Copy.zip

Steps to reproduce

Launched the game after following this guide for getting debug mode and the unity profiler https://gist.github.com/gotmachine/d973adcb9ae413386291170fa346d043

Expected behavior

The in game window to show up after making a node

Actual behavior

NRE spam in the log

Environment

mod: 2.4.99
KSP: 1.12.3

How did you download and install this?

SpaceDock (manual install)

github-actions[bot] commented 2 years ago

Thank you. Kindly read contributiing.md, code_of_conduct.md and styleguide.md. These are boilerplate.

zer0Kerbal commented 1 year ago

thank you to @lisias

Apparently, something is being loaded using Unity's Serialization on the MonoBehaviour constructor, and this breaks the Unity's life cicle.

All the NREs are happening, probably, because that Object was not loaded.

Move the code to the Awake callback, it should fix this problem - but you will need to be sure that anything using that object being loaded is not called before the Awake itself.

I think the culprit is this line:

https://github.com/zer0Kerbal/PreciseManeuver/blob/f2cef5b48ef04fe333219a632c00e83123bf830f/source/src/PreciseManeuver.cs#L48

Try to replace that code with:

private GameObject m_WindowPrefab;

internal void Awake()
{
    m_WindowPrefab = PreciseManeuverConfig.Instance.Prefabs.LoadAsset<GameObject> ("PreciseManeuverWindow");
}

The thingy is private, so no other object access it, and I didn't found anyone trying to use it before the Awake event is called!

zer0Kerbal commented 1 year ago

@Rodg88 thank you - and @lisias - it seems to have fixed the issue.