예제 #1
0
    protected override JobHandle OnUpdate(JobHandle lastJobHandle)
    {
        // Get component data from the GridPlane
        var cartesianGridPlane             = GetSingleton <CartesianGridOnPlane>();
        var rowCount                       = cartesianGridPlane.Blob.Value.RowCount;
        var colCount                       = cartesianGridPlane.Blob.Value.ColCount;
        var targetDirectionsBufferCapacity = ((colCount + 1) / 2) * rowCount;
        var gridWalls                      = (byte *)cartesianGridPlane.Blob.Value.Walls.GetUnsafePtr();

        // Initialize the buffer for the target paths with size appropriate to grid.
        Entities
        .WithName("InitializeTargets")
        .WithAll <CartesianGridTarget>()
        .WithNone <CartesianGridTargetDirection>()
        .WithStructuralChanges()
        .ForEach((Entity entity) =>
        {
            var buffer = EntityManager.AddBuffer <CartesianGridTargetDirection>(entity);
            buffer.ResizeUninitialized(targetDirectionsBufferCapacity);
        }).Run();

        // Rebuild all the paths to the target *only* when the target's grid position changes.
        Entities
        .WithName("UpdateTargetPaths")
        .WithAll <CartesianGridTarget>()
        .ForEach((Entity entity, ref CartesianGridTargetCoordinates prevTargetPosition, in CartesianGridCoordinates targetPosition, in DynamicBuffer <CartesianGridTargetDirection> targetDirections) =>
        {
            if (prevTargetPosition.Equals(targetPosition))
            {
                return;
            }

            prevTargetPosition = new CartesianGridTargetCoordinates(targetPosition);
            CartesianGridOnPlaneShortestPath.CalculateShortestPathsToTarget(targetDirections.Reinterpret <byte>().AsNativeArray(), rowCount, colCount, targetPosition, gridWalls);
        }).Run();
            public int WalkPathDistance(CartesianGridCoordinates sourcePosition, CartesianGridCoordinates targetPosition)
            {
                var directionsRowStride = (ColCount + 1) / 2;
                var directionsSize      = RowCount * directionsRowStride;

                var targetDirections = new NativeArray <byte>(directionsSize, Allocator.Temp);
                var sourceDirections = new NativeArray <byte>(directionsSize, Allocator.Temp);

                // For testing purposes, recalculate paths every time.
                CartesianGridOnPlaneShortestPath.CalculateShortestPathsToTarget(targetDirections, RowCount, ColCount, targetPosition, Walls);
                CartesianGridOnPlaneShortestPath.CalculateShortestPathsToTarget(sourceDirections, RowCount, ColCount, sourcePosition, Walls);

                // Test distance form source->target is same as target->source
                var sourceToTargetDistance = WalkPath(sourcePosition, targetDirections, 0);
                var targetToSourceDistance = WalkPath(targetPosition, sourceDirections, 0);

                Assert.AreEqual(sourceToTargetDistance, targetToSourceDistance);

                var expectedDistance = sourceToTargetDistance;

                // Sample path variations (not exhaustive, always follow the variation path option)
                for (int i = 1; i < 4; i++)
                {
                    // Test distance form source->target is same as target->source
                    // Test distance is same for all variations
                    sourceToTargetDistance = WalkPath(sourcePosition, targetDirections, i);
                    Assert.AreEqual(expectedDistance, sourceToTargetDistance);
                    targetToSourceDistance = WalkPath(targetPosition, sourceDirections, i);
                    Assert.AreEqual(expectedDistance, targetToSourceDistance);
                }

                targetDirections.Dispose();
                sourceDirections.Dispose();

                return(expectedDistance);
            }