public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) { var conversionTarget = GhostAuthoringConversion.GetConversionTarget(conversionSystem); if (conversionTarget == NetcodeConversionTarget.Undefined) { throw new InvalidOperationException( $"A ghost prefab can only be created in the client or server world, not {dstManager.World.Name}"); } var collection = default(GhostPrefabCollectionComponent); Type enableSystem = null; if (conversionTarget == NetcodeConversionTarget.Server) { enableSystem = FindComponentWithName($"Enable{NamePrefix}GhostSendSystemComponent"); if (enableSystem == null) { throw new InvalidOperationException($"Could not find Enable{NamePrefix}GhostSendSystemComponent, make sure the ghost collection is generated"); } var prefabList = new NativeList <GhostPrefabBuffer>(Allocator.Temp); foreach (var ghost in Ghosts) { if (ghost.prefab == null || !ghost.enabled) { continue; } var prefabEntity = GameObjectConversionUtility.ConvertGameObjectHierarchy(ghost.prefab.gameObject, conversionSystem.ForkSettings(1)); EnsurePrefab(prefabEntity, dstManager); prefabList.Add(new GhostPrefabBuffer { Value = prefabEntity }); } collection.serverPrefabs = conversionSystem.CreateAdditionalEntity(this); var prefabs = dstManager.AddBuffer <GhostPrefabBuffer>(collection.serverPrefabs); for (int i = 0; i < prefabList.Length; ++i) { prefabs.Add(prefabList[i]); } } else if (conversionTarget == NetcodeConversionTarget.Client) { enableSystem = FindComponentWithName($"Enable{NamePrefix}GhostReceiveSystemComponent"); if (enableSystem == null) { throw new InvalidOperationException($"Could not find Enable{NamePrefix}GhostReceiveSystemComponent, make sure the ghost collection is generated"); } var predictedList = new NativeList <GhostPrefabBuffer>(Allocator.Temp); var interpolatedList = new NativeList <GhostPrefabBuffer>(Allocator.Temp); foreach (var ghost in Ghosts) { if (ghost.prefab == null || !ghost.enabled) { continue; } var origInstantiate = ghost.prefab.DefaultClientInstantiationType; ghost.prefab.DefaultClientInstantiationType = GhostAuthoringComponent.ClientInstantionType.Interpolated; var prefabEntity = GameObjectConversionUtility.ConvertGameObjectHierarchy(ghost.prefab.gameObject, conversionSystem.ForkSettings(1)); ghost.prefab.DefaultClientInstantiationType = GhostAuthoringComponent.ClientInstantionType.Predicted; var predictedPrefabEntity = GameObjectConversionUtility.ConvertGameObjectHierarchy(ghost.prefab.gameObject, conversionSystem.ForkSettings(2)); ghost.prefab.DefaultClientInstantiationType = origInstantiate; EnsurePrefab(predictedPrefabEntity, dstManager); EnsurePrefab(prefabEntity, dstManager); predictedList.Add(new GhostPrefabBuffer { Value = predictedPrefabEntity }); interpolatedList.Add(new GhostPrefabBuffer { Value = prefabEntity }); } collection.clientInterpolatedPrefabs = conversionSystem.CreateAdditionalEntity(this); var interpolatedPrefabs = dstManager.AddBuffer <GhostPrefabBuffer>(collection.clientInterpolatedPrefabs); for (int i = 0; i < interpolatedList.Length; ++i) { interpolatedPrefabs.Add(interpolatedList[i]); } collection.clientPredictedPrefabs = conversionSystem.CreateAdditionalEntity(this); var predictedPrefabs = dstManager.AddBuffer <GhostPrefabBuffer>(collection.clientPredictedPrefabs); for (int i = 0; i < predictedList.Length; ++i) { predictedPrefabs.Add(predictedList[i]); } } dstManager.AddComponentData(entity, collection); if (enableSystem != null) { dstManager.AddComponent(entity, enableSystem); } }
public virtual void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) { // 客户端与服务端都需要注册序列化器. var collection = default(GhostPrefabCollectionComponent); var conversionTarget = GetConversionTarget(dstManager.World); // 查询出可用的Ghost预制体 _enabledGhosts = GetGhosts(); collection.ServerPrefabs = dstManager.CreateEntity(); var serverPrefabs = new NativeList <GhostPrefabBuffer>(Allocator.Temp); int ghostType = 0; foreach (var ghost in _enabledGhosts) { var orig = ghost.prefab.Type; Entity ent = GameObjectConversionUtility.ConvertGameObjectHierarchy(ghost.prefab.gameObject, conversionSystem.ForkSettings(1)); dstManager.SetComponentData(ent, new GhostComponent { GhostType = ghostType }); GhostPrefabType prefabType = orig == GhostAuthoringComponent.ClientInstanceType.Interpolated ? GhostPrefabType.InterpolatedClient : GhostPrefabType.PredictedClient; var ghostPrefab = new GhostPrefabBuffer { Value = ent, GhostType = ghostType, PrefabType = prefabType, IsOwner = orig == GhostAuthoringComponent.ClientInstanceType.OwnerPredicted && ghost.prefab.GetComponent <GhostOwnerAuthoringComponent>() }; NativeArray <ComponentType> componentTypes = dstManager.GetComponentTypes(ent); componentTypes.Dispose(); serverPrefabs.Add(ghostPrefab); ++ghostType; } dstManager.AddBuffer <GhostPrefabBuffer>(collection.ServerPrefabs).AddRange(serverPrefabs); serverPrefabs.Dispose(); //======================================================================================================= // 普通的预制体转换后的Entity PrefabCollectionSystem prefabCollectionSystem = dstManager.World.GetOrCreateSystem <PrefabCollectionSystem>(); prefabCollectionSystem.Prefabs = new NativeArray <PrefabItem>(this.ghostCollectionConfig.Prefabs.Count, Allocator.Persistent); for (int i = 0; i < this.ghostCollectionConfig.Prefabs.Count; i++) { Entity ent = conversionSystem.GetPrimaryEntity(ghostCollectionConfig.Prefabs[i]); var item = new PrefabItem { Value = ent, Type = i }; prefabCollectionSystem.Prefabs[i] = item; } // Debug.Log($"转换Prefabs: {prefabCollectionSystem.Prefabs.Length}"); //======================================================================================================= if (conversionTarget == TargetWorld.Client) { ghostType = 0; collection.ClientInterpolatedPrefabs = dstManager.CreateEntity(); collection.ClientPredictedPrefabs = dstManager.CreateEntity(); var predictedList = new NativeList <GhostPrefabBuffer>(Allocator.Temp); var interpolatedList = new NativeList <GhostPrefabBuffer>(Allocator.Temp); foreach (var ghost in _enabledGhosts) { var orig = ghost.prefab.Type; ghost.prefab.Type = GhostAuthoringComponent.ClientInstanceType.Interpolated; Entity interpolatedEnt = GameObjectConversionUtility.ConvertGameObjectHierarchy(ghost.prefab.gameObject, conversionSystem.ForkSettings(2)); dstManager.SetComponentData(interpolatedEnt, new GhostComponent { GhostType = ghostType }); interpolatedList.Add(new GhostPrefabBuffer { Value = interpolatedEnt, GhostType = ghostType, PrefabType = GhostPrefabType.InterpolatedClient }); ghost.prefab.Type = GhostAuthoringComponent.ClientInstanceType.Predicted; Entity predictedEnt = GameObjectConversionUtility.ConvertGameObjectHierarchy(ghost.prefab.gameObject, conversionSystem.ForkSettings(2)); dstManager.SetComponentData(predictedEnt, new GhostComponent { GhostType = ghostType }); predictedList.Add(new GhostPrefabBuffer { Value = predictedEnt, GhostType = ghostType, PrefabType = GhostPrefabType.PredictedClient }); ghost.prefab.Type = orig; ++ghostType; } dstManager.AddBuffer <GhostPrefabBuffer>(collection.ClientPredictedPrefabs).AddRange(predictedList); dstManager.AddBuffer <GhostPrefabBuffer>(collection.ClientInterpolatedPrefabs) .AddRange(interpolatedList); predictedList.Dispose(); interpolatedList.Dispose(); } dstManager.AddComponentData(entity, collection); }