• HelloCube:ForEach


    此示例演示了一个简单的ECS系统,它可以旋转一对立方体。

    它显示了什么?

    此示例演示了ECS中数据和功能的分离。
    数据存储在组件中,如下RadiansPerSecond属性存储在RotationSpeed_ForEach组件中, 该结构体数据组件有[Serializable]修饰符,表示实例化属性。

    using System;
    using Unity.Entities;

    // Serializable attribute is for editor support.
    [Serializable]
    public struct RotationSpeed_ForEach : IComponentData
    {
         public float RadiansPerSecond;
    }

    而功能则写入系统,如下RotationSpeedSystem_ForEach 使用存储在 RotationSpeed_ForEach 组件中的data更新对象的旋转。

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

    // This system updates all entities in the scene with both a RotationSpeed_ForEach and Rotation component.
    public class RotationSpeedSystem_ForEach : ComponentSystem
    {
         protected override void OnUpdate()
         {
             // Entities.ForEach processes each set of ComponentData on the main thread. This is not the recommended
             // method for best performance. However, we start with it here to demonstrate the clearer separation
             // between ComponentSystem Update (logic) and ComponentData (data).
             // There is no update logic on the individual ComponentData.
             Entities.ForEach((ref RotationSpeed_ForEach rotationSpeed, ref Rotation rotation) =>
             {
                 var deltaTime = Time.deltaTime;
                 rotation.Value = math.mul(math.normalize(rotation.Value),
                     quaternion.AxisAngle(math.up(), rotationSpeed.RadiansPerSecond * deltaTime));
             });
         }
    }


    ComponentSystems和Entities.ForEach

    RotationSpeedSystem_ForEach是一个ComponentSystem,它使用Entities.ForEach委托来遍历实体。
    此示例仅创建单个实体,但如果向场景添加了更多实体,则RotationSpeedSystem_ForEach会更新所有实体 - 只要它们具有RotationSpeed_ForEach组件(并且在将GameObject的Transform转换为ECS组件时添加了旋转组件)。
    请注意,使用Entities.ForEach的ComponentSystems在主线程上运行。
    要利用多个内核,可以使用JobComponentSystem(如下一个HelloCube示例所示)。

    从GameObject转换为Entity

    ConvertToEntity MonoBehaviour在Awake时将GameObject及其子节点转换为实体和ECS组件。
    目前,ConvertToEntity可以转换的内置Unity MonoBehaviours集包括Transform和MeshRenderer。
    您可以使用实体调试器(菜单:窗口> 分析> 实体调试器)来检查转换创建的ECS实体和组件。
    您可以在自己的MonoBehaviours上实现IConvertGameObjectEntity接口,以提供ConvertToEntity用于将存储在MonoBehavi中的数据转换为ECS组件的转换函数。
    在此示例中, RotationSpeedAuthoring_ForEach MonoBehaviour使用IConvertGameObjectEntity在转换时将RotationSpeed_ForEach组件添加到实体。

    using System;
    using Unity.Entities;
    using Unity.Mathematics;
    using UnityEngine;


    [RequiresEntityConversion]
    public class RotationSpeedAuthoring_ForEach : MonoBehaviour, IConvertGameObjectToEntity
    {
         public float DegreesPerSecond;

        // The MonoBehaviour data is converted to ComponentData on the entity.
         // We are specifically transforming from a good editor representation of the data (Represented in degrees)
         // To a good runtime representation (Represented in radians)
         public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
         {
             var data = new RotationSpeed_ForEach { RadiansPerSecond = math.radians(DegreesPerSecond) };
             dstManager.AddComponentData(entity, data);
         }
    }



    HelloCube_1b_ForEachWithEntityChanges

    此示例演示了一个简单的ECS系统,该系统使用查询来选择要更新的正确实体集。然后它在ForEach lambda函数内部修改这些实体。

    该示例定义了两个标记组件,名为MovingCube_ForEachWithEntityChanges和MoveUp_ForEachWithEntityChanges。

    using System;
    using Unity.Entities;

    namespace Samples.HelloCube_1b
    {
        // Serializable attribute is for editor support.
        [Serializable]
        public struct MoveUp_ForEachWithEntityChanges : IComponentData
        {
            // MoveUp is a "tag" component and contains no data. Tag components can be used to mark entities that a system should process.
        }
    }


    using System;
    using Unity.Entities;

    namespace Samples.HelloCube_1b
    {
        // Serializable attribute is for editor support.
        [Serializable]
        public struct MovingCube_ForEachWithEntityChanges : IComponentData
        {
            // MovingCube_ForEachWithEntityChanges is a "tag" component and contains no data.
            // Tag components can be used to mark entities that a system should process.
        }
    }

    系统中的一个查询选择同时具有MoveUp_ForEachWithEntityChanges组件和Translation组件的所有实体。与此查询关联的ForEach lambda函数向上移动每个选定的实体,直到达到某个高度时,该函数将删除MoveUp_ForEachWithEntityChanges组件,以便下次系统更新时,将不会选择该实体,因此它不会向上移动任何更远的位置。

    第二个查询选择具有Translation组件但没有MoveUp_ForEachWithEntityChanges组件的所有实体。与第二个查询关联的ForEach函数将实体向下移动到其起始位置,并添加新的MoveUp_ForEachWithEntityChanges组件。由于实体再次具有MoveUp_ForEachWithEntityChanges组件,因此下次系统更新时,实体将被第一个ForEach函数向上移动并被第二个查询跳过。

    MovingCube_ForEachWithEntityChanges是一个标记组件,用于确保系统仅适用于为此示例标记的组件。示例中的两个查询都需要MovingCube_ForEachWithEntityChanges组件。

    它显示了什么?

    此示例演示了一个简单的ECS系统,该系统使用查询来选择要向上移动的一组实体。当它们达到一定高度时,系统会删除一个组件并使用另一个查询在较低的高度重新生成它们。它还演示了使用“标签”组件来提供选择具有待处理标记组件的特定entite组的方法。最后,此示例演示了如何在ForEach lambda函数内修改实体。

    组件系统和实体.ForEach

    MovementSystem_ForEachWithEntityChanges是一个ComponentSystem,它使用Entities.ForEach lambda函数迭代实体。此示例使用WithAll和WithNone约束来选择要处理的特定实体集。

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

    namespace Samples.HelloCube_1b
    {
         // This system updates all entities in the scene with Translation components.
         // It treats entities differently depending on whether or not they also have a MoveUp component.
         public class MovementSystem_ForEachWithEntityChanges : ComponentSystem
         {
             protected override void OnUpdate()
             {
                 // If a MoveUp component is present, then the system updates the Translation component to move the entity upwards.
                 // Once the entity reaches a predetermined height, the function removes the MoveUp component.
                 Entities.WithAllReadOnly<MovingCube_ForEachWithEntityChanges, MoveUp_ForEachWithEntityChanges>().ForEach(
                     (Entity id, ref Translation translation) =>
                     {
                         var deltaTime = Time.deltaTime;
                         translation = new Translation()
                         {
                             Value = new float3(translation.Value.x, translation.Value.y + deltaTime, translation.Value.z)
                         };

                        if (translation.Value.y > 10.0f)
                             EntityManager.RemoveComponent<MoveUp_ForEachWithEntityChanges>(id);
                     }
                 );

                // If an entity does not have a MoveUp component (but does have a Translation component),
                 // then the system moves the entity down to its starting point and adds a MoveUp component.
                 Entities.WithAllReadOnly<MovingCube_ForEachWithEntityChanges>().WithNone<MoveUp_ForEachWithEntityChanges>().ForEach(
                     (Entity id, ref Translation translation) =>
                     {
                         translation = new Translation()
                         {
                             Value = new float3(translation.Value.x, -10.0f, translation.Value.z)
                         };

                        EntityManager.AddComponentData(id, new MoveUp_ForEachWithEntityChanges());
                     }
                 );
             }
         }
    }

    注意:使用Entities.ForEach的组件系统在主线程上运行。要利用多个内核,可以使用JobComponentSystem(如其他HelloCube示例所示)。这也允许更改ForEach lambda函数内的实体。


  • 相关阅读:
    Python语言解析xml文件
    运行manage.py db shell出错
    ImportError: No module named win32com.client
    ImportError: No module named urllib2
    《演讲之禅》 读书笔记
    no such table: django_admin_log
    2 策略模式(2)
    1 简单工厂模式
    2 策略模式(1)
    无言
  • 原文地址:https://www.cnblogs.com/longsl/p/11324206.html
Copyright © 2020-2023  润新知