Cách spawn Entity từ Prefab bằng Entity manager
C#
using Unity.Entities;
using UnityEngine;
using Unity.Transforms;
public class PrefabSpawner : MonoBehaviour
{
public GameObject Prefab; // Prefab from inspector
void Start()
{
// Config conversion settings
GameObjectConversionSettings settings = GameObjectConversionSettings.FromWorld(World.DefaultGameObjectInjectionWorld, null);
// Convert game object prefab into entity prefab
Entity prefabEntity = GameObjectConversionUtility.ConvertGameObjectHierarchy(Prefab, settings);
// Declare entity manager
EntityManager entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
// Spawn entity from prefab
Entity spawnedEntity = entityManager.Instantiate(prefabEntity);
// Set position to spawned entity
entityManager.SetComponentData(spawnedEntity, new Translation { Value = new float3(0, 0, 0) });
}
}
GameObjectConversionSettings.FromWorld(...)
- Hàm này tạo một đối tượng GameObjectConversionSettings để cấu hình quá trình chuyển đổi từ GameObject sang entity.
- Tham số đầu tiên (World.DefaultGameObjectInjectionWorld) chỉ định World mà entity sẽ được tạo ra trong đó. Đây là World mặc định mà Unity dùng cho các hệ thống hybrid (kết hợp GameObject và ECS).
- Tham số thứ hai (null) là BlobAssetStore, dùng để lưu trữ các blob asset (dữ liệu lớn như mesh, material). Nếu bạn không cần tái sử dụng blob asset giữa các lần chuyển đổi, để null là đủ.
GameObjectConversionUtility.ConvertGameObjectHierarchy(...)
- Hàm này chuyển toàn bộ hierarchy của Prefab (một GameObject) thành một entity.
- Prefab ở đây là tham chiếu đến prefab bạn đã tạo trong Unity Editor (phải gán trước, ví dụ qua Inspector hoặc code).
- Kết quả trả về là một Entity đại diện cho prefab trong ECS.
World.DefaultGameObjectInjectionWorld.EntityManager
- Lấy EntityManager từ World mặc định để quản lý entity (spawn, thêm component, v.v.).
Điều gì xảy ra khi chuyển Prefab thành Entity?
Trong Unity ECS, khi bạn dùng GameObjectConversionUtility.ConvertGameObjectHierarchy(...)
để chuyển một prefab GameObject thành entity, bạn có thể thắc mắc: “Nó có tạo entity mới không, dù chưa khởi tạo (instantiate)?” Câu trả lời là có, nhưng với một chút khác biệt.
Khi chuyển đổi, Unity tạo một entity đại diện cho prefab trong thế giới ECS. Entity này giống như một bản mẫu (template), được gắn tag Prefab, chứ không phải instance hoạt động ngay trong game. Nó tồn tại để bạn có thể dùng sau này—chẳng hạn, khi muốn khởi tạo nhiều bản sao bằng EntityManager.Instantiate(...)
.
Ví dụ cụ thể
Giả sử bạn có một prefab GameObject với một script chuyển đổi đơn giản:
C#
public class MyPrefabConverter : MonoBehaviour, IConvertGameObjectToEntity
{
public int health = 100;
public void Convert(Entity entity, EntityManager entityManager, GameObjectConversionSystem conversionSystem)
{
entityManager.AddComponentData(entity, new HealthComponent { Value = health });
}
}
Khi bạn chuyển đổi prefab này:
C#
Entity prefabEntity = GameObjectConversionUtility.ConvertGameObjectHierarchy(prefab, world);
- Một entity sẽ được tạo trong world để đại diện cho prefab.
- Bạn có thể tìm kiếm entity này (ví dụ: dùng
entityManager.GetAllEntities()
), và nó sẽ có thành phầnPrefab
cùng vớiHealthComponent
của bạn. - Tuy nhiên, entity này không “hoạt động” trong cảnh—nó chỉ là một entity prefab. Để có một instance thực sự, bạn cần khởi tạo nó:
C#
Entity instance = entityManager.Instantiate(prefabEntity);