Forum rules - please read before posting.

Suggestion: Ability to specify a custom persistent prefab

Hi there!

It would be great if it was possible to point out a custom prefab that gets added (last) to AC's persistent engine during SetPersistentEngine().

Here's just one example where this would be helpful:
When targeting platforms that require a custom handlers for Options.OptionsFileHandler or SaveSystem.SaveFileHandler, the new handlers must be registered on Awake (by any game object in the scene). This prefab would allow a clean way for this and any other custom logic to be executed at the right time no matter which scene is ran as the first scene (without the need to add custom bootstrapping logic to every scene in the game).

Alternatively, the "Event system prefab" in the Menu manager could be used for this purpose, if it was instantiated at the point mentioned above (today it's Awake is called too late for stuff like custom handlers to be registered).

Thanks

Comments

  • a custom prefab that gets added (last) to AC's persistent engine during SetPersistentEngine().

    As in, a separate object that gets pareneted to the PersistentEngine?

    It's already possible to modify the PersistentEngine prefab - it's in /AdventureCreator/Resources.

  • As in, a separate object that gets pareneted to the PersistentEngine?

    Exactly

    It's already possible to modify the PersistentEngine prefab - it's in /AdventureCreator/Resources.

    This comes with two drawbacks - it must be done after every AC update, and it requires PersistentEngine to be loaded from Resources rather than to be "constructed" in runtime.

    If you don't think it's a good fit, would you consider the alternative solution I mentioned?

  • If you don't think it's a good fit, would you consider the alternative solution I mentioned?

    Try this. Open up StateHandler, and look for the line:

    KickStarter.sceneChanger.OnInitPersistentEngine ();
    

    Immediately above, copy/paste:

    KickStarter.playerMenus.gameObject.SendMessage ("CreateEventSystem");
    

    Then open up PlayerMenus, and look for the line:

    Menu[] allMenus = GetMenus (true).ToArray ();
    

    Replace it with:

    Menu[] allMenus = KickStarter.menuManager.menus.ToArray ();
    

    That should cause the EventSystem to kick in before any data-loading occurs. Does that work for you?

  • PlayerMenus has 6 occurrances of:
    Menu[] allMenus = GetMenus (true).ToArray ();

    I tried replacing the first one - it didn't work.

  • Ah, sorry - it's the one in the AreAnyMenusUI function.

  • Doesn't work.
    No worries tho - I'll figure something out on my end.

  • Doesn't work.

    In what way?

  • edited June 2023
    In that it doesn't run early enough. If you have a package for me to try out where it's firring earlier I'd love to try it out tho.
  • The dev package I sent you yesterday should include the changes - with a script attached that sets the OptionsFileHandler in Awake, it should kick in before Options data is requested.

  • It work in the Unity Editor, but in a real (Switch) build I get this (indexing fails because KickStarter.runtimeLanguages.Languages on Options.cs:145 has a count of 0):

    ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
    Parameter name: index
    at System.Collections.Generic.List`1[T].get_Item (System.Int32 index) [0x00000] in <00000000000000000000000000000000>:0
    at AC.Options.LoadPrefs () [0x0012c] in C:\Users\pontu\source\repos\Korath\Korath\Assets\AdventureCreator\Scripts\Options\Options.cs:145
    at AC.Options.set_OptionsFileHandler (AC.iOptionsFileHandler value) [0x00007] in C:\Users\pontu\source\repos\Korath\Korath\Assets\AdventureCreator\Scripts\Options\Options.cs:982
    at Scuac.Runtime.Hosting.GameHostResolver.EnsurePreInit () [0x00024] in C:\Users\pontu\source\repos\Korath\Korath\Assets\Scuac\Runtime\Hosting\GameHostResolver.cs:50
    at Scuac.Components.RuntimePersistentLogicBootstrapper.Awake () [0x00015] in C:\Users\pontu\source\repos\Korath\Korath\Assets\Scuac\Runtime\Components\RuntimePersistentLogicBootstrapper.cs:25
    at UnityEngine.Object.Instantiate[T] (T original) [0x00018] in C:\build\output\unity\unity\Runtime\Export\Scripting\UnityEngineObject.bindings.cs:285
    at AC.PlayerMenus.CreateEventSystem () [0x0004a] in C:\Users\pontu\source\repos\Korath\Korath\Assets\AdventureCreator\Scripts\Controls\PlayerMenus.cs:258
    at AC.StateHandler.Initialise (System.Boolean rebuildMenus) [0x0001f] in C:\Users\pontu\source\repos\Korath\Korath\Assets\AdventureCreator\Scripts\Game engine\StateHandler.cs:104
    at AC.KickStarter.SetPersistentEngine () [0x0017a] in C:\Users\pontu\source\repos\Korath\Korath\Assets\AdventureCreator\Scripts\Game engine\KickStarter.cs:178
    at AC.KickStarter.Initialise () [0x00034] in C:\Users\pontu\source\repos\Korath\Korath\Assets\AdventureCreator\Scripts\Game engine\KickStarter.cs:1103
    at AC.MultiSceneChecker.Awake () [0x00042] in C:\Users\pontu\source\repos\Korath\Korath\Assets\AdventureCreator\Scripts\Game engine\MultiSceneChecker.cs:45
    UnityEngine.Object:Instantiate(EventSystem) (at C:\build\output\unity\unity\Runtime\Export\Scripting\UnityEngineObject.bindings.cs:285)
    AC.PlayerMenus:CreateEventSystem() (at C:\Users\pontu\source\repos\Korath\Korath\Assets\AdventureCreator\Scripts\Controls\PlayerMenus.cs:258)
    AC.StateHandler:Initialise(Boolean) (at C:\Users\pontu\source\repos\Korath\Korath\Assets\AdventureCreator\Scripts\Game engine\StateHandler.cs:104)
    AC.KickStarter:SetPersistentEngine() (at C:\Users\pontu\source\repos\Korath\Korath\Assets\AdventureCreator\Scripts\Game engine\KickStarter.cs:178)
    AC.KickStarter:Initialise() (at C:\Users\pontu\source\repos\Korath\Korath\Assets\AdventureCreator\Scripts\Game engine\KickStarter.cs:1103)
    AC.MultiSceneChecker:Awake() (at C:\Users\pontu\source\repos\Korath\Korath\Assets\AdventureCreator\Scripts\Game engine\MultiSceneChecker.cs:45)

  • Replace Options.cs line 145:

    if (KickStarter.speechManager && KickStarter.runtimeLanguages.Languages[optionsData.language].isDisabled)
    

    with:

    if (KickStarter.speechManager && optionsData.language < KickStarter.runtimeLanguages.Languages.Count && KickStarter.runtimeLanguages.Languages[optionsData.language].isDisabled)
    
  • edited June 2023

    I Get this error (no stack trace):

    Error: nn::fs::CreateDirectory() failed because the operation is unsupported.

    This means the bootstrapping logic ran too late.
    After trying a bunch of strategies, the only way I found that works reliably in all circumstances are:

    Option1: Having a component on every scene that does the bootstrapping logic on Await

    Option2: Modifying PersistentEngine prefab to contain a custom written component that does the bootstrapping (requires the prefab to be updated on each AC update and for it to be loaded form Resources in runtime)

    I'm not sure if it's even possible, but it would be awesome if we could register a type (component) with AC that it would then add to the PersistentEngine (after line 170 in Kickstarter).

  • requires the prefab to be updated on each AC update

    Not necessarily - you can omit it from the import dialog window when updating to retain any custom changes. If using version control, you can also roll back that specific file otherwise.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.