Пример #1
0
    public override void UpdateBehaviour()
    {
#if UNITY_EDITOR
        debugDrawDependencies.Complete();

        NativeArray <DebugDrawCommand> debugDrawCommands = m_debugDrawCommandQueue.ToArray(Allocator.Temp);
        m_debugDrawCommandQueue.Clear();

        for (int debugDrawCommandIndex = 0; debugDrawCommandIndex < debugDrawCommands.Length; debugDrawCommandIndex++)
        {
            DebugDrawCommand debugDrawCommand = debugDrawCommands[debugDrawCommandIndex];
            switch (debugDrawCommand.debugDrawCommandType)
            {
            case DebugDrawCommandType.Line:
                DebugDrawLineData debugDrawLineData = debugDrawCommand.DebugCommandData <DebugDrawLineData>();
                Debug.DrawLine(debugDrawLineData.start, debugDrawLineData.end, debugDrawLineData.colour);
                break;

            case DebugDrawCommandType.Sphere:
                break;

            default:
                throw new Exception("Invalid debug draw command type");
            }
        }

        debugDrawCommands.Dispose();
#endif
    }
Пример #2
0
        public unsafe void Test()
        {
            const int cnt = 1000;

            using var queue = new NativeQueue <int>(0);
            var managed = new Queue <int>(cnt);

            var arr  = new int[cnt];
            var rand = new Random();

            for (int i = 0; i < cnt; i++)
            {
                arr[i] = rand.Next(cnt);
            }

            for (int i = 0; i < cnt; i++)
            {
                managed.Enqueue(arr[i]);
                queue.Enqueue(arr[i]);
            }

            var se    = queue.GetEnumerator();
            var me    = managed.GetEnumerator();
            var toArr = queue.ToArray();

            for (var i = 0; i < cnt; i++)
            {
                se.MoveNext();
                me.MoveNext();
                Assert.True(se.Current == me.Current);
                Assert.True(toArr[i] == se.Current);
            }

            se.Dispose();
            me.Dispose();

            for (int i = 0; i < cnt; i++)
            {
                Assert.True(managed.Count == queue.Count);
                var l = managed.Dequeue();
                var r = queue.Peek();
                Assert.True(l == r);
                queue.Dequeue();
            }

            queue.Clear();
            queue.TrimExcess();

            Assert.True(!queue.IsDisposed);

            queue.Dispose();

            Assert.True(queue.Ptr == null);
            Assert.True(queue.IsDisposed);
        }
Пример #3
0
    protected override void OnUpdate()
    {
        EntityQuery enemyQuery  = GetEntityQuery(typeof(EnemyComponent), typeof(Translation));
        EntityQuery playerQuery = GetEntityQuery(typeof(PlayerComponent), typeof(Translation));

        NativeArray <Entity>      enemies    = enemyQuery.ToEntityArray(Allocator.TempJob);
        NativeArray <Translation> enemyTrans = enemyQuery.ToComponentDataArray <Translation>(Allocator.TempJob);

        NativeArray <CollisionData> enemyCollisionDatas = new NativeArray <CollisionData>(enemies.Length, Allocator.TempJob);

        for (int i = 0; i < enemies.Length; i++)
        {
            CollisionData data = new CollisionData();
            data.entity            = enemies[i];
            data.position          = enemyTrans[i].Value;
            data.radius            = GameSetting.Instance.enemyRadius + GameSetting.Instance.playerRadius;
            enemyCollisionDatas[i] = data;
        }
        enemies.Dispose();
        enemyTrans.Dispose();

        NativeQueue <Entity> collisionEnemies = new NativeQueue <Entity>(Allocator.TempJob);
        CollisionDetectJob   job = new CollisionDetectJob()
        {
            collisionDatas  = enemyCollisionDatas,
            translationType = GetArchetypeChunkComponentType <Translation>(),
            entityType      = GetArchetypeChunkEntityType(),
            collisionEntity = collisionEnemies.AsParallelWriter(),
        };
        JobHandle handle = job.Schedule(playerQuery);

        handle.Complete();


        if (collisionEnemies.Count > 0)
        {
            NativeArray <Entity> removeEntity = collisionEnemies.ToArray(Allocator.Temp);
            this.EntityManager.DestroyEntity(removeEntity);


            //foreach (var item in removeEntity)
            //{
            //    Debug.LogFormat("remove count:{0},index:{1},version:{2}" , removeEntity.Length,item.Index,item.Version);
            //}
            removeEntity.Dispose();
        }
        collisionEnemies.Dispose();
        enemyCollisionDatas.Dispose();
    }
 public void ToArray_WorksFromJobs()
 {
     using (var queue = new NativeQueue <int>(Allocator.TempJob))
     {
         new EnqueueJob
         {
             Queue = queue.AsParallelWriter()
         }.Schedule(100, 10).Complete();
         Assert.AreEqual(100, queue.Count);
         using (var arr = queue.ToArray(Allocator.Temp))
         {
             Assert.AreEqual(100, arr.Length);
             arr.Sort();
             for (int i = 0; i < arr.Length; i++)
             {
                 Assert.AreEqual(i, arr[i]);
             }
         }
     }
 }
Пример #5
0
    //protected override void OnUpdate()
    //{
    //    matrices.Clear();
    //    block.Clear();
    //    EntityQuery entityQuery = GetEntityQuery(typeof(Translation), typeof(EnemyComponent));
    //    NativeArray<Translation> nativeArray = entityQuery.ToComponentDataArray<Translation>(Allocator.Temp);
    //    for (int i = 0; i < nativeArray.Length; i++)
    //    {
    //        for (int j = i; j < nativeArray.Length - 1; j++)
    //        {
    //            if (nativeArray[j].Value.y < nativeArray[j + 1].Value.y)
    //            {
    //                Translation temp = nativeArray[j];
    //                nativeArray[j] = nativeArray[j + 1];
    //                nativeArray[j + 1] = temp;
    //            }
    //        }
    //    }

    //    foreach (var item in nativeArray)
    //    {
    //        matrices.Add(Matrix4x4.TRS(item.Value, Quaternion.identity, Vector3.one));
    //        if (matrices.Count >= 1023)
    //        {
    //            Graphics.DrawMeshInstanced(GameSetting.Instance.entityMesh, 0, GameSetting.Instance.enemyMat, matrices, block);
    //            matrices.Clear();
    //        }
    //    }

    //    Graphics.DrawMeshInstanced(GameSetting.Instance.entityMesh, 0, GameSetting.Instance.enemyMat, matrices, block);

    //    EntityQueryBuilder queryBuilder = Entities.WithNone(typeof(EnemyComponent)).WithAll(typeof(Translation));
    //    queryBuilder.ForEach((ref Translation translation, ref Rotation rotation) =>
    //    {
    //        Graphics.DrawMesh(GameSetting.Instance.entityMesh, translation.Value, rotation.Value, GameSetting.Instance.playerMat, LayerMask.GetMask("Default"));
    //    });


    //}

    protected override void OnUpdate()
    {
        matrices.Clear();
        block.Clear();
        int jobHandleindex = 0;
        NativeArray <JobHandle> jobHandles  = new NativeArray <JobHandle>(4, Allocator.Temp);
        EntityQuery             entityQuery = GetEntityQuery(typeof(Translation), typeof(EnemyComponent));


        NativeQueue <RenderData> renderQueue0   = new NativeQueue <RenderData>(Allocator.TempJob);
        NativeQueue <RenderData> renderQueue1   = new NativeQueue <RenderData>(Allocator.TempJob);
        NativeQueue <RenderData> renderQueue2   = new NativeQueue <RenderData>(Allocator.TempJob);
        NativeQueue <RenderData> renderQueue3   = new NativeQueue <RenderData>(Allocator.TempJob);
        NativeQueue <Entity>     toRemoveEntity = new NativeQueue <Entity>(Allocator.TempJob);
        Camera camera = Camera.main;

        NativeQueue <RenderData> .ParallelWriter pw0 = renderQueue0.AsParallelWriter();
        NativeQueue <RenderData> .ParallelWriter pw1 = renderQueue1.AsParallelWriter();
        NativeQueue <RenderData> .ParallelWriter pw2 = renderQueue2.AsParallelWriter();
        NativeQueue <RenderData> .ParallelWriter pw3 = renderQueue3.AsParallelWriter();

        NativeQueue <Entity> .ParallelWriter tre = toRemoveEntity.AsParallelWriter();
        float         halfW   = camera.orthographicSize / Screen.currentResolution.height * Screen.currentResolution.width;
        SpriteCullJob cullJob = new SpriteCullJob()
        {
            top              = camera.transform.position.y + camera.orthographicSize,
            bottom           = camera.transform.position.y - camera.orthographicSize,
            left             = camera.transform.position.x - halfW,
            right            = camera.transform.position.x + halfW,
            nativeQueue0     = pw0,
            nativeQueue1     = pw1,
            nativeQueue2     = pw2,
            nativeQueue3     = pw3,
            typeTranslation  = GetArchetypeChunkComponentType <Translation>(),
            entityType       = GetArchetypeChunkEntityType(),
            needRemoveEntity = tre,
        };

        JobHandle handle = cullJob.Schedule(entityQuery);

        handle.Complete();

        NativeArray <JobHandle> switchHandles = new NativeArray <JobHandle>(4, Allocator.TempJob);
        int switchJobIndex                      = 0;
        NativeArray <RenderData> rd0            = new NativeArray <RenderData>(renderQueue0.Count, Allocator.TempJob),
                                 rd1            = new NativeArray <RenderData>(renderQueue1.Count, Allocator.TempJob),
                                 rd2            = new NativeArray <RenderData>(renderQueue2.Count, Allocator.TempJob),
                                 rd3            = new NativeArray <RenderData>(renderQueue3.Count, Allocator.TempJob);
        NativeQueue2ArrayJob nativeQueue2Array0 = new NativeQueue2ArrayJob()
        {
            nativeQueue = renderQueue0,
            nativeArray = rd0
        };

        switchHandles[switchJobIndex++] = nativeQueue2Array0.Schedule();
        NativeQueue2ArrayJob nativeQueue2Array1 = new NativeQueue2ArrayJob()
        {
            nativeQueue = renderQueue1,
            nativeArray = rd1
        };

        switchHandles[switchJobIndex++] = nativeQueue2Array1.Schedule();
        NativeQueue2ArrayJob nativeQueue2Array2 = new NativeQueue2ArrayJob()
        {
            nativeQueue = renderQueue2,
            nativeArray = rd2
        };

        switchHandles[switchJobIndex++] = nativeQueue2Array2.Schedule();
        NativeQueue2ArrayJob nativeQueue2Array3 = new NativeQueue2ArrayJob()
        {
            nativeQueue = renderQueue3,
            nativeArray = rd3
        };

        switchHandles[switchJobIndex++] = nativeQueue2Array3.Schedule();

        JobHandle.CompleteAll(switchHandles);
        switchHandles.Dispose();

        renderQueue0.Dispose();
        renderQueue1.Dispose();
        renderQueue2.Dispose();
        renderQueue3.Dispose();
        SpriteSortJobs sortJobs0 = new SpriteSortJobs()
        {
            renderDatas = rd0,
        };

        jobHandles[jobHandleindex++] = sortJobs0.Schedule();

        SpriteSortJobs sortJobs1 = new SpriteSortJobs()
        {
            renderDatas = rd1,
        };

        jobHandles[jobHandleindex++] = sortJobs1.Schedule();

        SpriteSortJobs sortJobs2 = new SpriteSortJobs()
        {
            renderDatas = rd2,
        };

        jobHandles[jobHandleindex++] = sortJobs2.Schedule();

        SpriteSortJobs sortJobs3 = new SpriteSortJobs()
        {
            renderDatas = rd3,
        };

        jobHandles[jobHandleindex++] = sortJobs3.Schedule();

        JobHandle.CompleteAll(jobHandles);
        foreach (var item in rd0)
        {
            AddData(item);
        }
        foreach (var item in rd1)
        {
            AddData(item);
        }
        foreach (var item in rd2)
        {
            AddData(item);
        }
        foreach (var item in rd3)
        {
            AddData(item);
        }
        if (matrices.Count > 0)
        {
            Graphics.DrawMeshInstanced(GameSetting.Instance.entityMesh, 0, GameSetting.Instance.enemyMat, matrices, block);
        }
        rd0.Dispose();
        rd1.Dispose();
        rd2.Dispose();
        rd3.Dispose();
        jobHandles.Dispose();
        if (toRemoveEntity.Count > 0)
        {
            NativeArray <Entity> toRemoveEntityArray = toRemoveEntity.ToArray(Allocator.Temp);
            this.EntityManager.DestroyEntity(toRemoveEntityArray);

            toRemoveEntityArray.Dispose();
        }
        toRemoveEntity.Dispose();



        Entities.ForEach((ref PlayerComponent playerComponent, ref Translation translation, ref Rotation rotation) =>
        {
            Graphics.DrawMesh(GameSetting.Instance.entityMesh, translation.Value, rotation.Value, GameSetting.Instance.playerMat, LayerMask.GetMask("Default"));
        });
    }
Пример #6
0
        public void Execute()
        {
            var commandQueueArray = commandQueue.ToArray(Allocator.Temp);

            {
                // Mass destroy
                weaponToDestroyCache.Clear();
                for (int i = 0; i < commandQueueArray.Length; ++i)
                {
                    var command = commandQueueArray[i];
                    if (command.currentWeaponRef.Value != Entity.Null)
                    {
                        weaponToDestroyCache.Add(command.currentWeaponRef.Value);
                    }
                }

                if (weaponToDestroyCache.Length > 0)
                {
                    // To be replaced with batched ECB destroy when API ships
                    {
                        for (int i = 0; i < weaponToDestroyCache.Length; ++i)
                        {
                            commandBuffer.DestroyEntity(weaponToDestroyCache[i]);
                        }
                    }
                }

                // Instantiate has to 1-1 since mass instantiate does not work with LinkedEntityGroup
                newWeaponInstantiatedCache.Clear();
                for (int i = 0; i < commandQueueArray.Length; ++i)
                {
                    var command = commandQueueArray[i];
                    newWeaponInstantiatedCache.Add(commandBuffer.Instantiate(weaponPrefabs[command.newWeaponIdx]));
                }

                // Mass add component
                {
                    // To be replaced with batched ECB add component when API ships
                    {
                        for (int i = 0; i < newWeaponInstantiatedCache.Length; ++i)
                        {
                            commandBuffer.AddComponent <Parent>(newWeaponInstantiatedCache[i]);
                        }

                        for (int i = 0; i < newWeaponInstantiatedCache.Length; ++i)
                        {
                            commandBuffer.AddComponent <LocalToParent>(newWeaponInstantiatedCache[i]);
                        }
                    }
                }

                // There is no mass set component but setting component is way less of a cost than add component
                for (int i = 0; i < newWeaponInstantiatedCache.Length; ++i)
                {
                    var command   = commandQueueArray[i];
                    var newWeapon = newWeaponInstantiatedCache[i];

                    commandBuffer.SetComponent(newWeapon, new Parent {
                        Value = command.weaponOwner
                    });
                    commandBuffer.SetComponent(newWeapon, new LocalToParent {
                        Value = command.localToParent
                    });

                    commandBuffer.SetComponent(command.weaponOwner, new Weapon {
                        Value = newWeapon
                    });
                }
            }
            commandQueueArray.Dispose();

            commandQueue.Clear();
        }
    protected override void OnUpdate()
    {
        EntityQuery entityQuery = GetEntityQuery(typeof(Translation), typeof(SpriteSheetComponentData));

        NativeArray <SpriteSheetComponentData> animationDataQuery = entityQuery.ToComponentDataArray <SpriteSheetComponentData>(Allocator.TempJob);
        NativeArray <Translation> translationArray = entityQuery.ToComponentDataArray <Translation>(Allocator.TempJob);

        NativeQueue <RenderData> nativeQueue_1 = new NativeQueue <RenderData>(Allocator.TempJob);
        NativeQueue <RenderData> nativeQueue_2 = new NativeQueue <RenderData>(Allocator.TempJob);

        Camera cameraMain     = Camera.main;
        float3 cameraPosition = cameraMain.transform.position;

        float yBottom = cameraPosition.y - cameraMain.orthographicSize;
        float yTop_1  = cameraPosition.y + cameraMain.orthographicSize;
        float yTop_2  = cameraPosition.y + 0f;

        CullAndSortJob cullAndSortJob = new CullAndSortJob
        {
            yBottom = yBottom,
            yTop_1  = yTop_1,
            yTop_2  = yTop_2,

            nativeQueue1 = nativeQueue_1.AsParallelWriter(),
            nativeQueue2 = nativeQueue_2.AsParallelWriter()
        };

        JobHandle jobHandle = cullAndSortJob.Schedule(this);

        jobHandle.Complete();

        animationDataQuery.Dispose();
        translationArray.Dispose();

        NativeArray <RenderData> nativeArray_1 = nativeQueue_1.ToArray(Allocator.TempJob);
        NativeArray <RenderData> nativeArray_2 = nativeQueue_2.ToArray(Allocator.TempJob);

        nativeQueue_1.Dispose();
        nativeQueue_2.Dispose();

        NativeArray <JobHandle> jobHandleArray = new NativeArray <JobHandle>(2, Allocator.TempJob);

        SortByPositionJob sortByPositionJob_1 = new SortByPositionJob
        {
            dataArray = nativeArray_1
        };

        jobHandleArray[0] = sortByPositionJob_1.Schedule();

        SortByPositionJob sortByPositionJob_2 = new SortByPositionJob
        {
            dataArray = nativeArray_2
        };

        jobHandleArray[1] = sortByPositionJob_2.Schedule();

        JobHandle.CompleteAll(jobHandleArray);

        int visibleEntityTotal = nativeArray_1.Length + nativeArray_2.Length;

        NativeArray <Matrix4x4> matrixArray = new NativeArray <Matrix4x4>(visibleEntityTotal, Allocator.TempJob);
        NativeArray <Vector4>   uvArray     = new NativeArray <Vector4>(visibleEntityTotal, Allocator.TempJob);

        FillArraysParrallelJob fillArraysParrallelJob_1 = new FillArraysParrallelJob
        {
            nativeArray   = nativeArray_1,
            matrixArray   = matrixArray,
            uvArray       = uvArray,
            startingIndex = 0
        };

        jobHandleArray[0] = fillArraysParrallelJob_1.Schedule(nativeArray_1.Length, 10);


        FillArraysParrallelJob fillArraysParrallelJob_2 = new FillArraysParrallelJob
        {
            nativeArray   = nativeArray_2,
            matrixArray   = matrixArray,
            uvArray       = uvArray,
            startingIndex = nativeArray_1.Length
        };

        jobHandleArray[1] = fillArraysParrallelJob_2.Schedule(nativeArray_2.Length, 10);

        JobHandle.CompleteAll(jobHandleArray);

        nativeArray_1.Dispose();
        nativeArray_2.Dispose();

        MaterialPropertyBlock materialPropertyBlock = new MaterialPropertyBlock();

        Vector4[] uv = new Vector4[1];

        Mesh     quadMesh         = GameEntity.GetInstance().quadMesh;
        Material material         = GameEntity.GetInstance().walkingSpriteSheetMaterial;
        int      shaderPropertyId = Shader.PropertyToID("_MainTex_UV");

        int sliceCount = 1023;

        Matrix4x4[] matrixInstancedArray = new Matrix4x4[sliceCount];
        Vector4[]   uvInstancedArray     = new Vector4[sliceCount];
        for (int i = 0; i < matrixArray.Length; i += sliceCount)
        {
            int sliceSize = Mathf.Min(sliceCount, matrixArray.Length - i);

            NativeArray <Matrix4x4> .Copy(matrixArray, i, matrixInstancedArray, 0, sliceSize);

            NativeArray <Vector4> .Copy(uvArray, i, uvInstancedArray, 0, sliceSize);

            materialPropertyBlock.SetVectorArray(shaderPropertyId, uvInstancedArray);

            Graphics.DrawMeshInstanced(
                quadMesh,
                0,
                material,
                matrixInstancedArray,
                sliceSize,
                materialPropertyBlock
                );
        }



        matrixArray.Dispose();
        uvArray.Dispose();

        jobHandleArray.Dispose();
    }
                public void Execute()
                {
                    *EntityCount += Queue.Count;

                    List.AddRange(Queue.ToArray(Allocator.Temp));
                }
    protected override void OnUpdate()
    {
        // Some initialization must happen on first update for singleton entity query to work
        if (!initialized)
        {
            initialized = true;

            var weaponDataEntity = GetSingletonEntity <WeaponDataEntry>();
            var weaponDatabase   = EntityManager.GetBuffer <WeaponDataEntry>(weaponDataEntity);

            weaponPrefabs.Clear();
            for (int i = 0; i < weaponDatabase.Length; ++i)
            {
                weaponPrefabs.Add(weaponDatabase[i].prefab);
            }
        }

        commandQueueDependency.Complete();

        using (var commandQueueArray = commandQueue.ToArray(Allocator.Temp))
        {
            // Mass destroy
            weaponToDestroyCache.Clear();
            for (int i = 0; i < commandQueueArray.Length; ++i)
            {
                var command = commandQueueArray[i];
                if (command.currentWeaponRef.Value != Entity.Null)
                {
                    weaponToDestroyCache.Add(command.currentWeaponRef.Value);
                }
            }
            if (weaponToDestroyCache.Length > 0)
            {
                EntityManager.DestroyEntity(weaponToDestroyCache);
            }

            // Instantiate has to 1-1 since mass instantiate does not work with LinkedEntityGroup
            newWeaponInstantiatedCache.Clear();
            for (int i = 0; i < commandQueueArray.Length; ++i)
            {
                var command = commandQueueArray[i];
                newWeaponInstantiatedCache.Add(EntityManager.Instantiate(weaponPrefabs[command.newWeaponIdx]));
            }

            // Mass add component
            EntityManager.AddComponent <Parent>(newWeaponInstantiatedCache);
            EntityManager.AddComponent <LocalToParent>(newWeaponInstantiatedCache);

            // There is no mass set component but setting component is way less of a cost than add component
            for (int i = 0; i < newWeaponInstantiatedCache.Length; ++i)
            {
                var command   = commandQueueArray[i];
                var newWeapon = newWeaponInstantiatedCache[i];

                EntityManager.SetComponentData(newWeapon, new Parent {
                    Value = command.weaponOwner
                });
                EntityManager.SetComponentData(newWeapon, new LocalToParent {
                    Value = command.localToParent
                });

                EntityManager.SetComponentData(command.weaponOwner, new Weapon {
                    Value = newWeapon
                });
            }
        }

        commandQueue.Clear();
    }