Unity DOTS中创建一个AssetBundle并将其用作Entity
创建一个新的Unity项目,并确保已启用DOTS功能。
创建一个AssetBundle,可以通过在Project视图中右键单击文件夹并选择“Create > AssetBundle”来创建。
将您想要转换为Entity的资源(例如模型、纹理等)拖放到AssetBundle中。
创建一个新的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
});
}
}
据传递
动态加载代码
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
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
});
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
mesh = GetComponent
});
}
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系统或自定义事件系统来实现通信。以下是一种常见的方法:
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?.TriggerJobCompletedEvent();
}
}
}
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();
}
}
}
要将DynamicBuffer与Entity关联,我们只需要定义需要的IBufferElementData,而不是DynamicBuffer本身,使用GenerateAuthoringComponent属性会自动帮我们生成DynamicBuffer并添加到Entity上,这里需要注意一下,下面定义一个简单的IBufferElementData看一下吧:
- using Unity.Entities;
-
- [GenerateAuthoringComponent]
- public struct IntBufferElement : IBufferElementData
- {
- public int Value;
- }
添加与释放
- EntityManager.AddComponent<IntBufferElement>(yourEntity);
- EntityManager.RemoveComponent<IntBufferElement>(yourEntity);