Is is safe to store a ComponentType in a Subscene?

If I perform the following steps in sequence…

  • Define a ComponentA struct in the project.
  • Define a ComponentB struct in my project, with a ComponentType field.
  • Create a new Subscene. Add an entity to it. Add a ComponentB to that entity, and assign its ComponentType field to the value of ComponentType.ReadWrite().
  • Save and close the Subscene.
  • Define a ComponentC struct in the project.

At runtime, if I load my subscene, will the ComponentType I saved still be valid? Will it still refer to the ComponentType for ComponentA?

Or will the ComponentType for ComponentA have changed, because I added the ComponentC struct to my project?

If it does not, I think you can work around it by storing the type index instead of the component type.

https://docs.unity3d.com/Packages/com.unity.entities@0.16/api/Unity.Entities.TypeManager.html#Unity_Entities_TypeManager_GetTypeIndex_System_Type_

That index should be stable across all platform and builds.

But does the type index for a specific component type change, when more types are added to the project later?

I would suspect the answer is yes, which could invalidate any type indexes saves in Subscenes.

And the same problem would apply to ComponentTypes saved in Subscenes.

Hi,

Sorry did not have time to come back to you earlier.

It’s an interesting question so I made this little script in an almost empty project to test scenarios:

using Unity.Entities;

using UnityEngine;

public class LogTypeIndex : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        foreach (TypeManager.TypeInfo typeInfo in TypeManager.GetAllTypes())
        {
            System.Type systemType = TypeManager.GetType(typeInfo.TypeIndex);
            if (systemType == null || !systemType.AssemblyQualifiedName.StartsWith("wayn")) continue;
            Debug.Log($"{typeInfo.TypeIndex} / {systemType.AssemblyQualifiedName} ");
        }
    }

    // Update is called once per frame
    void Update()
    {

    }
}

It log the type index and type info of each type that is in my name space.

Baseline :

I tested adding and removing some test components and apparently nothing changes.

Adding ZTestComponent


Removing ATestComponent

Re adding ATypeComponent

Rename ATestComponent into ATestComponet2

That does not appear to be the case after building to windows however :

285212932 / wayn.mgm.demos.HealthAuthoring, mgm.demos, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
285212933 / wayn.mgm.demos.ManaAuthoring, mgm.demos, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
1090519302 / wayn.mgm.demos.ATestComponent2, mgm.demos, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
16777479 / wayn.mgm.demos.Health, mgm.demos, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
16777480 / wayn.mgm.demos.Mana, mgm.demos, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
16777481 / wayn.mgm.demos.ManaCost, mgm.demos, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
1090519306 / wayn.mgm.demos.ZTestComponent, mgm.demos, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null

And it change between rebuild on same plateform :

285212930 / wayn.mgm.demos.HealthAuthoring, mgm.demos, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
285212931 / wayn.mgm.demos.ManaAuthoring, mgm.demos, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
1090519300 / wayn.mgm.demos.ATestComponent2, mgm.demos, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
16777477 / wayn.mgm.demos.Health, mgm.demos, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
16777478 / wayn.mgm.demos.Mana, mgm.demos, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
16777479 / wayn.mgm.demos.ManaCost, mgm.demos, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
1090519304 / wayn.mgm.demos.ZTestComponent, mgm.demos, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null

TLDR ; :

Is type index robust to:

  1. new types : YES
  2. removed type : YES
  3. remove and readd type : YES
  4. Enter/exit play mode YES
  5. Built to platform : NO
  6. REbuilt to same platefrom : NO

I was not able to test for other platforms but seeing the results for Windows I don’t have much hope…

ComponentType just being a store for type index and access mode I expect it would behave in the same way…

That is terrible new IMO because now I can’t see how to make a save system for instance if we can’t trust the type index in sucessive build for the same platform. Saving an entity for one built will not be loadable in another.
Worst of all it will seems to work in editor but will not in Game… I’ll have to check how the serialize world is done to see if there is a way to make it survive rebuilds on platforms…

I supose it’s not an issue for the subsceenes themselves as they probably are rebuild when building to plaform so they would probably work fine.

OK the key is probbably in this line of code from the SerializeUtility:
var typeIndex = TypeManager.GetTypeIndexFromStableTypeHash(typeHashBuffer*);*