Forum rules - please read before posting.
Tech questions during the weekend? Drop in on the community Discord channel!

[Feature request] Action data serialization

We're currently investigating the causes of scene assets heavily changing in scene. This is to improve version control reviews, when checking file differences. And I noticed that Actions have A LOT of serialized data, that is used only in editor and changes only based on what type of action is present. This doesn't need serialization and would HEAVILY reduce the weight of scene files. The way that could work would be to make a lot of that data into virtual getters. That way derivative classes would override the value and regardles whether you would type cast into those classes or just the parent action. Additional effect would be that when you edit or alter action properties in code they would properly update immediately. At a glance stuff that can be reduced into virtual getters is:

category
title
description

Maybe there is more serialized data that can be removed or some of these have reasons to be serialized and not just generated through code.
I understand that some of these requests seem quite niche and nit-picky. But a lot of these seem very important for people who work with your plugin like with library or code as opposed to IDE. And right now we're working really hard to improve scene changes readability when looking at it as a text asset.

Also a consistent sorting of serialized Actions/scriptable objects would help IMMENSELY. But I haven't dug in into those systems to figure that stuff out. If actionlist actions wouldn't rearrange and rename themselves constantly in scene it would be amazing, but I haven't dug in to those systems, so I don't know whether that's possible and how.

Comments

  • edited August 2019

    Certainly I agree about the category/title/description fields - however this would bring heavy upgrade issues to any user and project that relies on custom Actions, since such changes would need to be made to all Actions.

    I am open to suggestions on a possible workaround, but at the moment there are two sides to weigh up.

  • Hmmm... If those variables would turn into public get / set without changing the name (or system.nonserialized, with values set in script automatically), compilation wouldn't break. But assigning to them inside custom actions would yield no results, since setter wouldn't point to an actual variable. That I assume would be okay for description. Scripts would just have to be updated. It would possibly be way more messy for title and category. Also you could throw warnings in setter requesting to update the field. This should ease in to the migration. This doesn't account for the situation where a person actually relies on that data being serialized, but I can't come up with such an example use case for those mentioned variables.

    And lastly a solution that would take care of both cases would be having custom defines which would replace those three. But that would make the codebase even less manageable and less readable.

    Still, all of these wouldn't matter that much if the scriptable objects wouldn't constantly rearrange and rename themselves behind the scenes. If you have any pointers as to where and in what context that happens I could try looking into it to see whether they can be consistently sorted and named in the scene file and would move around as little as possible when altered.

  • edited August 2019

    I'm not sure exactly what you're referring to, but the order of Actions is more important when using the Inspector to configure them since they're displayed linearly. When exactly does re-ordering occur? Only when viewing an ActionList in its Inspector / Editor?

  • The reordering happens when reviewing scenes as text assets. Actions which are created as scriptable objects seem to get heavily shuffled around. The prime reason could be that some serialized data is constantly recreated and thus it gets shuffled around.

    Diff tool comparison (see left scrollbar for the whole scene changes overview):

  • Viewing the asset in and of itself shouldn't cause data to get reshuffled - though if so it may be a quirk of Unity. What kind of change are you making to an ActionList before and after such a change? Just adding an Action, viewing it's Editor, etc?

  • edited September 2019

    The minimum amount of changes when this happens is viewing actionlist editor. Actionlists are also grouped in hierarchies which are occassionaly disabled and/or enabled both in edit and in play.
    The most edge case I can think of is viewing ActionList editor window on an action that is currently disabled in hierarchy. We may refactor in the future so that all actions are grouped under objects that don't get disabled/enabled. Since we don't need actual gameobject disable/enable for them specifically, they just end up getting it because of the scene structure.

  • OK, so I've found the source of the data reshuffling - ActionList's CopyScriptable function, which is used to duplicate Actions to ensure that they aren't linked copies of another set when the ActionList GameObject is duplicated.

    This is currently called in Awake during Edit Mode, and is necessary because Unity does not provide an event hook for the act of duplication.

    I feel it should be safe, however, to call this instead from OnValidate. In testing, this typically only gets called when an ActionList is duplicated, or upon script compilation - which should mean it modifies your scene file a lot less.

  • Great catch! I'll check the area too. Maybe I'll have some ideas as to how to work around this stuff. As far as I can see this is the place that probably causes actions to eventually become named (Clone)(Clone)(Clone)(Clone)(Clone)(Clone)Something. This again is only visible when opening asset in text editor, since ScriptableObject names aren't displayed in unity itself. It would be nice if you could restore the old name after object copy.

  • edited November 2019

    OnValidate could potentially fire more often than an awake. The best I could come up with, was passing a reference of actionlist to the action that it belongs to. This reference if serialized should be more reliable than various InstanceID comparisons. So actionlist can check whether the action 'considers' itself to belong to that actionlist before. And wrap this field in #if UNITY_EDITOR, so that this serialized back-reference inside action wouldn't make it to the build.

    Another part that could help, is when copying actions, not creating a new List. I can't say from the top of my head, so this might need some testing, but I think when component gets duplicated, the lists also get duplicated. Each item in the list ends up being the same only.

    So instead of this:

    `

    foreach (Action action in actions)
    {
    if (action != null)
    {
    Action clonedAction = Object.Instantiate (action) as Action;
    newActions.Add (clonedAction);
    }
    }

    `

    doing this:

    `

    for (int i=0; i<actions.Count; i++)
    {
    if (actions[i] != null)
    {
    actions[i] = Object.Instantiate(actions[i]) as Action;
    }
    }

    `

    Note that the latter version, doesn't clean up list elements that are null the way that former does. I don't know whether that is needed, but it can be done separately afterwards if it is.

    Might help... or it might have absolutely no effect on serialization.

  • Food for though, certainly.

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.
Do NOT follow this link or you will be banned from the site!