unity ecs的备忘录
关于parent和LinkedEntityGroup
parent 涉及到localtoworld, 以及一些物理和其他的转换规则
parent和位置有关系..所以父实体需要添加Translation和LocalToWorld.否则会删除该parent和LocalToParent组件
添加了parent组件且添加了Translation,LocalToWorld,LocalToParent组件,会自动给父实体添加child组件,四个组件缺一不可
如果使用了LocalToParent,这个时候Translation代表的是相对于父对象的坐标..相当于传统的localTranslation
这个时候如果获取世界坐标..可以使用LocalToWorld.pos
linkedEntityGroup 和
Instantiate
SetEnabled
DestroyEntity
有关
关于转换
在Conversion World中,仅仅是复制生成了来自Classic World的、保留原有Hierarchy关系的GameObject Entity,这些Entity拥有的组件仍然是我们熟知的传统Unity组件,例如Transform、MeshFilter。接下来,将调用DOTS预置的或我们自定义的Convert接口,完成向IComponentData组件的转换。自然而然的,可能没有实现对某Component Object的转换接口,那么在转换过程中将被丢弃,所以该转换不一定是“一对一”,所以Unity称呼其为”Primary Entity”。下图呈现了转换全过程。
转换过程都是在Conversion World中完成的,DOTS在内部为转换过程创建了一个World。作为独立World,它拥有自己的EntityManager和ComponentSystem,进而拥有并管理自己的Entity和ComponentData。
使用ConvertToEntity组件,添加IConvertGameObjectToEntity接口,或者在组件上添加
[GenerateAuthoringComponent]
同一,但是使用代码控制转换的时机,继承ConvertToSingleEntity,并覆盖awake,然后在手动调用.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20public class ConvertToSingleEntity : ConvertToEntity
{
void Awake()
{
}
}
//实际上就是ConvertToEntity中的代码
public static void ConvertGameObejct(World dstWorld, GameObject gameObject)
{
var system = World.DefaultGameObjectInjectionWorld.GetOrCreateSystem<ConvertToEntitySystem>();
var convert = gameObject.GetComponent<ConvertToEntity>();
if (convert == null)
{
return ;
}
system.AddToBeConverted(dstWorld, convert);
}使用IDeclareReferencedPrefabs.声明实体的prefab,然后进行存储,以便进行之后的实例化
对于转换世界中的每个游戏对象,在任何转换系统运行之前,都会在目标世界中自动创建一个主要实体。随后可以通过 GameObjectConversionSystem.GetPrimaryEntity 访问与 GameObject 关联的实体。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51/*
*
*
if (m_Prefab == Entity.Null)
{
var prefabEntity = GetSingletonEntity<GamePrefabCollectionComponent>();
var prefabs = GetBuffer<GamePrefabBuffer>(prefabEntity);
for (int i = 0; i < prefabs.Length; ++i)
{
if (HasComponent<Player.State>(prefabs[i].Value))
m_Prefab = prefabs[i].Value;
}
}
*
*
* 添加进来的prefab不需要添加convert to entity
* 可以用单例获取GamePrefabCollectionComponent,然后获取想要的entity
*
*/
public class GameDeclareReferencedPrefabs : MonoBehaviour, IConvertGameObjectToEntity, IDeclareReferencedPrefabs
{
public List<GameObject> Prefabs = new List<GameObject>();
public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
{
dstManager.AddComponentData(entity, default(GamePrefabCollectionComponent));
var prefabs = dstManager.AddBuffer<GamePrefabBuffer>(entity);
foreach (var prefab in Prefabs)
{
var prefabEnt = conversionSystem.GetPrimaryEntity(prefab);
if (dstManager.Exists(prefabEnt))
prefabs.Add(new GamePrefabBuffer { Value = prefabEnt });
else
Debug.LogError($"The prefab {prefab.name} in the ghost collection was no converted to an entity, skipping it");
}
}
public void DeclareReferencedPrefabs(List<GameObject> referencedPrefabs)
{
foreach (var prefab in Prefabs)
{
if(prefab == null)
{
continue;
}
referencedPrefabs.Add(prefab);
}
}
}4.从转换系统中根据component获取实体,和上面类似..因为转换子物体的时候,转换系统中会生成实体,这个时候可以使用组件从conversionSystem中获取,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34public static void AddAbilityComponents(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem, AbilityAuthoring[] abilities)
{
dstManager.AddComponentData(entity, new AbilityCollection.State());
// Create ability entities
var abilityEntities = new List<Entity>(abilities.Length);
for (int i = 0; i < abilities.Length; i++)
{
var e = conversionSystem.GetEntities(abilities[i]);
e.MoveNext();
var abilityEntity = e.Current;
if (abilityEntities.Contains(abilityEntity))
{
GameDebug.LogError("Ability " + abilities[i] + " registered multiple times in abilities list");
}
abilityEntities.Add(abilityEntity);
}
// Add abilities to ability buffer
dstManager.AddBuffer<AbilityCollection.AbilityEntry>(entity);
var abilityBuffer = dstManager.GetBuffer<AbilityCollection.AbilityEntry>(entity);
for (int i = 0; i < abilities.Length; i++)
{
abilityBuffer.Add(new AbilityCollection.AbilityEntry
{
entity = abilityEntities[i],
abilityType = abilities[i].abilityTypeFlags,
canRunWith = abilities[i].canRunWithFlags,
canInterrupt = abilities[i].canInterruptFlags,
});
}
}5.手动转换gameobject,他的代码和
ConvertToEntitySystem
的代码差不多.会创建一个ConversionWorld,然后进行转换,都是使用了GameObjectConversionUtility.Convert
工作1
2
3
4
5
6
7
8
9
10
11public static Entity ConvertGameObjectPrefab(GameObject go,World dstWorld,out BlobAssetStore blob)
{
Entity returnEntity = Entity.Null;
blob = new BlobAssetStore();
returnEntity =
GameObjectConversionUtility.ConvertGameObjectHierarchy(go,GameObjectConversionSettings.FromWorld(dstWorld, blob));
return returnEntity;
}