Forum rules - please read before posting.

Deleted Action Data Stored in Scene ActionLists

Hello, I've been looking into a strange issue with Action data persisting in scene files after the associated Actions have been deleted from all in-scene Action Lists. I haven't been able to reproduce the actual cause of this issue, unfortunately, since I only discovered it recently in a few scene files.

I have an example scene that has everything deleted out of it except for an AC Trigger component with a single Action. For some reason, this remaining Action is tied to approximately 5K lines of unrelated MonoBehaviour Action data in the scene file. If I delete the Action and save the scene, the file length is reduced to ~250 lines (just the bare scene). The same thing happens if I change the Action type and save. However, changing settings on the current Action does not clear the stale data.

Here is a link to the scene set up in the scenario above (apologies for providing this right off the bat, I know that's not recommended in the Forum Rules, but I don't know of a better way to clearly demonstrate the issue): https://drive.proton.me/urls/SQCVR8DWN4#mW2W4OCrjvZj

I have tried clearing Action Data on the Trigger component (Right Click -> Action Data -> Clear), but that does not remove the stale data.

When I imported this scene into a new project with the same AC/Unity versions and saved the file with no changes, it was reduced to ~3.5K lines. Not exactly sure what changed, but it still has a significant amount of old action data.

As a test, I tried removing all Actions on the same Trigger except for a different random one and it seems leave a similar, but not identical, set of stale data in place...

Is there any way to run a cleanup process to purge the stale action data in the scenes? Or some way to gain some insight into why this may be happening?

Any thoughts would be appreciated. Thanks!

AC Version: 1.76.0
Unity Version: 2021.3.16 LTS

Comments

  • I have an example scene that has everything deleted out of it except for an AC Trigger component with a single Action. For some reason, this remaining Action is tied to approximately 5K lines of unrelated MonoBehaviour Action data in the scene file.

    To be clear: was the old Action data part of the Trigger - and those Actions were deleted in the ActionList Editor - or were they on other ActionLists that you deleted in the Hierarchy?

    If it's the latter, I suspect this isn't a case of the remaining Action data being a part of the Trigger - but part of the scene itself.

    On a technical level: Unity stores data for scene-based Actions as part of the scene file itself - detached from the ActionList GameObject. Since Unity introduced its [SerializeReference] keyword, it's become possible to get around this with some alterations under the hood - but so far I cannot get it to do so without destroying existing Action data.

    If you're interested, AC is technically possible of this, and you can enable it by adding AC_ActionListPrefabs as a Scripting Define Symbol. Just be sure to in a new project - as any existing ActionList data will be removed!

    So far as the original issue goes: if the ActionLists that stored the now-detached Action are gone, it's a case of Unity running its own clean-up process to remove unused data (which you can see when switching Action). With existing ActionLists, it'd be a case of deleting Actions manually first and then deleting the GameObject.

    I shall look into this myself, though, and let you know if I can find an alternative.

  • Thanks for the explanation and technical detail, that's very helpful to understand. The main reason I ran across this was when searching for references before deleting old files and was confused to find some very old ones in certain scenes.

    One additional factor that I can think of (which I have zero idea if it's related or not) is that we used to have all of our ActionList game objects inheriting from the default AC Prefabs. This was causing scene files to scramble their contents every time the scene was saved, so we unpacked the prefabs with ActionLists directly into the scene to prevent this behavior from occurring since it wrecked havoc on source control.

    To be clear: was the old Action data part of the Trigger - and those Actions were deleted in the ActionList Editor - or were they on other ActionLists that you deleted in the Hierarchy?

    The old action data (at least those that I can identify with confidence in the code) was part of the Trigger, not other ActionLists. And yes, those actions would have been deleted via the ActionList Editor during normal workflows.

    So far as the original issue goes: if the ActionLists that stored the now-detached Action are gone, it's a case of Unity running its own clean-up process to remove unused data (which you can see when switching Action). With existing ActionLists, it'd be a case of deleting Actions manually first and then deleting the GameObject.

    I considered converting all of our ActionLists to assets using the Convert to ActionList Asset tool, however that process does not automatically clear the action data in the scene and would require us to manually convert every ActionList in the project - quite a big lift for us at this point and not something we'd consider lightly.

    Is the remaining action in question somehow linked to the old actions? It seems super odd that if I copy/paste the action inside the ActionList and delete the original one that the detached actions also come along with the copied action.

    I shall look into this myself, though, and let you know if I can find an alternative.

    Much appreciated!

  • Oddly, there seems to be two sets of disconnected Action data within the scene file. Running a "SetDirty" command on the ActionList reduces about half of them, but the others are a part of the GameObject itself, due to the way Unity serializes the data.

    How far back does your project - or this scene - go so far as AC versioning goes?

  • How far back does your project - or this scene - go so far as AC versioning goes?

    This is the project's AC version history: 1.63.2 -> 1.69.5 -> 1.76.0

    The scene in question goes all the way back to the beginning, so it's been through all the upgrades, AC and Unity. Started on Unity 2018.1.5 and made incremental upgrades through the LTS versions.

  • OK, thanks. I see what's going on.

    It's a case of Actions being inadvertently copied when being linked to one another. This is behaviour I saw a few years ago and took steps to remedy - but it's only been able to be partial, as there is a (albeit very small by this point) risk of some Actions becoming disconnected in very old AC versions.

    The complete remedy isn't difficult to implement manually, however - though it's crucial to back up the project first.

    Firstly, in Action.cs, replace line 64:

    [SerializeField] private AC.Action skipActionActual = null;
    

    with:

    [System.NonSerialized] private AC.Action skipActionActual = null;
    

    And then make a similar change to ActionCheck.cs' lines 32 and 43:

    [System.NonSerialized] private AC.Action skipActionTrueActual = null;
    [System.NonSerialized] private AC.Action skipActionFailActual = null;
    

    You'd then need Unity to mark your ActionLists as dirty so that it can remove the lost data. You can do this by e.g. adding then removing an Action, but this script will add an option in the Adventure Creator top toolbar menu to update your scenes automatically:

    using UnityEditor;
    using AC;
    
    public class CleanActionLists : EditorWindow
    {
    
        [MenuItem ("Adventure Creator/ActionLists/Clean")]
        static void Clean ()
        {
            if (UnityEditor.SceneManagement.EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo ())
            {
                string originalScene = UnityVersionHandler.GetCurrentSceneFilepath ();
    
                string[] sceneFiles = AdvGame.GetSceneFiles ();
                foreach (string sceneFile in sceneFiles)
                {
                    if (string.IsNullOrEmpty (sceneFile)) continue;
    
                    UnityVersionHandler.OpenScene (sceneFile);
                    ActionList[] actionLists = FindObjectsOfType<ActionList> ();
                    foreach (ActionList actionList in actionLists)
                    {
                        UnityVersionHandler.CustomSetDirty (actionList, true);
                    }
    
                    UnityVersionHandler.SaveScene ();
                }
    
                UnityVersionHandler.OpenScene (originalScene);
            }
        }
    
    }
    
  • I'll need to do some deeper testing across the game to make sure everything is working before committing the change, but that appears to have done the trick!

    Thank you so much for your help, Chris - sincerely appreciated! :)

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.