unity-game-engineunity-ecs

Unity ECS Aspects ComponentType Unkown


I am new to Unity ECS and I have troubles creating a custom aspect. Honestly I am a little bit helpless, why I better describe what I did and give the corresponding error messages.

Info: I'm running following versions:

Unity 2022.2.17
ECS 1.0.0-pre.65

I started with this Struct:

namespace RubixCube.Aspects
{
    using ComponentData;
    using Unity.Entities;
    
    public readonly partial struct CubeSpawnerAspect : IAspect
    {
        public readonly RefRO<CubeSpawner> cubeSpawner;
    }
}

I got the error that I need to implement the interface interface member IAspectCreate<CubeSpawnerAspect>.AddComponentRequirementsTo(ref UnsafeList<ComponentType>, bool).

So I got to this code:

namespace RubixCube.Aspects
{
    using Unity.Collections.LowLevel.Unsafe;
    using ComponentData;
    using Unity.Entities;
    
    public readonly partial struct CubeSpawnerAspect : IAspect
    {
        public readonly RefRO<CubeSpawner> cubeSpawner;

        public void AddComponentRequirementsTo(ref UnsafeList<ComponentType> all, bool isReadOnly) {}
    }
}

Now I get the following error message: Unity.Entities.SourceGen.AspectGenerator/Unity.Entities.SourceGen.Aspect.AspectGenerator/CubeSpawnerAspect__Aspect_15009073790.g.cs(36,99): error CS0246: The type or namespace name 'ComponentType' could not be found (are you missing a using directive or an assembly reference?)

According to my IDE (I know that I cannot really rely on that one) and to an old documentation of Unity I found here, ContentType should be available in the namespace Unity.Entities.

Strangely if I change my code to the following, I get a different error message and Unity seams to recognise ContentType:

namespace RubixCube.Aspects
{
    using Unity.Collections.LowLevel.Unsafe;
    using ComponentData;
    //using Unity.Entities;
    
    public readonly partial struct CubeSpawnerAspect : Unity.Entities.IAspect
    {
        public readonly Unity.Entities.RefRO<CubeSpawner> cubeSpawner;

        public void AddComponentRequirementsTo(ref UnsafeList<Unity.Entities.ComponentType> all, bool isReadOnly) {}
    }
}

This is the new error message: Temp/GeneratedCode/RubixCube/SpawnCubeJob__JobEntity_16494086480.g.cs(115,61): error CS0426: The type name 'TypeHandle' does not exist in the type 'CubeSpawnerAspect'

At this one I am stuck and I don't get what is possible wrong nor do I understand, why the last change fixed the ContentType Error.

How can I fix it?

I am open for a different way to create a custom (reusable) Aspect if there is one tho.

Thank you in advance!!

For the sake of completeness here all file aspect depends on or that use the aspect:

CubeSpawner:

namespace RubixCube.ComponentData
{
    using UnityEngine;
    using Unity.Entities;
    
    public struct CubeSpawner : IComponentData
    {
        public Entity cubeEntity;

        public Entity plateEntity;

        public byte cubeSize;

        public Color topColor;
        public Color bottomColor;
        public Color frontColor;
        public Color backColor;
        public Color leftColor;
        public Color rightColor;
    }
}

CubeSpawnerAuthoring:

namespace RubixCube.Authoring
{
    using ScriptableObjects;
    using UnityEngine;
    
    public class CubeSpawnerAuthoring : MonoBehaviour
    {
        [SerializeField]
        private ScriptableRubixCube rubixCube;

        public ScriptableRubixCube getRubixCube()
        {
            return this.rubixCube;
        }
    }
}

CubeSpawnerBaker:

namespace RubixCube.Bakers
{
    using Enums;
    using ScriptableObjects;
    using ComponentData;
    using Authoring;
    using Unity.Entities;
    
    public class CubeSpawnerBaker : Baker<CubeSpawnerAuthoring>
    {
        public override void Bake(CubeSpawnerAuthoring authoring)
        {
             ScriptableRubixCube cube = authoring.getRubixCube();
            
            AddComponent(new CubeSpawner
            {
                cubeEntity = GetEntity(cube.getCubePrefab()),
                plateEntity = GetEntity(cube.getPlatePrefab()),
                
                cubeSize = cube.getCubeSize(),
                
                topColor = cube.getColorOf(CubeSide.TOP),
                bottomColor = cube.getColorOf(CubeSide.TOP),
                frontColor = cube.getColorOf(CubeSide.TOP),
                backColor = cube.getColorOf(CubeSide.TOP),
                leftColor = cube.getColorOf(CubeSide.TOP),
                rightColor = cube.getColorOf(CubeSide.TOP)
            });
        }
    }
}

SpawnCubeJob:

namespace RubixCube
{
    using Aspects;
    using ComponentData;
    using Unity.Entities;
    
    public partial struct SpawnCubeJob : IJobEntity
    {
        public EntityManager entityManager;
        
        private void Execute(ref CubeSpawnerAspect cubeSpawnerAspect)
        {
            CubeSpawner cubeSpawner = cubeSpawnerAspect.cubeSpawner.ValueRO;
            byte cubeSize = cubeSpawner.cubeSize;
            Entity cubePrefab = cubeSpawner.cubeEntity;
        }
    }
}

CubeSpawnSystem:

using UnityEngine;
namespace RubixCube.Systems
{
    using Unity.Entities;
    public partial struct CubeSpawnSystem : ISystem
    {
        public void OnCreate(ref SystemState state)
        {
        }
    }
}

Solution

  • After some time I found a fix. I get those bugs when I put the using Statements in which I require types from Unity inside of the namespace.

    So instead of this:

    namespace RubixCube.Aspects
    {
        using ComponentData;
        using Unity.Entities;
        
        public readonly partial struct CubeSpawnerAspect : IAspect
        {
            public readonly RefRO<CubeSpawner> cubeSpawner;
        }
    }
    

    Do this:

    using RubixCube.ComponentData;
    using Unity.Entities;
    
    namespace RubixCube.Aspects
    { 
        public readonly partial struct CubeSpawnerAspect : IAspect
        {
            public readonly RefRO<CubeSpawner> cubeSpawner;
        }
    }
    

    I'm not sure whether this change is just needed for any partial struct/class nor do I know whether you just need to drag the using Unity.Entities statements outside of the namespace.

    I just did it with any using Statement in every file and it worked.