Unity ECS 案例学习笔记


资源地址:https://github.com/Unity-Technologies/EntityComponentSystemSamples

1.ForEach

在Hierarchy中创建GameObject实例,由插件中的ConvertToEntity在运行时把实例转换成Entity实例,RotationSpeedAuthoring_ForEach负责具体转换工作(添加组件数据等…)
在这里插入图片描述

脚本说明

RotationSpeedAuthoring_ForEach:把设置的参数DegreesPerSecond(角度速率)转成ComponentData(弧度速率)并绑定到entity上。
RotationSpeed_ForEach:这是个ComponentData,Entity实例的数据,注意它是结构体(Struct)不是类(Class)
RotationSpeedSystem_ForEach:组件系统,负责把ComponentData应用到Entity上,它在OnUpdate中对所有的Entity进行设置,Entities.ForEach会经常用到。

ReadMe

This sample demonstrates a simple ECS System that rotates a pair of cubes.

## What does it show?

This sample demonstrates the separation of data and functionality in ECS. Data is stored in components, while functionality is written into systems.

The **RotationSpeedSystem_ForEach** *updates* the object's rotation using the *data* stored in the **RotationSpeed_ForEach** Component.

## ComponentSystems and Entities.ForEach

RotationSpeedSystem_ForEach is a ComponentSystem and uses an Entities.ForEach delegate to iterate through the Entities. This example only creates a single Entity, but if you added more Entities to the scene, the RotationSpeedSystem_ForEach updates them all — as long as they have a RotationSpeed_ForEach Component (and the Rotation Component added when converting the GameObject's Transform to ECS Components).

Note that ComponentSystems using Entities.ForEach run on the main thread. To take advantage of multiple cores, you can use a JobComponentSystem (as shown in the next HelloCube example).

## Converting from GameObject to Entity

The **ConvertToEntity** MonoBehaviour converts a GameObject and its children into Entities and ECS Components upon Awake. Currently the set of built-in Unity MonoBehaviours that ConvertToEntity can convert includes the Transform and MeshRenderer. You can use the **Entity Debugger** (menu: **Window** > **Analysis** > **Entity Debugger**) to inspect the ECS Entities and Components created by the conversion.

You can implement the IConvertGameObjectEntity interface on your own MonoBehaviours to supply a conversion function that ConvertToEntity will use to convert the data  stored in the MonoBehaviour to an ECS Component.

In this example, the **RotationSpeedAuthoring_ForEach** MonoBehaviour uses IConvertGameObjectEntity to add the RotationSpeed_ForEach Component to the Entity on conversion.

1b.FluentQuery

在MonoBehaviour中可以生成一堆的Entity实例,并对它们初始化
在这里插入图片描述

脚本说明

HelloSpawnMonoBehaviour:把GameObject预制体转成EntityPrefab,再由World.Active.EntityManager实例化。初始化的时候给实例添加自定义的:ComponentData(MoveUp&MovingCube),它们两个不存数据只做Tag用。
MovementSystem:分两个部分第一部分:在OnUpdate中筛选出带有MoveUp&MovingCube组件的Entity实例,对它们进行位置偏移操作,当到达条件时删除(PostUpdateCommands.RemoveComponent<MoveUp>)掉MoveUp组件取消对它的偏移操作,第二部分:筛选出不带MoveUp的所有带MovingCube组件的Entity实例重置它的位置并重新添加(PostUpdateCommands.AddComponent)MoveUp组件。这两个部分就起到了循环Entity实例位置运动的功能。

ReadMe

This sample demonstrates a simple ECS System that uses fluent queries to select the correct set of entities to update.

The example defines two tag component, named MovingCube and MoveUp. One fluent query in the system selects all entities that have both a MoveUp component and a Translation component. The ForEach lambda function associated with this query moves each selected entity upwards until it reaches a certain height. At that point, the function removes the MoveUp component so the next time the system updates, the entity will not be selected and thus it will not be moved upwards any farther.

A second fluid query selects all entities that have a Translation component, but do not have a MoveUp component. The ForEach function associated with the second query moves the entity down to its starting location and adds a new MoveUp component. Since the entity has a MoveUp component once again, the next time the system updates, the entity is moved upward by the first ForEach function and skipped by the second query.

The MovingCube is another tag component that ensures that the system only works on components marked for this sample.

## What does it show?

This sample demonstrates a simple ECS System that uses fluent queries to select a set of entities to move upwards.  When they reach a certain height, the system removes a component and uses another query to respawn them at a lower height.  It also demonstrates the use of "tag" components to provide a means of selecting specific sets of entites with marker components to be processed.

## Component Systems and Entities.ForEach

MovementSystem is a ComponentSystem and uses an Entities.ForEach delegate to iterate through the Entities. This example uses the WithAll and WithNone constraints to select specific sets of entities to work on.

Note: Component Systems using Entities.ForEach run on the main thread. To take advantage of multiple cores, you can use a JobComponentSystem (as shown in other HelloCube examples).

2.IJobForEach

由于Component System 使用的Entities.ForEach是运行在主线程中的,如果需要多核方式就可以使用JobComponentSystem
只需要修改System部分即可。如下:

using Unity.Entities;
using Unity.Jobs;
using Unity.Mathematics;
using Unity.Transforms;
using UnityEngine;

// This system updates all entities in the scene with both a RotationSpeed_IJobForEach and Rotation component.

// ReSharper disable once InconsistentNaming
public class RotationSpeedSystem_IJobForEach : JobComponentSystem
{
    // Use the [BurstCompile] attribute to compile a job with Burst. You may see significant speed ups, so try it!
    [BurstCompile]
    struct RotationSpeedJob : IJobForEach<Rotation, RotationSpeed_IJobForEach>
    {
        public float DeltaTime;

        // The [ReadOnly] attribute tells the job scheduler that this job will not write to rotSpeedIJobForEach
        public void Execute(ref Rotation rotation, [ReadOnly] ref RotationSpeed_IJobForEach rotSpeedIJobForEach)
        {
            // Rotate something about its up vector at the speed given by RotationSpeed_IJobForEach.
            rotation.Value = math.mul(math.normalize(rotation.Value), quaternion.AxisAngle(math.up(), rotSpeedIJobForEach.RadiansPerSecond * DeltaTime));
        }
    }

    // OnUpdate runs on the main thread.
    protected override JobHandle OnUpdate(JobHandle inputDependencies)
    {
        var job = new RotationSpeedJob
        {
            DeltaTime = Time.deltaTime
        };

        return job.Schedule(this, inputDependencies);
    }
}

3.IJobChunk

IJobChunk与IJobForEach类似,但是:Systems using IJobChunk can handle more complex situations than those supported by IJobForEach, while maintaining maximum efficiency.即IJobChunk更好点。

4.SubScene

如果场景中有大量的物体,可以把它们分成一系列的SubScene,然后放到主场景中。
如下图所示SubScene是当前的主场景,Game View中的物体其实是RotatingCube子场景中的物体,通过SubScene脚本实现。

在这里插入图片描述

5.SpawnFromMonobehaviour

如何在Monobehaviour中生成一个Entity实例呢?
首先通过GameObjectConversionUtility.ConvertGameObjectHierarchy(Prefab, World.Active);把一般普通的预制体转成EntityPrefab,然后用
World.Active.EntityManager.Instantiate(prefab)进行实例化。
未完待续

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

牙膏上的小苏打2333

哟,哟,切克闹,煎饼果子来一套

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值