protected override JobHandle OnUpdate(JobHandle jobHandle) { return(new ViewTransformJob() { SimTranslations = SimWorldAccessor.GetComponentDataFromEntity <Translation>() }.Schedule(this, jobHandle)); }
protected override void OnCreate() { base.OnCreate(); _newSimEntitiesQ = SimWorldAccessor.CreateEntityQuery(ComponentType.ReadOnly <NewlyCreatedTag>(), ComponentType.ReadOnly <BlueprintId>()); _ecbSystem = World.GetOrCreateSystem <BeginPresentationEntityCommandBufferSystem>(); RequireSingletonForUpdate <BlobAssetReferenceComponent <ViewBindingSystemSettings> >(); }
protected override void OnCreate() { base.OnCreate(); World simWorld = World.GetOrCreateSystem <SimulationWorldSystem>().SimulationWorld; SimWorldAccessor = new SimWorldAccessor( simWorld: simWorld, beginViewSystem: World.GetOrCreateSystem <BeginViewSystem>(), someSimSystem: simWorld.GetExistingSystem <SimPreInitializationSystemGroup>()); // could be any system }
protected override void OnUpdate() { // todo optim: we should only update once per frame TransformAccessArray transforms = _viewTransformsQ.GetTransformAccessArray(); Dependency = new CopyTransforms { SimTranslations = SimWorldAccessor.GetComponentDataFromEntity <FixTranslation>(), SimRotations = SimWorldAccessor.GetComponentDataFromEntity <FixRotation>(), BindedSimEntities = _viewTransformsQ.ToComponentDataArrayAsync <BindedSimEntity>(Allocator.TempJob, out JobHandle dep), }.Schedule(transforms, dep);
private void DestroyDanglingViewEntities() { // Destroy view entities binded with non-existant sim entities var ecb = _ecb.CreateCommandBuffer(); var simEntities = SimWorldAccessor.GetComponentDataFromEntity <SimAssetId>(); Entities .WithReadOnly(simEntities) .ForEach((Entity viewEntity, in BindedSimEntity simEntity) => { if (!simEntities.HasComponent(simEntity)) { ecb.DestroyEntity(viewEntity); } }).Schedule(); }
protected override void OnUpdate() { Entities .WithName("UpdateViewEntityNames") .WithoutBurst() .WithChangeFilter <BindedSimEntity>() .ForEach((Entity viewEntity, in BindedSimEntity simEntity) => { if (simEntity.Index < SimWorldAccessor.EntityCapacity && SimWorldAccessor.Exists(simEntity)) { EntityManager.SetName(viewEntity, $"View_{SimWorldAccessor.GetName(simEntity)}"); } else { EntityManager.SetName(viewEntity, $"View_{(Entity)simEntity}(destroyed)"); } }).Run(); }
protected override void OnUpdate() { if (!SimAssetBankInstance.Ready) { return; } _simWorldReplaceVersion.Set(SimWorldAccessor.ReplaceVersion); _simWorldTickId.Set(SimWorldAccessor.ExpectedNewTickId); if (!_simWorldTickId.IsDirty && !_simWorldReplaceVersion.IsDirty) // only continue if sim has changed since last update { return; } _simWorldTickId.ClearDirty(); if (_simWorldReplaceVersion.ClearDirty()) // world replaced! { // update cached sim queries since world got replaced // NB: No need to dispose of these queries because the world gets disposed ... _updatedSimEntitiesQ = SimWorldAccessor.CreateEntityQuery(ComponentType.ReadOnly <SimAssetId>()); _updatedSimEntitiesQ.SetChangedVersionFilter(ComponentType.ReadOnly <SimAssetId>()); // Destroy all view DestroyAllViewEntities(); } else { // Destroy dangling view DestroyDanglingViewEntities(); } // update map UpdateSim2ViewMap(); // destroy then create view for entities that had their SimAssetId modified UpdateViewEntities(SimAssetBankInstance.GetJobLookup(), _updatedSimEntitiesQ); _updatedSimEntitiesQ.SetChangedFilterRequiredVersion(SimWorldAccessor.GlobalSystemVersion); _ecb.AddJobHandleForProducer(Dependency); }
Entity GetUnassignedSimPlayer() { using (EntityQuery query = SimWorldAccessor.CreateEntityQuery( ComponentType.ReadOnly <PlayerTag>(), ComponentType.ReadOnly <PersistentId>())) { using (NativeArray <Entity> simPlayers = query.ToEntityArray(Allocator.TempJob)) { foreach (Entity playerEntity in simPlayers) { if (PlayerHelpers.GetPlayerFromSimPlayer(playerEntity, SimWorldAccessor) == null) { return(playerEntity); } } } } return(Entity.Null); }
protected override JobHandle OnUpdate(JobHandle jobHandle) { //////////////////////////////////////////////////////////////////////////////////////// // Copy Rotation //////////////////////////////////////////////////////////////////////////////////////// ComponentDataFromEntity <FixRotation> simRotations = SimWorldAccessor.GetComponentDataFromEntity <FixRotation>(); var copyRotJobHandle = Entities .WithReadOnly(simRotations) .ForEach((ref Rotation rotation, in BindedSimEntity linkedSimEntity) => { if (simRotations.HasComponent(linkedSimEntity)) { fix rot = simRotations[linkedSimEntity].Value; rotation.Value = fixQuaternion.FromEuler(0, 0, rot).ToUnityQuat(); } }).Schedule(jobHandle); //////////////////////////////////////////////////////////////////////////////////////// // Copy Translation //////////////////////////////////////////////////////////////////////////////////////// ComponentDataFromEntity <FixTranslation> simTranslations = SimWorldAccessor.GetComponentDataFromEntity <FixTranslation>(); var copyTrJobHandle = Entities .WithReadOnly(simTranslations) .ForEach((ref Translation translation, in BindedSimEntity linkedSimEntity) => { if (simTranslations.HasComponent(linkedSimEntity)) { fix2 pos = simTranslations[linkedSimEntity].Value; translation.Value = new float3((float)pos.x, (float)pos.y, 0); } }).Schedule(jobHandle); return(JobHandle.CombineDependencies(copyRotJobHandle, copyTrJobHandle)); }
protected override void OnUpdate() { if (PlayerRepertoireSystem.Instance == null) { return; } // wait for level to be loaded before trying to spawn pawns, kinda hack ... if (!SimWorldAccessor.HasSingleton <GridInfo>()) { return; } _simTick.Set(SimWorldAccessor.ExpectedNewTickId); if (!_simTick.ClearDirty()) // makes sure we wait for sim update before sending new request { return; } // When we submit an input in the simulation, we have no guarantee that it will be processed in the next frame // This 'cooldown' mechanism ensures we don't ask for too many player creations if (_dontAskForPlayerCreateCooldownMap.Count > 0) { foreach (KeyValuePair <PlayerInfo, double> playerInCooldown in _dontAskForPlayerCreateCooldownMap) { if (playerInCooldown.Value < Time.ElapsedTime) { _dontAskForPlayerCreateCooldownMap.Remove(playerInCooldown.Key); break; } } } foreach (PlayerInfo playerInfo in PlayerRepertoireSystem.Instance.Players) { if (playerInfo.SimPlayerId == PersistentId.Invalid && AllowCreatePlayers) { Entity unassignedSimPlayer = GetUnassignedSimPlayer(); if (unassignedSimPlayer == Entity.Null) { // ask the simulation to create a new player // When we submit an input in the simulation, we have no guarantee that it will be processed in the next frame // This 'cooldown' mechanism ensures we don't ask for too many player creations if (!_dontAskForPlayerCreateCooldownMap.ContainsKey(playerInfo)) { SimWorldAccessor.SubmitInput(new SimInputPlayerCreate() { PlayerName = playerInfo.PlayerName }); _dontAskForPlayerCreateCooldownMap.Add(playerInfo, Time.ElapsedTime + 1); } } else { // assign the sim player to the player PersistentId simPlayerId = SimWorldAccessor.GetComponent <PersistentId>(unassignedSimPlayer); PlayerRepertoireMaster.Instance.AssignSimPlayerToPlayer(playerInfo.PlayerId, simPlayerId); } } } // Update Active Player State SimWorldAccessor.Entities .WithAll <PlayerTag>() .ForEach((Entity playerEntity, ref PersistentId playerID, ref Active isActive) => { PlayerInfo playerInfo = PlayerHelpers.GetPlayerFromSimPlayer(playerID); if (playerInfo != null && !isActive.Value) // player connected in game but not active in simulation { SimWorldAccessor.SubmitInput(new SimInputSetPlayerActive() { IsActive = true, PlayerID = playerID }); } else if (playerInfo == null && isActive.Value) // player disconnected but active in simulation { SimWorldAccessor.SubmitInput(new SimInputSetPlayerActive() { IsActive = false, PlayerID = playerID }); } }); }