UnityDOTS备忘

Unity DOTS中创建一个AssetBundle并将其用作Entity

  1. 创建一个新的Unity项目,并确保已启用DOTS功能。

  2. 创建一个AssetBundle,可以通过在Project视图中右键单击文件夹并选择“Create > AssetBundle”来创建。

  3. 将您想要转换为Entity的资源(例如模型、纹理等)拖放到AssetBundle中。

  4. 创建一个新的C#脚本,用于加载AssetBundle并将其转换为Entity。以下是一个示例代码:

System间的数

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

public class AssetBundleToEntity : MonoBehaviour
{
    public GameObject prefab;
    public Material material;

    void Start()
    {
        var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;

        var entityPrefab = GameObjectConversionUtility.ConvertGameObjectHierarchy(prefab, World.Active);

        Entity entity = entityManager.Instantiate(entityPrefab);

        entityManager.AddComponentData(entity, new Translation { Value = new float3(0, 0, 0) });

        entityManager.AddSharedComponentData(entity, new RenderMesh
        {
            material = material,
            mesh = entityManager.GetSharedComponentData<RenderMesh>(entityPrefab).mesh
        });
    }
}

据传递

动态加载代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine;
using Unity.Entities;
using Unity.Transforms;
using Unity.Rendering;
using Unity.Mathematics;

public class DynamicAssetBundleLoading : MonoBehaviour
{
    public string assetBundlePath;
    public string assetName;
    public Material material;

    IEnumerator Start()
    {
        AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync(assetBundlePath);
        yield return request;

        AssetBundle assetBundle = request.assetBundle;

        AssetBundleRequest assetRequest = assetBundle.LoadAssetAsync<GameObject>(assetName);
        yield return assetRequest;

        GameObject prefab = assetRequest.asset as GameObject;

        var entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;

        var entityPrefab = GameObjectConversionUtility.ConvertGameObjectHierarchy(prefab, World.Active);

        Entity entity = entityManager.Instantiate(entityPrefab);

        entityManager.AddComponentData(entity, new Translation { Value = new float3(0, 0, 0) });

        entityManager.AddSharedComponentData(entity, new RenderMesh
        {
            material = material,
            mesh = entityManager.GetSharedComponentData<RenderMesh>(entityPrefab).mesh
        });

        assetBundle.Unload(false);
    }
}

释放Entity

using Unity.Entities;
using Unity.Transforms;
using Unity.Rendering;
using UnityEngine;

public class ReleaseEntity : MonoBehaviour
{
    EntityManager entityManager;

    void Start()
    {
        entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;

        // 创建Entity
        Entity entity = entityManager.CreateEntity();

        // 添加组件数据
        entityManager.AddComponentData(entity, new Translation { Value = new float3(0, 0, 0) });

        // 添加SharedComponent数据
        entityManager.AddSharedComponentData(entity, new RenderMesh
        {
            material = GetComponent<Renderer>().material,
            mesh = GetComponent<MeshFilter>().sharedMesh
        });
    }

    void OnDestroy()
    {
        // 释放Entity
        entityManager.DestroyEntity(entity);

        // 释放相关的GameObject和AssetBundle引用
        Destroy(gameObject);
        Resources.UnloadUnusedAssets();
    }
}

System以MonoBehaviour数据事件通知

在Unity的Data-Oriented Technology Stack (DOTS)中,如果您希望在ECS系统中的Job执行完毕后通知MonoBehaviour或外部代码,可以使用Unity的Events系统或自定义事件系统来实现通信。以下是一种常见的方法:

  1. 使用Unity的Events系统:
    • 在MonoBehaviour中定义一个事件,当事件被触发时通知外部代码。
    • 在ECS系统中,创建一个System,在System中检查Job是否执行完毕,并在适当的时机触发MonoBehaviour中定义的事件。
    • using Unity.Entities;
      using UnityEngine;
      using UnityEngine.Events;

      public class JobCompletedEvent : MonoBehaviour
      {
          public UnityEvent onJobCompleted;

          public void TriggerJobCompletedEvent()
          {
              onJobCompleted.Invoke();
          }
      }

      public class JobCompletionSystem : ComponentSystem
      {
          protected override void OnUpdate()
          {
              // 检查Job是否执行完毕
              if (jobCompleted)
              {
                  // 获取JobCompletedEvent组件
                  JobCompletedEvent jobCompletedEvent = FindObjectOfType<JobCompletedEvent>();

                  // 触发事件通知外部代码
                  jobCompletedEvent?.TriggerJobCompletedEvent();
              }
          }
      }

    • 自定义事件系统:
      • 创建一个自定义的事件系统,允许ECS系统和MonoBehaviour之间进行通信。
      • 在ECS系统中,触发自定义事件来通知MonoBehaviour或外部代码。
      • using Unity.Entities;
        using UnityEngine;

        public class CustomEventSystem : ComponentSystem
        {
            public delegate void JobCompletedEventHandler();
            public static event JobCompletedEventHandler OnJobCompleted;

            protected override void OnUpdate()
            {
                // 检查Job是否执行完毕
                if (jobCompleted)
                {
                    // 触发自定义事件通知外部代码
                    OnJobCompleted?.Invoke();
                }
            }
        }

  2. IBufferElementData

    要将DynamicBuffer与Entity关联,我们只需要定义需要的IBufferElementData,而不是DynamicBuffer本身,使用GenerateAuthoringComponent属性会自动帮我们生成DynamicBuffer并添加到Entity上,这里需要注意一下,下面定义一个简单的IBufferElementData看一下吧:

  3. using Unity.Entities;
    
    [GenerateAuthoringComponent]
    public struct IntBufferElement : IBufferElementData
    {
        public int Value;
    }

 添加与释放

EntityManager.AddComponent<IntBufferElement>(yourEntity);
EntityManager.RemoveComponent<IntBufferElement>(yourEntity);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

虾米神探

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值