docs.unity3d.com
Search Results for

    Show / Hide Table of Contents

    SystemAPI overview

    SystemAPI is a class that provides caching and utility methods for accessing data in an entity's world. It works in non-static methods in SystemBase and non-static methods in ISystem that take ref SystemState as a parameter.

    You can use it to perform the following actions:

    • Iterate through data: Retrieve data per entity that matches a query.
    • Query building: Get a cached EntityQuery, which you can use to schedule jobs, or retrieve information about that query.
    • Access data: Get component data, buffers, and EntityStorageInfo.
    • Access singletons: Find single instances of data, also known as singletons.

    All SystemAPI methods directly map to the system you put them in. This means a call like SystemAPI.GetSingleton<T>() checks whether the world that's contained on the system can perform the action.

    SystemAPI uses stub methods, which mean that they all directly call ThrowCodeGenException. This is because SystemAPI uses Roslyn source generators which replaces the methods with the correct lookup. This means that you can't call SystemAPI outside a supported context.

    To inspect your systems, use an IDE that supports source generation, such as Visual Studio 2022+ or Rider 2021.3.3+. You can then select Go To Definition to inspect the generated code on the system you're using SystemAPI within. This illustrates why you need to mark systems as partial.

    Iterate through data

    To iterate through a collection of data on the main thread, you can use the Query method in both ISystem and SystemBase system types. It uses C#’s idiomatic foreach syntax. For more information, see the documentation on SystemAPI.Query overview

    Query building

    The QueryBuilder method gets an EntityQuery, which you can then use to schedule jobs or retrieve information about the query. It follows the same syntax as EntityQueryBuilder.

    The benefit of using SystemAPI.QueryBuilder is that the method caches the data. The following example shows how the SystemAPI call is fully compiled:

    /// SystemAPI call
    SystemAPI.QueryBuilder().WithAll<HealthData>().Build();
    
    /// ECS compiles it like so:
    EntityQuery query;
    public void OnCreate(ref SystemState state){
        query = new EntityQueryBuilder(state.WorldUpdateAllocator).WithAll<HealthData>().Build(ref state);
    }
    
    public void OnUpdate(ref SystemState state){
        query;
    }
    

    Access data

    SystemAPI contains the following utility methods that you can use to access data in a system's world:

    Data type API
    Component data GetComponentLookup
    GetComponent
    SetComponent
    HasComponent
    IsComponentEnabled
    SetComponentEnabled
    Buffers GetBufferLookup
    GetBuffer
    HasBuffer
    IsBufferEnabled
    SetBufferEnabled
    EntityInfo GetEntityStorageInfoLookup
    Exists
    Aspects GetAspect
    Handles GetEntityTypeHandle
    GetComponentTypeHandle
    GetBufferTypeHandle
    GetSharedComponentTypeHandle

    These SystemAPI methods cache in your systems' OnCreate and call .Update before any call. Also, when you call these methods, ECS makes sure that the calls are synced before they get lookup access. This means that a call like SystemAPI.SetBuffer<MyElement>, which uses a lookup, in this case BufferLookup<MyElement>, causes all jobs that are currently writing to MyElement to complete. Calls such as GetEntityTypeHandle and GetBufferLookup don't cause syncs.

    This is a useful way to pass data like IJobEntity and IJobChunk into jobs without causing a sync on the main thread. For example:

    new MyJob{healthLookup=SystemAPI.GetComponentLookup<HealthData>(isReadOnly:true)};
    

    Because ECS caches this data, you can directly call it in OnUpdate. You don't need to write the whole thing, because it's equal to:

    ComponentLookup<HealthData> lookup_HealthData_RO;
    public void OnCreate(ref SystemState state){
        lookup_HealthData_RO = state.GetComponentLookup<HealthData>(isReadOnly:true);
    }
    
    public void OnUpdate(ref SystemState state){
        lookup_HealthData_RO.Update(ref state);
        new MyJob{healthLookup=lookup_HealthData_RO};
    }
    

    Entities.ForEach compatibility

    Only a selection of SystemAPI methods work in Entities.ForEach. These are as follows:

    Data type API
    Component data GetComponentLookup
    GetComponent
    SetComponent
    HasComponent
    Buffers GetBufferLookup
    GetBuffer
    HasBuffer
    EntityInfo GetEntityStorageInfoLookup
    Exists
    Aspects GetAspect

    Access singletons

    SystemAPI has singleton methods that check to make sure that there is only a single instance of the data it retrieves when invoked. These methods don't sync, which gives them a performance boost.

    For example, a call like SystemAPI.GetSingleton<MyComponent>() queries whether there is only one entity that matches the given criteria, and if so, gets the component MyComponent. It does this without asking the job system to complete all jobs that use MyComponent.

    This is a useful alternative to EntityManager.GetComponentData, which syncs data. For example, when you call EntityManager.GetComponentData<MyComponent>, all jobs that write to MyComponent complete.

    The following are a list of methods that you can use to access singleton data in SystemAPI:

    Data type API name
    Singleton component data GetSingleton
    TryGetSingleton
    GetSingletonRW
    TryGetSingletonRW
    SetSingleton
    Singleton entity data GetSingletonEntity
    TryGetSingletonEntity
    Singleton buffers GetSingletonBuffer
    TryGetSingletonBuffer
    All singletons HasSingleton

    Managed versions of SystemAPI

    The SystemAPI.ManagedAPI namespace exposes managed versions of the methods in SystemAPI, which you can use to access managed components.

    Data type API name
    Component data ManagedAPI.GetComponent
    ManagedAPI.HasComponent
    ManagedAPI.IsComponentEnabled
    ManagedAPI.SetComponentEnabled
    Handles ManagedAPI.GetSharedComponentTypeHandle

    It also contains the following managed versions of the singleton APIs:

    Data type API name
    Singleton component data ManagedAPI.GetSingleton
    ManagedAPI.TryGetSingleton
    Singleton entity data ManagedAPI.GetSingletonEntity
    ManagedAPI.TryGetSingletonEntity
    All singletons ManagedAPI.HasSingleton

    You can also use the ManagedAPI.UnityEngineComponent method, which extends SystemAPI.Query so you can query over MonoBehaviours, scriptable objects, and UnityEngine components like UnityEngine.Transform. For example:

    foreach (var transformRef in SystemAPI.Query<SystemAPI.ManagedAPI.UnityEngineComponent<Transform>>())
        transformRef.Value.Translate(0,1,0);
    

    Additional resources

    • SystemAPI API documentation
    In This Article
    Back to top
    Copyright © 2024 Unity Technologies — Trademarks and terms of use
    • Legal
    • Privacy Policy
    • Cookie Policy
    • Do Not Sell or Share My Personal Information
    • Your Privacy Choices (Cookie Settings)