UniTAS icon indicating copy to clipboard operation
UniTAS copied to clipboard

ScriptableObject objects not affected by soft restart

Open Eddio0141 opened this issue 2 years ago • 5 comments

Currently its jank and barely works When TAS playback ends, you can't control the game anymore ULTRAKILL spams warnings / errors for the new input system and can't control

Eddio0141 avatar Sep 14 '23 23:09 Eddio0141

Seems like its uGUI's new input system module breaks on soft restart

Eddio0141 avatar Sep 24 '23 03:09 Eddio0141

I think I figured it out In unity, you can bind some object to a serializable field (which works as a reference for most types i think other than for primitives) When the binded object is reference type and is updated in any way like doing component_field.value++, that value is preserved through soft restart, which is really bad InputSystemUIInputModule uses InputActionReference which is assigned through a serializable field in the editor, and the state of them doesn't get reset on soft restart, which is probably what's responsible for breaking

TODOs

  • [x] test if soft restart work on serializable field assigning
    • soft restart seem to work for those
    • [x] value type
    • [x] other object in scene
    • [x] other component in scene
    • [x] other component as prefab
    • [x] DontDestroyOnLoad script reference
    • [x] some other object reference that has a weird flag to be hidden
  • [x] test where is the reference type stored in (try finding with Resources class)
  • [x] reset the referencing object on soft restart
    • [x] if even possible, re-instantiate the referencing object to reset it
      • Looks like I have to use save state to serialize all the ScriptableObject classes on start up
      • [ ] otherwise, work on saving the state for some objects on start up (related to #21)
        • [ ] work on serializing basics of all fields
        • [x] test if static fields matter or not
          • it doesn't, UniTAS can handle this already
        • [x] test if object needs to be derived from UnityEngine.Object and see if only prefabs can be assigned
          • that seems to be the case, reference storing is simple as storing the reference
        • [x] timing of when to store all ScriptableObject? could it be generated later in game too?
          • initial load
          • when Object.Instantiate, ScriptableObject.CreateInstance(Type && String), ScriptableObject.CreateInstance<T>
        • [x] could ScriptableObject be duplicated and would it be a separate instance?
          • yeah just handle it like its a new object

Notes

  • Seems like reference.value modifications are reset
  • Seems like neither reference.valueType or reference.referenceType is affected by this bug
  • InputActionReference is ScriptableObject
  • Scene loading that isn't additive will wipe out all loaded ScriptableObject

Eddio0141 avatar Sep 27 '23 16:09 Eddio0141

I successfully replicated the bug with a test object deriving from ScriptableObject and its value persists after soft restart

Eddio0141 avatar Sep 28 '23 02:09 Eddio0141

changes.txt

patch file for current progress for later pr open

Eddio0141 avatar Nov 17 '23 02:11 Eddio0141

could actually use the serialized info stored in assets instead use AssetTools.NET to decode data this method would be much cleaner to do and much much easier (it should work)

  • [ ] find where the data lives
  • [ ] attempt to find how to serialize to get actual data
  • [ ] what happens with references? check!
    • it isn't stored, so probably null
    • [x] check what happens if a link happens like obj -> obj2 -> obj etc
      • they get linked. if the target ref is an unity object, it would link by path ids
      • [ ] this would require getting runtime object at path id
  • [ ] what happens with non-serializable data? is it default value?
  • [ ] how do i link from ScriptableObject to data on disk?
    • name is unreliable, don't use name
    • looks like grabbing objects from unity would return in order as defined in the resource file, NEEDS MORE TESTING
    • type is MonoBehaviour in the disk data
    • to know if the MonoBehaviour is actually a ScriptableObject, check m_Script reference, the MonoScript instance would tell exactly what type it is, this can be then verified at runtime
    • [ ] does the order appear as the path ID order in runtime?
      • [ ] TEST FIRST - to make things easier, could I directly correlate UnityEngine.Object instances found in scene at runtime
      • [ ] honestly, it would be much easier if i could find code that loads from disk and init this data. could i reverse engineer unity engine to find this out? (very hard)
      • [ ] test with game object order and compare with runtime vs disk
      • [ ] test with split ScriptableObject across levels

Extras

  • [ ] test unity 3.4
  • [ ] test latest unity
  • [ ] test with asset bundle? (idk if this is the correct name)
    • games like ultrakill split the levels into different chunks of data, investigate

Eddio0141 avatar May 22 '24 21:05 Eddio0141

This for the most part works now MonoBehaviour cloning doesn't work but this is tracked in a new issue #333

Eddio0141 avatar Nov 10 '24 17:11 Eddio0141