コード例 #1
0
    public void NativeMultiHashMap_CountValuesForKey()
    {
        var hashMap = new NativeMultiHashMap <int, int> (1, Allocator.Temp);

        hashMap.Add(5, 7);
        hashMap.Add(6, 9);
        hashMap.Add(6, 10);

        Assert.AreEqual(1, hashMap.CountValuesForKey(5));
        Assert.AreEqual(2, hashMap.CountValuesForKey(6));
        Assert.AreEqual(0, hashMap.CountValuesForKey(7));

        hashMap.Dispose();
    }
コード例 #2
0
        /// <summary>
        /// Update the store with the recorded BlobAsset/UnityObject associations.
        /// </summary>
        /// <remarks>
        /// User don't have to call this method because <see cref="Dispose"/> will do it.
        /// This method can be called multiple times, on the first one will matter.
        /// </remarks>
        public void UpdateBlobStore()
        {
            var keys = m_BlobPerUnityObject.GetUniqueKeyArray(Allocator.Temp);

            using (keys.Item1)
            {
                for (var k = 0; k < keys.Item2; ++k)
                {
                    var key        = keys.Item1[k];
                    var valueCount = m_BlobPerUnityObject.CountValuesForKey(key);
                    var valueArray = new NativeArray <Hash128>(valueCount, Allocator.Temp);
                    var i          = 0;
                    if (m_BlobPerUnityObject.TryGetFirstValue(key, out var value, out var iterator))
                    {
                        do
                        {
                            valueArray[i++] = value;
                        }while (m_BlobPerUnityObject.TryGetNextValue(out value, ref iterator));

                        valueArray.Sort();
                    }

                    m_BlobAssetStore.UpdateBlobAssetForUnityObject <TB>(key, valueArray);
                    valueArray.Dispose();
                }
            }

            m_BlobPerUnityObject.Clear();
        }
コード例 #3
0
 public bool HasVehicleInSegment(
     NativeMultiHashMap <Entity, VehicleSegmentData> vehicleSegmentMap,
     Entity segmentEntity
     )
 {
     return(vehicleSegmentMap.CountValuesForKey(segmentEntity) > 0);
 }
コード例 #4
0
        public static NativeArray <CollisionTriggerData>?CollectCollisionTriggerData(int frame, ref NativeMultiHashMap <Entity, CollisionTriggerData> nativeMultiHashMap, Entity e)
        {
            var count = nativeMultiHashMap.CountValuesForKey(e);
            NativeArray <CollisionTriggerData> collisions = new NativeArray <CollisionTriggerData>(count, Allocator.Temp);
            int idx = 0;

            if (nativeMultiHashMap.TryGetFirstValue(e, out var collInfo1, out var it))
            {
                do
                {
                    if (collInfo1.Frame < frame)
                    {
                        collInfo1.State = CollisionState.Exit;
                        nativeMultiHashMap.Remove(it);
                    }
                    else if (collInfo1.Frame == frame)
                    {
                        // MBRIAU: What are we trying to clean up here?
                        collInfo1.State = collInfo1.State == CollisionState.Stay ? CollisionState.Stay : CollisionState.Enter;
                    }
                    collisions[idx++] = collInfo1;
                }while (nativeMultiHashMap.TryGetNextValue(out collInfo1, ref it));
            }

            return(collisions);
        }
コード例 #5
0
 private static int GetSubSceneCount(Scene gameObjectScene)
 {
     if (!SubSceneLookup.IsCreated)
     {
         return(0);
     }
     return(SubSceneLookup.CountValuesForKey(gameObjectScene.handle));
 }
コード例 #6
0
        internal void CreateCollider(Entity rigidbodyEntity)
        {
            var colliderCount = RigidbodyToColliderMapping.CountValuesForKey(rigidbodyEntity);

            if (colliderCount == 0)
            {
                return;
            }

            // Single collider doesn't require a compound collider.
            if (colliderCount == 1)
            {
                var foundColliderBlob = RigidbodyToColliderMapping.TryGetFirstValue(rigidbodyEntity, out BlobAssetReference <Collider> colliderBlob, out NativeMultiHashMapIterator <Entity> ignore);
                SafetyChecks.IsTrue(foundColliderBlob);

                // Add the single collider to the rigidbody entity.
                DstEntityManager.AddComponentData(rigidbodyEntity, new PhysicsColliderBlob {
                    Collider = colliderBlob
                });

                return;
            }

            // Multiple colliders required a compound collider.
            var childrenArray = new NativeArray <PhysicsCompoundCollider.ColliderBlobInstance>(colliderCount, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
            var childIndex    = 0;

            foreach (var colliderBlob in RigidbodyToColliderMapping.GetValuesForKey(rigidbodyEntity))
            {
                childrenArray[childIndex++] = new PhysicsCompoundCollider.ColliderBlobInstance
                {
                    Collider = colliderBlob,
                    // NOTE: Right now the relative pose of the collider with respect to the rigidbody is baked into the shape.
                    // Later, we'll want to remove that and only have its offset (if any) baked into it and use this transform instead.
                    CompoundFromChild = PhysicsTransform.Identity
                };
            }

            // Create the compound collider.
            DstEntityManager.AddComponentData(rigidbodyEntity, new PhysicsColliderBlob {
                Collider = PhysicsCompoundCollider.Create(childrenArray)
            });

            // We've finished with the children blobs and array.
            for (var i = 0; i < colliderCount; ++i)
            {
                childrenArray[i].Collider.Dispose();
            }
            childrenArray.Dispose();
        }
コード例 #7
0
        public void Execute()
        {
            for (int i = 0; i < meshSlices.Length; i++)
            {
                var meshData   = meshes[i];
                var vertexData = meshData.GetVertexData <TVertex>();
                vertexData.CopyFrom(vertices.GetSubArray(meshSlices[i].startVertex, meshSlices[i].vertexLength));
                var indexData = meshData.GetIndexData <int>();
                indexData.CopyFrom(indices.GetSubArray(meshSlices[i].startIndex, meshSlices[i].indexLength));

                meshData.subMeshCount = subMeshes.CountValuesForKey(i) + 1;
                foreach (var subMesh in subMeshes.GetValuesForKey(i))
                {
                    meshes[i].SetSubMesh(subMesh.index, new SubMeshDescriptor(subMesh.start, subMesh.length, subMesh.topology));
                }
            }
        }
コード例 #8
0
            // パーティクル連動頂点ごと
            public void Execute(int index)
            {
                int vindex = vertexToParticleList[index];

                if (vindex < 0)
                {
                    return;
                }

                int pindex;

                //#if !UNITY_2018_4
#if false
                // v1.5.2
                // こちらのクォータニオン補間の方が安全
                int cnt = vertexToParticleMap.CountValuesForKey(vindex);
                if (cnt > 0)
                {
                    if (vertexToParticleMap.TryGetFirstValue(vindex, out pindex, out iterator))
                    {
                        float3     pos    = particlePosList[pindex];
                        quaternion rot    = particleRotList[pindex];
                        var        flag   = particleFlagList[pindex];
                        int        fixcnt = flag.IsKinematic() ? 1 : 0;
                        float      ratio  = 1.0f / cnt;

                        while (vertexToParticleMap.TryGetNextValue(out pindex, ref iterator))
                        {
                            float3     ppos = particlePosList[pindex];
                            quaternion prot = particleRotList[pindex];
                            flag = particleFlagList[pindex];

                            pos    += ppos;
                            rot     = math.slerp(rot, prot, ratio);
                            fixcnt += flag.IsKinematic() ? 1 : 0;
                        }
                        pos = pos / cnt;

                        virtualPosList[vindex] = pos;
                        virtualRotList[vindex] = rot;

                        // 仮想メッシュの法線/接線計算フラグ
                        //virtualVertexFlagList[vindex] = 1;
                        byte vflag = (byte)(PhysicsManagerMeshData.VirtualVertexFlag_Use
                                            | (fixcnt > 0 ? PhysicsManagerMeshData.VirtualVertexFlag_Fix : 0x0));
                        //virtualVertexFlagList[vindex] = (byte)(fixcnt == cnt ? 0 : 1);
                        virtualVertexFlagList[vindex] = vflag;
                    }
                }
#else
                if (vertexToParticleMap.TryGetFirstValue(vindex, out pindex, out iterator))
                {
                    float3 pos = 0;
                    float3 nor = 0;
                    float3 tan = 0;
                    int    cnt = 0;
                    do
                    {
                        // particle
                        var flag = particleFlagList[pindex];

                        // 固定パーティクルかつ固定は回転しない設定ならば打ち切る(v1.5.2)
                        if (flag.IsKinematic())
                        {
                            var team = teamDataList[teamIdList[pindex]];
                            if (team.IsFlag(PhysicsManagerTeamData.Flag_FixedNonRotation))
                            {
                                // 1つでも当てはまれば打ち切る
                                return;
                            }
                        }

                        float3     ppos = particlePosList[pindex];
                        quaternion prot = particleRotList[pindex];

                        pos += ppos;
                        nor += math.mul(prot, new float3(0, 0, 1));
                        tan += math.mul(prot, new float3(0, 1, 0));
                        cnt++;
                    }while (vertexToParticleMap.TryGetNextValue(out pindex, ref iterator));

                    if (cnt > 0)
                    {
                        pos = pos / cnt;
                        nor = math.normalize(nor);
                        tan = math.normalize(tan);

                        virtualPosList[vindex] = pos;
                        virtualRotList[vindex] = quaternion.LookRotation(nor, tan);

                        // 仮想メッシュの法線/接線計算フラグ
                        virtualVertexFlagList[vindex] = PhysicsManagerMeshData.VirtualVertexFlag_Use;
                    }
                }
#endif
            }
コード例 #9
0
ファイル: BlobAssetStore.cs プロジェクト: isaveu/SimpleUIDemo
        internal void UpdateBlobAssetForGameObject <TB>(int ownerId, NativeArray <Hash128> newBlobHashes) where TB : struct
        {
            var leftLength = newBlobHashes.Length;
            var toInc      = new NativeArray <Hash128>(leftLength, Allocator.Temp);
            var toDec      = new NativeArray <Hash128>(m_HashByOwner.CountValuesForKey(ownerId), Allocator.Temp);

            var curLeftIndex = 0;
            var curIncIndex  = 0;
            var curDecIndex  = 0;

            var leftRes  = curLeftIndex < leftLength;
            var rightRes = m_HashByOwner.TryGetFirstValue(ownerId, out var rightHash, out var it);

            var maxHash = new Hash128(UInt32.MaxValue, UInt32.MaxValue, UInt32.MaxValue, UInt32.MaxValue);

            // We will parse newBlobHashes, considered the left part and the store hashes for this ownerId, considered the right part
            //  in order to build a list of BlobAssets to increment (the ones only present in left part) and the ones to decrement
            //  (only present in the right part). If a hash is present on both side, we do not change its RefCounter
            do
            {
                var leftHash = leftRes ? newBlobHashes[curLeftIndex] : maxHash;
                rightHash = rightRes ? rightHash : maxHash;

                // Both side equal? We are synchronized, step next for both sides
                if (rightHash == leftHash)
                {
                    leftRes  = ++curLeftIndex < leftLength;
                    rightRes = m_HashByOwner.TryGetNextValue(out rightHash, ref it);
                    continue;
                }

                // More items on the left, add them to the "toAdd" list
                if (leftHash < rightHash)
                {
                    do
                    {
                        // Get left hash
                        leftHash = newBlobHashes[curLeftIndex++];

                        // Add to "toInc"
                        toInc[curIncIndex++] = leftHash;

                        // Check if there's more left item
                        leftRes = curLeftIndex < leftLength;
                    } while (leftRes && (leftHash < rightHash));
                }

                // More items on the right, add them to the "toRemove" list
                else
                {
                    do
                    {
                        // Add to "toDec"
                        toDec[curDecIndex++] = rightHash;

                        // Get next right item
                        rightRes = m_HashByOwner.TryGetNextValue(out rightHash, ref it);
                    } while (rightRes && leftHash > rightHash);
                }
            } while (leftRes || rightRes);

            // Increment each hash in "toInc" if they exist, add them to the RefCounter hash if they are new
            for (int i = 0; i < curIncIndex; i++)
            {
                var hash = toInc[i];
                if (m_RefCounterPerBlobHash.TryGetValue(hash, out var counter))
                {
                    m_RefCounterPerBlobHash[hash] = counter + 1;
                }
                else
                {
                    m_RefCounterPerBlobHash.Add(hash, 1);
                }
            }

            // Decrement each hash in "toDec", remove the BlobAsset if it reaches 0
            for (int i = 0; i < curDecIndex; i++)
            {
                // Decrement the hash of the previously assigned Blob Asset
                var hash         = toDec[i];
                var oldHashCount = --m_RefCounterPerBlobHash[hash];

                // If it reaches 0, we dispose the Blob Asset and remove the counter
                if (oldHashCount == 0)
                {
                    Remove <TB>(hash, true);
                    m_RefCounterPerBlobHash.Remove(hash);
                }
            }

            // Clear the former list of BlobAsset hashes and replace by the new one
            m_HashByOwner.Remove(ownerId);

            for (int i = 0; i < leftLength; i++)
            {
                m_HashByOwner.Add(ownerId, newBlobHashes[i]);
            }
        }
コード例 #10
0
    protected override unsafe void OnUpdate()
    {
        var preSpawnsAlreadyProcessed = EntityManager.CreateEntityQuery(ComponentType.ReadOnly <PreSpawnsInitialized>())
                                        .CalculateEntityCount();

        if (preSpawnsAlreadyProcessed > 0)
        {
            // Check if an uninitialized scene has appeared with no ghosts present inside, then just mark it as initialized and continue
            var prespawns = m_Prespawns.ToEntityArray(Allocator.TempJob);
            var newScenes = m_UninitializedScenes.ToEntityArray(Allocator.TempJob);
            for (int j = 0; j < newScenes.Length; ++j)
            {
                for (int i = 0; i < prespawns.Length; ++i)
                {
                    var scenes      = EntityManager.GetSharedComponentData <SceneSection>(prespawns[i]);
                    var sceneSystem = World.GetExistingSystem <SceneSystem>();
                    var sceneEntity = sceneSystem.GetSceneEntity(scenes.SceneGUID);
                    if (sceneEntity == newScenes[j])
                    {
                        UnityEngine.Debug.LogError("[" + World.Name +
                                                   "] Prespawned ghosts have already been initialized, this needs to happen for all subscenes at the same time.");
                        return;
                    }
                }
                EntityManager.AddComponent <PreSpawnsInitialized>(newScenes[j]);
            }
            newScenes.Dispose();
            prespawns.Dispose();
            return;
        }

        // Handle the chunk for an entity type, then handle each entity in the chunk (prespawned entities)
        var prespawnChunk   = m_Prespawns.CreateArchetypeChunkArray(Allocator.TempJob);
        var entityType      = GetEntityTypeHandle();
        var preSpawnedIds   = GetComponentDataFromEntity <PreSpawnedGhostId>();
        var subsceneMap     = new NativeMultiHashMap <ulong, Entity>(32, Allocator.Temp);
        var subscenePadding = new NativeHashMap <ulong, int>(32, Allocator.Temp);
        var ghostComponents = GetComponentDataFromEntity <GhostComponent>();

        // Put all known subscene hashes tracked by the prespawned ghosts into a map for sorting
        for (int i = 0; i < prespawnChunk.Length; ++i)
        {
            var chunk    = prespawnChunk[i];
            var entities = chunk.GetNativeArray(entityType);
            for (int j = 0; j < entities.Length; ++j)
            {
                var entity       = entities[j];
                var subsceneHash = EntityManager.GetSharedComponentData <SubSceneGhostComponentHash>(entity).Value;
                subsceneMap.Add(subsceneHash, entity);
            }
        }

        var subsceneArray = subsceneMap.GetUniqueKeyArray(Allocator.Temp);

        // Figure out scene id padding or how many IDs were used by the previous scenes in the sorted list, continue
        // where it left off so each ghost in a scene starts of at the ID+1 of last ghost in the previous scene
        var scenePadding = 0;

        for (int i = 0; i < subsceneArray.Item2; ++i)
        {
            subscenePadding.Add(subsceneArray.Item1[i], scenePadding);
            scenePadding += subsceneMap.CountValuesForKey(subsceneArray.Item1[i]);
        }

        var PostUpdateCommands          = new EntityCommandBuffer(Allocator.Temp);
        var serverSystems               = World.GetExistingSystem <ServerSimulationSystemGroup>();
        var ghostTypes                  = GetComponentDataFromEntity <GhostTypeComponent>();
        var ghostPrefabBufferFromEntity = GetBufferFromEntity <GhostPrefabBuffer>(true);
        var prefabEntity                = GetSingletonEntity <GhostPrefabCollectionComponent>();
        var ghostReceiveSystem          = World.GetExistingSystem <GhostReceiveSystem>();
        var ghostSendSystem             = World.GetExistingSystem <GhostSendSystem>();
        var ghostCollectionSystem       = World.GetExistingSystem <GhostCollectionSystem>();
        DynamicBuffer <GhostPrefabBuffer> prefabList = ghostPrefabBufferFromEntity[prefabEntity];
        int highestPrespawnId = -1;
        var spawnedGhosts     = new NativeList <SpawnedGhostMapping>(1024, Allocator.Temp);

        for (int i = 0; i < prespawnChunk.Length; ++i)
        {
            var chunk    = prespawnChunk[i];
            var entities = chunk.GetNativeArray(entityType);

            for (int j = 0; j < entities.Length; ++j)
            {
                var entity = entities[j];

                var ghostTypeComponent = ghostTypes[entity];
                int ghostType;
                for (ghostType = 0; ghostType < prefabList.Length; ++ghostType)
                {
                    if (ghostTypes[prefabList[ghostType].Value] == ghostTypeComponent)
                    {
                        break;
                    }
                }
                if (ghostType >= prefabList.Length)
                {
                    UnityEngine.Debug.LogError("Failed to look up ghost type for entity");
                    return;
                }

                // Check if this entity has already been handled
                if (ghostComponents[entity].ghostId != 0)
                {
                    UnityEngine.Debug.LogWarning(entity + " already has ghostId=" + ghostComponents[entity].ghostId + " prespawn=" + preSpawnedIds[entity].Value);
                    continue;
                }

                // Modfy the entity to its proper version
                if (EntityManager.HasComponent <GhostPrefabMetaDataComponent>(prefabList[ghostType].Value))
                {
                    ref var ghostMetaData = ref EntityManager.GetComponentData <GhostPrefabMetaDataComponent>(prefabList[ghostType].Value).Value.Value;
                    if (serverSystems != null)
                    {
                        for (int rm = 0; rm < ghostMetaData.RemoveOnServer.Length; ++rm)
                        {
                            var rmCompType = ComponentType.ReadWrite(TypeManager.GetTypeIndexFromStableTypeHash(ghostMetaData.RemoveOnServer[rm]));
                            PostUpdateCommands.RemoveComponent(entity, rmCompType);
                        }
                    }
                    else
                    {
                        for (int rm = 0; rm < ghostMetaData.RemoveOnClient.Length; ++rm)
                        {
                            var rmCompType = ComponentType.ReadWrite(TypeManager.GetTypeIndexFromStableTypeHash(ghostMetaData.RemoveOnClient[rm]));
                            PostUpdateCommands.RemoveComponent(entity, rmCompType);
                        }
                        // FIXME: should disable instead of removing once we have a way of doing that without structural changes
                        if (ghostMetaData.DefaultMode == GhostPrefabMetaData.GhostMode.Predicted)
                        {
                            for (int rm = 0; rm < ghostMetaData.DisableOnPredictedClient.Length; ++rm)
                            {
                                var rmCompType = ComponentType.ReadWrite(TypeManager.GetTypeIndexFromStableTypeHash(ghostMetaData.DisableOnPredictedClient[rm]));
                                PostUpdateCommands.RemoveComponent(entity, rmCompType);
                            }
                        }
                        else if (ghostMetaData.DefaultMode == GhostPrefabMetaData.GhostMode.Interpolated)
                        {
                            for (int rm = 0; rm < ghostMetaData.DisableOnInterpolatedClient.Length; ++rm)
                            {
                                var rmCompType = ComponentType.ReadWrite(TypeManager.GetTypeIndexFromStableTypeHash(ghostMetaData.DisableOnInterpolatedClient[rm]));
                                PostUpdateCommands.RemoveComponent(entity, rmCompType);
                            }
                        }
                    }
                }

                var subsceneHash = EntityManager.GetSharedComponentData <SubSceneGhostComponentHash>(entity).Value;
                var newId        = preSpawnedIds[entity].Value + subscenePadding[subsceneHash];
                if (newId > highestPrespawnId)
                {
                    highestPrespawnId = newId;
                }

                // If on a server we need to allocate the ghost ID for the pre-spawned entity so runtime spawns
                // will happen from the right start index
                if (serverSystems != null)
                {
                    spawnedGhosts.Add(new SpawnedGhostMapping {
                        ghost = new SpawnedGhost {
                            ghostId = newId, spawnTick = 0
                        }, entity = entity
                    });
                    var ghostSystemStateComponent = new GhostSystemStateComponent
                    {
                        ghostId = newId, despawnTick = 0, spawnTick = 0
                    };
                    PostUpdateCommands.AddComponent(entity, ghostSystemStateComponent);
                }
                else if (ghostReceiveSystem != null)
                {
                    var snapshotSize = ghostCollectionSystem.m_GhostTypeCollection[ghostType].SnapshotSize;
                    spawnedGhosts.Add(new SpawnedGhostMapping {
                        ghost = new SpawnedGhost {
                            ghostId = newId, spawnTick = 0
                        }, entity = entity
                    });
                    var newBuffer = PostUpdateCommands.SetBuffer <SnapshotDataBuffer>(entity);
                    newBuffer.ResizeUninitialized(snapshotSize * GhostSystemConstants.SnapshotHistorySize);
                    UnsafeUtility.MemClear(newBuffer.GetUnsafePtr(), snapshotSize * GhostSystemConstants.SnapshotHistorySize);
                    PostUpdateCommands.SetComponent(entity, new SnapshotData {
                        SnapshotSize = snapshotSize, LatestIndex = 0
                    });
                }

                // Pre-spawned uses spawnTick = 0, if there is a reference to a ghost and it has spawnTick 0 the ref is always resolved
                // This works because there despawns are high priority and we never create pre-spawned ghosts after connection
                var ghostComponent = new GhostComponent {
                    ghostId = newId, ghostType = ghostType, spawnTick = 0
                };
                PostUpdateCommands.SetComponent(entity, ghostComponent);

                // Mark scene as processed, as whole scene will have been loaded when this entity appeared
                var sceneSection = EntityManager.GetSharedComponentData <SceneSection>(entity);
                var sceneSystem  = World.GetExistingSystem <SceneSystem>();
                var sceneEntity  = sceneSystem.GetSceneEntity(sceneSection.SceneGUID);
                PostUpdateCommands.AddComponent <PreSpawnsInitialized>(sceneEntity);
            }
        }
コード例 #11
0
    protected override unsafe void OnUpdate()
    {
        var preSpawnsAlreadyProcessed = EntityManager.CreateEntityQuery(ComponentType.ReadOnly <PreSpawnsInitialized>())
                                        .CalculateEntityCount();

        if (preSpawnsAlreadyProcessed > 0)
        {
            // Check if an uninitialized scene has appeared with no ghosts present inside, then just mark it as initialized and continue
            var prespawns = m_Prespawns.ToEntityArray(Allocator.TempJob);
            var newScenes = m_UninitializedScenes.ToEntityArray(Allocator.TempJob);
            for (int j = 0; j < newScenes.Length; ++j)
            {
                for (int i = 0; i < prespawns.Length; ++i)
                {
                    var scenes      = EntityManager.GetSharedComponentData <SceneSection>(prespawns[i]);
                    var sceneSystem = World.GetExistingSystem <SceneSystem>();
                    var sceneEntity = sceneSystem.GetSceneEntity(scenes.SceneGUID);
                    if (sceneEntity == newScenes[j])
                    {
                        UnityEngine.Debug.LogError("[" + World.Name +
                                                   "] Prespawned ghosts have already been initialized, this needs to happen for all subscenes at the same time.");
                        return;
                    }
                }
                EntityManager.AddComponent <PreSpawnsInitialized>(newScenes[j]);
            }
            newScenes.Dispose();
            prespawns.Dispose();
            return;
        }

        // Handle the chunk for an entity type, then handle each entity in the chunk (prespawned entities)
        var prespawnChunk   = m_Prespawns.CreateArchetypeChunkArray(Allocator.TempJob);
        var entityType      = GetEntityTypeHandle();
        var preSpawnedIds   = GetComponentDataFromEntity <PreSpawnedGhostId>();
        var subsceneMap     = new NativeMultiHashMap <ulong, Entity>(32, Allocator.Temp);
        var subscenePadding = new NativeHashMap <ulong, int>(32, Allocator.Temp);
        var ghostComponents = GetComponentDataFromEntity <GhostComponent>();

        // Put all known subscene hashes tracked by the prespawned ghosts into a map for sorting
        for (int i = 0; i < prespawnChunk.Length; ++i)
        {
            var chunk    = prespawnChunk[i];
            var entities = chunk.GetNativeArray(entityType);
            for (int j = 0; j < entities.Length; ++j)
            {
                var entity       = entities[j];
                var subsceneHash = EntityManager.GetSharedComponentData <SubSceneGhostComponentHash>(entity).Value;
                subsceneMap.Add(subsceneHash, entity);
            }
        }

        var subsceneArray = subsceneMap.GetUniqueKeyArray(Allocator.Temp);

        // Figure out scene id padding or how many IDs were used by the previous scenes in the sorted list, continue
        // where it left off so each ghost in a scene starts of at the ID+1 of last ghost in the previous scene
        var scenePadding = 0;

        for (int i = 0; i < subsceneArray.Item2; ++i)
        {
            subscenePadding.Add(subsceneArray.Item1[i], scenePadding);
            scenePadding += subsceneMap.CountValuesForKey(subsceneArray.Item1[i]);
        }

        var PostUpdateCommands  = new EntityCommandBuffer(Allocator.Temp);
        var serverSystems       = World.GetExistingSystem <ServerSimulationSystemGroup>();
        var ghostTypes          = GetComponentDataFromEntity <GhostTypeComponent>();
        var ghostReceiveSystem  = World.GetExistingSystem <GhostReceiveSystem>();
        var ghostSendSystem     = World.GetExistingSystem <GhostSendSystem>();
        var ghostTypeCollection = EntityManager.GetBuffer <GhostCollectionPrefabSerializer>(GetSingletonEntity <GhostCollection>());
        int highestPrespawnId   = -1;
        var spawnedGhosts       = new NativeList <SpawnedGhostMapping>(1024, Allocator.Temp);

        // Create a lookup from ghost type component to prefab entity, used to figure out how to strip components on the client
        var prefabFromType = new NativeHashMap <GhostTypeComponent, Entity>(1024, Allocator.Temp);

        Entities.WithNone <GhostPrefabRuntimeStrip>().WithAll <Prefab>().ForEach((Entity ent, in GhostTypeComponent ghostType) =>
        {
            prefabFromType.TryAdd(ghostType, ent);
        }).Run();

        for (int i = 0; i < prespawnChunk.Length; ++i)
        {
            var chunk    = prespawnChunk[i];
            var entities = chunk.GetNativeArray(entityType);

            for (int j = 0; j < entities.Length; ++j)
            {
                var entity = entities[j];

                var ghostTypeComponent = ghostTypes[entity];
                if (!prefabFromType.TryGetValue(ghostTypeComponent, out var ghostPrefabEntity))
                {
                    UnityEngine.Debug.LogError("Failed to look up ghost type for entity");
                    return;
                }

                // Check if this entity has already been handled
                if (ghostComponents[entity].ghostId != 0)
                {
                    UnityEngine.Debug.LogWarning(entity + " already has ghostId=" + ghostComponents[entity].ghostId + " prespawn=" + preSpawnedIds[entity].Value);
                    continue;
                }

                // Modfy the entity to its proper version
                if (EntityManager.HasComponent <GhostPrefabMetaDataComponent>(ghostPrefabEntity))
                {
                    ref var ghostMetaData     = ref EntityManager.GetComponentData <GhostPrefabMetaDataComponent>(ghostPrefabEntity).Value.Value;
                    var     linkedEntityGroup = EntityManager.GetBuffer <LinkedEntityGroup>(entity);
                    if (serverSystems != null)
                    {
                        for (int rm = 0; rm < ghostMetaData.RemoveOnServer.Length; ++rm)
                        {
                            var childIndexCompHashPair = ghostMetaData.RemoveOnServer[rm];
                            var rmCompType             = ComponentType.ReadWrite(TypeManager.GetTypeIndexFromStableTypeHash(childIndexCompHashPair.StableHash));
                            PostUpdateCommands.RemoveComponent(linkedEntityGroup[childIndexCompHashPair.EntityIndex].Value, rmCompType);
                        }
                    }
                    else
                    {
                        for (int rm = 0; rm < ghostMetaData.RemoveOnClient.Length; ++rm)
                        {
                            var childIndexCompHashPair = ghostMetaData.RemoveOnClient[rm];
                            var rmCompType             = ComponentType.ReadWrite(TypeManager.GetTypeIndexFromStableTypeHash(childIndexCompHashPair.StableHash));
                            PostUpdateCommands.RemoveComponent(linkedEntityGroup[childIndexCompHashPair.EntityIndex].Value, rmCompType);
                        }
                        // FIXME: should disable instead of removing once we have a way of doing that without structural changes
                        if (ghostMetaData.DefaultMode == GhostPrefabMetaData.GhostMode.Predicted)
                        {
                            for (int rm = 0; rm < ghostMetaData.DisableOnPredictedClient.Length; ++rm)
                            {
                                var childIndexCompHashPair = ghostMetaData.DisableOnPredictedClient[rm];
                                var rmCompType             = ComponentType.ReadWrite(TypeManager.GetTypeIndexFromStableTypeHash(childIndexCompHashPair.StableHash));
                                PostUpdateCommands.RemoveComponent(linkedEntityGroup[childIndexCompHashPair.EntityIndex].Value, rmCompType);
                            }
                        }
                        else if (ghostMetaData.DefaultMode == GhostPrefabMetaData.GhostMode.Interpolated)
                        {
                            for (int rm = 0; rm < ghostMetaData.DisableOnInterpolatedClient.Length; ++rm)
                            {
                                var childIndexCompHashPair = ghostMetaData.DisableOnInterpolatedClient[rm];
                                var rmCompType             = ComponentType.ReadWrite(TypeManager.GetTypeIndexFromStableTypeHash(childIndexCompHashPair.StableHash));
                                PostUpdateCommands.RemoveComponent(linkedEntityGroup[childIndexCompHashPair.EntityIndex].Value, rmCompType);
                            }
                        }
                    }
                }
コード例 #12
0
 private static int GetEntityCountInHashMap(NativeMultiHashMap <int, MyData> map, int key)
 {
     return(map.CountValuesForKey(key));
 }
コード例 #13
0
 public void Execute(ref MapTile tile, [ReadOnly] ref Sector sector)
 {
     tile.agents = (byte)hashMap.CountValuesForKey(sector.coordinates);
 }
コード例 #14
0
        public void Execute(int jobIndex)
        {
            var       stateKey = StatesToUpdate[jobIndex];
            StateInfo updatedStateInfo;

            var actionCount = ActionLookup.CountValuesForKey(stateKey);

            if (actionCount == 0)
            {
                if (UpdateStateValueNoActions(stateKey, out updatedStateInfo))
                {
                    // Queue for write job
                    StateInfoLookup[stateKey] = updatedStateInfo;

                    // If a change has occured, queue predecessors for update
                    if (PredecessorGraph.TryGetFirstValue(stateKey, out var predecessorStateKey, out var predecessorIterator))
                    {
                        do
                        {
                            PredecessorStatesToUpdate.TryAdd(predecessorStateKey, default);
                        }while (PredecessorGraph.TryGetNextValue(out predecessorStateKey, ref predecessorIterator));
                    }
                }
                return;
            }

            // Allocate local container
            if (!m_ActionInfoForState.IsCreated)
            {
                m_ActionInfoForState = new NativeList <ActionInfo>(actionCount, Allocator.Temp);
            }
            else
            {
                m_ActionInfoForState.Clear();
            }

            // Expanded state. Only update if one or more actions have updated.
            var updateState = false;

            // Update all actions
            ActionLookup.TryGetFirstValue(stateKey, out var actionKey, out var stateActionIterator);
            do
            {
                var stateActionPair = new StateActionPair <TStateKey, TActionKey>(stateKey, actionKey);
                if (UpdateCumulativeReward(stateActionPair, out var actionInfo))
                {
                    // Queue for write job
                    ActionInfoLookup[stateActionPair] = actionInfo;

                    updateState = true;
                }

                m_ActionInfoForState.Add(actionInfo);
            }while (ActionLookup.TryGetNextValue(out actionKey, ref stateActionIterator));



            // If no actions have changed info, the state info will not change, so check before updating state.
            if (updateState && UpdateStateValueFromActions(stateKey, m_ActionInfoForState, out updatedStateInfo))
            {
                // Queue for write job
                StateInfoLookup[stateKey] = updatedStateInfo;

                // If a change has occured, queue predecessors for update
                if (PredecessorGraph.TryGetFirstValue(stateKey, out var predecessorStateKey, out var predecessorIterator))
                {
                    do
                    {
                        PredecessorStatesToUpdate.TryAdd(predecessorStateKey, default);
                    }while (PredecessorGraph.TryGetNextValue(out predecessorStateKey, ref predecessorIterator));
                }
            }
        }