【Unity3D】ECS入门学习(九)SystemBase

SystemBase:支持主线程或多线程执行筛选实体任务。

主要介绍是内部成员:Entities的各种筛选方法,其内部成员还有EntityManager

ForEach方法筛选,传递一个有参委托函数进去,参数ref xxx组件类(可填多个)代表筛选条件。

WithAll:&& 形式筛选组件

WithAny: || 形式筛选组件

WithNone: 筛选出不带某组件的

WithChangeFilter:监听组件数据变化时触发筛选

WithSharedComponentFilter:筛选共享组件(指定特定数据)

WithStoreEntityQueryInField(ref EntityQuery对象):存储筛选结果

WithEntityQueryOptions(EntityQueryOptions):

EntityQueryOptions.FilterWriteGroup:筛选带[WriteGroup(typeof(xxx))特性的组件

EntityQueryOptions.IncludeDisabled:具有Disabled(已禁用)组件的实体

EntityQueryOptions.IncludePrefab:具有Prefab组件的实体

WithoutBurst:不使用Burst编译

WithBurst:使用Burst编译

Run:主线程(单线程执行)

Schedule:多线程并发

ScheduleParallel:多线程并行

cs 复制代码
using System.Collections;
using System.Collections.Generic;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
using UnityEngine;
/// <summary>
/// 可操作主线程或多线程; ComponentSystem单线程 JobComponentSystem多线程
/// </summary>
public class MySystemBase : SystemBase
{
    EntityQuery query;
    //以下方法从上到下按顺序执行
    protected override void OnCreate()
    {
        Debug.Log("OnCreate");
    }

    protected override void OnStartRunning()
    {
        Debug.Log("OnStartRunning");
    }

    protected override void OnUpdate()
    {
        Debug.Log("OnUpdate");

        //使用内部成员Entities遍历所有实体筛选出Translation组件的实体进行修改
        Entities.ForEach((ref Translation trans) =>
        {
            trans.Value = new Unity.Mathematics.float3(0, 5, 0);
        }).Run();


        //使用WithAll增加筛选条件,必须带有PrintTestComponentData组件的
        //使用Run()代表是主线程执行
        Entities.ForEach((ref Translation trans) =>
        {
            trans.Value = new Unity.Mathematics.float3(0, 5, 0);
        }).WithAll<PrintTestComponentData>().Run();

        //WithAny 只要带任意一个即可满足筛选
        Entities.ForEach((ref Translation trans) =>
        {
            trans.Value = new Unity.Mathematics.float3(0, 5, 0);
        }).WithAny<PrintTestComponentData>().Run();

        //WithNone 不包含xxx的
        Entities.ForEach((ref Translation trans) =>
        {
            trans.Value = new Unity.Mathematics.float3(0, 5, 0);
        }).WithNone<PrintTestComponentData>().Run();

        //WithChangeFilter 监听组件值变化时才触发方法体,参数必须带上ref PrintTestComponentData  否则会报错
        Entities.ForEach((ref Translation trans, ref PrintTestComponentData data) =>
        {
            trans.Value = new Unity.Mathematics.float3(0, 5, 0);
        }).WithChangeFilter<PrintTestComponentData>().Run();

        //WithSharedComponentFilter 筛选共享组件 特定值为2的
        Entities.ForEach((ref Translation trans) =>
        {
            trans.Value = new Unity.Mathematics.float3(0, 5, 0);
        }).WithSharedComponentFilter(new MyShareComponentData() { data = 2 }).Run();

        //存储筛选结果        
        Entities.ForEach((ref Translation trans) =>
        {
            trans.Value = new Unity.Mathematics.float3(0, 5, 0);
        }).WithStoreEntityQueryInField(ref query).Run();

        NativeArray<Entity> array = query.ToEntityArray(Unity.Collections.Allocator.TempJob);
        foreach (var v in array)
        {
            //do something
        }

        //过滤出带[WriteGroup]特性的组件实体  [WriteGroup(typeof(PrintTestComponentData))] 查询会根据查询中指定的组件的WriteGroupAttribute属性筛选所选实体
        Entities.ForEach((ref Translation trans) =>
        {
            trans.Value = new Unity.Mathematics.float3(0, 5, 0);
        }).WithEntityQueryOptions(EntityQueryOptions.FilterWriteGroup).Run();

        //过滤出带[DisableAutoCreation]特性的组件实体  该查询不会隐式的排除具有Disabled(已禁用)组件的实体
        Entities.ForEach((ref Translation trans) =>
        {
            trans.Value = new Unity.Mathematics.float3(0, 5, 0);
        }).WithEntityQueryOptions(EntityQueryOptions.IncludeDisabled).Run();

        //过滤出预制体实体  [DisableAutoCreation]  该查询不会隐式的排除具有Prefab组件的实体
        Entities.ForEach((ref Translation trans) =>
        {
            trans.Value = new Unity.Mathematics.float3(0, 5, 0);
        }).WithEntityQueryOptions(EntityQueryOptions.IncludePrefab).Run();

        //Schedule 多线程并发执行 ; WithoutBurst 不使用Burst编译
        Entities.ForEach((ref Translation trans) =>
        {
            trans.Value = new Unity.Mathematics.float3(0, 5, 0);
        }).WithoutBurst().Schedule();

        //ScheduleParallel 配合Job 多线程并行执行 WithBurst 使用Burst编译
        Entities.ForEach((ref Translation trans) =>
        {
            trans.Value = new Unity.Mathematics.float3(0, 5, 0);
        }).WithBurst().ScheduleParallel();

        query.Dispose();
        array.Dispose();
    }

    protected override void OnStopRunning()
    {
        Debug.Log("OnStopRunning");
    }

    protected override void OnDestroy()
    {
        Debug.Log("OnDestroy");
    }
}
相关推荐
Aman19847 小时前
Claude Code做Unity项目移植(二): 自动执行只读操作,告别频繁的
unity·游戏开发·vibe coding·claude code
Nuanyt9 小时前
Agent 学习笔记(下篇三):上线工程、进阶选择与操作界面(Stage 7 / 7.5 / 8 + 延伸路线)
笔记·python·学习·memory·aiagent·harness
叼烟扛炮11 小时前
Linux 学习笔记(四十一):TCP 并发演进——从单进程到多线程服务器
linux·运维·服务器·网络·笔记·学习·tcp/ip
叼烟扛炮11 小时前
Linux 学习笔记(四十四):HTTP 协议解析与极简 Web 服务器实战
linux·服务器·学习
songyuc12 小时前
【Manskill3】TableSceneBuilder学习笔记
pytorch·笔记·学习
外收内放12 小时前
Python基础语法练习题(75)
开发语言·python·学习
kyrie_sakura14 小时前
大模型学习20 大模型学习 - LangChain3 - Agents
人工智能·学习·langchain
zroooo14 小时前
计算机学习-知识庞大而繁杂
笔记·学习
坤坤子吖14 小时前
算法学习——单调队列
开发语言·c++·笔记·学习·算法
乌暮15 小时前
请求进门先安检:Spring 拦截器与统一功能实战指南
java·开发语言·后端·学习·spring