示例#1
0
        public void SetPathAndForget(Vector3 destination, MoveCommandType command)
        {
            Vector3 pos = _unit.transform.position;

            _PathQueue.Enqueue(new PathData(pos, destination, command));
            _PathFinderRunnerEvent.Set();
        }
示例#2
0
 public void RpcOrderMovement(
     Vector3 destination,
     float heading,
     MoveCommandType mode,
     bool enqueue)
 {
     OrderMovement(destination, heading, mode, enqueue);
 }
示例#3
0
 /// <summary>
 /// Sets the unit's destination location,
 /// with a specific given heading value.
 /// </summary>
 public void SetDestination(
     Vector3 d,
     float heading            = NO_HEADING,
     MoveCommandType moveMode = MoveCommandType.FAST)
 {
     // multithreading
     Pathfinder.SetPathAndForget(d, moveMode);
     _moveStrategy.FinalHeading = heading;
 }
示例#4
0
        /// <summary>
        /// Give the platoon a movement order.
        /// </summary>
        /// <param name="destination"></param>
        /// <param name="heading">
        /// What direction should the units face when they arrive?
        /// </param>
        /// <param name="mode"></param>
        /// <param name="enqueue"></param>
        public void OrderMovement(
            Vector3 destination,
            float heading        = MovementComponent.NO_HEADING,
            MoveCommandType mode = MoveCommandType.NORMAL,
            bool enqueue         = false)
        {
            OrderData order = OrderData.MakeMoveOrder(this, destination, heading, mode);

            OrderQueue.SendOrder(order, enqueue);
        }
示例#5
0
 /// <summary>
 /// Sets the unit's destination location,
 /// with a specific given heading value.
 /// </summary>
 public void SetDestination(
     Vector3 d,
     float heading            = NO_HEADING,
     MoveCommandType moveMode = MoveCommandType.FAST)
 {
     if (Pathfinder.SetPath(d, moveMode) < Pathfinder.FOREVER)
     {
         _moveStrategy.FinalHeading = heading;
     }
 }
示例#6
0
 public static OrderData MakeMoveOrder(
     PlatoonBehaviour platoon,
     Vector3 destination,
     float heading = MovementComponent.NO_HEADING,
     MoveCommandType moveCommandType = MoveCommandType.NORMAL)
 {
     return(new OrderData(
                OrderType.MOVE_ORDER,
                platoon,
                destination,
                heading,
                moveCommandType));
 }
示例#7
0
 private OrderData(
     OrderType orderType,
     PlatoonBehaviour platoon,
     Vector3 targetPosition,
     float heading = MovementComponent.NO_HEADING,
     MoveCommandType moveCommandType = MoveCommandType.NORMAL)
 {
     OrderType       = orderType;
     Platoon         = platoon;
     TargetPosition  = targetPosition;
     Heading         = heading;
     MoveCommandType = moveCommandType;
 }
示例#8
0
        public void MoveFixed(Vector3D targetPosition, float speed, ACDTranslateFixedMessage baseMessage = null)
        {
            _SetupMove(targetPosition, speed);
            _moveCommand = MoveCommandType.Fixed;

            if (baseMessage == null)
                baseMessage = new ACDTranslateFixedMessage();

            baseMessage.ActorId = (int)this.Target.DynamicID;
            baseMessage.Velocity = this.Velocity;

            this.Target.World.BroadcastIfRevealed(baseMessage, this.Target);
        }
示例#9
0
        public void Move(Vector3D destination, float speed, ACDTranslateNormalMessage baseMessage = null)
        {
            _SetupMove(destination, speed);
            _moveCommand = MoveCommandType.Normal;

            if (baseMessage == null)
                baseMessage = new ACDTranslateNormalMessage();

            baseMessage.ActorId = (int)this.Target.DynamicID;
            baseMessage.Position = destination;
            baseMessage.Angle = (float)Math.Acos(this.Target.RotationW) * 2f;
            baseMessage.Speed = speed;

            this.Target.World.BroadcastIfRevealed(baseMessage, this.Target);
        }
示例#10
0
        public void MoveFixed(Vector3D targetPosition, float speed, ACDTranslateFixedMessage baseMessage = null)
        {
            _SetupMove(targetPosition, speed);
            _moveCommand = MoveCommandType.Fixed;

            if (baseMessage == null)
            {
                baseMessage = new ACDTranslateFixedMessage();
            }

            baseMessage.ActorId  = (int)this.Target.DynamicID;
            baseMessage.Velocity = this.Velocity;

            this.Target.World.BroadcastIfRevealed(baseMessage, this.Target);
        }
示例#11
0
        public void CmdOrderMovement(
            uint platoonNetId,
            Vector3 destination,
            float heading,
            MoveCommandType mode,
            bool enqueue)
        {
            NetworkIdentity identity;

            if (NetworkIdentity.spawned.TryGetValue(platoonNetId, out identity))
            {
                PlatoonBehaviour platoon = identity.gameObject.GetComponent <PlatoonBehaviour>();
                platoon.RpcOrderMovement(destination, heading, mode, enqueue);
            }
        }
示例#12
0
        public void Move(Vector3D destination, float speed, ACDTranslateNormalMessage baseMessage = null)
        {
            _SetupMove(destination, speed);
            _moveCommand = MoveCommandType.Normal;

            if (baseMessage == null)
            {
                baseMessage = new ACDTranslateNormalMessage();
            }

            baseMessage.ActorId  = (int)this.Target.DynamicID;
            baseMessage.Position = destination;
            baseMessage.Angle    = (float)Math.Acos(this.Target.RotationW) * 2f;
            baseMessage.Speed    = speed;

            this.Target.World.BroadcastIfRevealed(baseMessage, this.Target);
        }
示例#13
0
        public void MoveArc(Vector3D destination, float height, float gravity, ACDTranslateArcMessage baseMessage = null)
        {
            _SetupArcMove(destination, height, gravity);
            _moveCommand = MoveCommandType.Arc;

            if (baseMessage == null)
            {
                baseMessage = new ACDTranslateArcMessage();
            }

            baseMessage.ActorId  = (int)this.Target.DynamicID;
            baseMessage.Start    = this.Target.Position;
            baseMessage.Velocity = this.Velocity;
            baseMessage.Field6   = gravity;
            baseMessage.Field9   = destination.Z;

            this.Target.World.BroadcastIfRevealed(baseMessage, this.Target);
        }
示例#14
0
    // Gives the next step along the previously computed path
    // For speed, this will only update the waypoint on some frames
    // Returns 'NoPosition' if there is no destination or a step cannot be found
    public Vector3 GetWaypoint()
    {
        if (!HasDestination())   // Nowhere to go
        {
            waypoint = NoPosition;
        }
        else if (Time.time > nextUpdateTime)
        {
            nextUpdateTime = Time.time + UpdateInterval;
            UpdateWaypoint();
        }

        if (waypoint == NoPosition)
        {
            command = MoveCommandType.Slow;
        }

        return(waypoint);
    }
示例#15
0
    // Generate and store the sequence of nodes leading to the destination using the global graph
    // Returns the total normalized path time
    // If no path was found, return 'forever' and set no destination
    public float SetPath(Vector3 destination, MoveCommandType command)
    {
        previousNode   = null;
        nextUpdateTime = 0f;

        if (destination == NoPosition)
        {
            path.Clear();
            return(Forever);
        }

        this.command = command;

        float pathTime = data.FindPath(path, unit.transform.position, destination, unit.Data.mobility, 0f, command);

        if (pathTime >= Forever)
        {
            path.Clear();
        }
        return(pathTime);
    }
示例#16
0
        /// <summary>
        /// Generate and store the sequence of nodes leading to the
        /// destination using the global graph.
        /// Returns the total normalized path time.
        /// If no path was found, returns 'forever' and sets no destination.
        /// </summary>
        /// <param name="destination"></param>
        /// <param name="command"></param>
        /// <returns></returns>
        public float SetPath(Vector3 destination, MoveCommandType command)
        {
            Logger.LogPathfinding(
                $"Pathfinder::SetPath() called, destination = {destination}, command = {command}",
                LogLevel.DEBUG);

            _previousNode   = null;
            _nextUpdateTime = 0f;

            if (destination == NO_POSITION)
            {
                Logger.LogPathfinding(
                    $"Pathfinder::SetPath() for destination {destination} " +
                    $"got no viable path.",
                    LogLevel.DEBUG);
                _path.Clear();
                return(FOREVER);
            }

            this.Command = command;

            float pathTime = Data.FindPath(
                _path, _unit.transform.position, destination, _unit.Mobility, 0f, command);

            if (pathTime >= FOREVER)
            {
                _path.Clear();
            }

            UpdateWaypointAngle();

            Logger.LogPathfinding(
                $"Pathfinder::SetPath() for destination {destination}, " +
                $"command = {command} chose path with {_path.Count} " +
                $"waypoints and {pathTime} travel time.",
                LogLevel.DEBUG);
            return(pathTime);
        }
示例#17
0
        /**
         * Send a movement command to the currently selected platoons.
         *
         * \param useGhostHeading If true, the platoons will move to their sillhouettes
         * (e.g. the command was previewed using mouse drag and the units should move to
         * the positions that were shown in the preview). If false, the platoons
         * will just pick their destinations based on where the cursor is.
         */
        public void DispatchMoveCommand(bool useGhostHeading, MoveCommandType moveMode)
        {
            if (Empty)
            {
                return;
            }

            bool shouldQueue = Input.GetKey(KeyCode.LeftShift);

            _selection.ForEach(x => CommandConnection.Connection.CmdOrderMovement(
                                   x.netId,
                                   x.GhostPlatoon.transform.position,
                                   useGhostHeading ?
                                   x.GhostPlatoon.FinalHeading : MovementComponent.NO_HEADING,
                                   moveMode,
                                   shouldQueue));

            // A random platoon in selection plays the move command voice line
            int randInt = Random.Range(0, _selection.Count);

            _selection[randInt].PlayMoveCommandVoiceline();

            MaybeDropSelectionAfterOrder();
        }
示例#18
0
 public static Type GetTypeByEnum(MoveCommandType type)
 {
     return(Instance._moveCommandTypes[(int)type]);
 }
示例#19
0
        private void CollectCommandsAndSend(TankNode tankNode, WeaponNode weaponNode, MoveCommandType commandType)
        {
            TankMovementSenderComponent tankMovementSender = tankNode.tankMovementSender;

            if (((commandType & MoveCommandType.TANK) != MoveCommandType.NONE) && (tankMovementSender.LastSentMovementTime >= PreciseTime.Time))
            {
                commandType ^= MoveCommandType.TANK;
            }
            if (((commandType & MoveCommandType.WEAPON) != MoveCommandType.NONE) && (tankMovementSender.LastSentWeaponRotationTime >= PreciseTime.Time))
            {
                commandType ^= MoveCommandType.WEAPON;
            }
            Movement?nullable  = null;
            float?   nullable3 = null;

            if ((commandType & MoveCommandType.TANK) != MoveCommandType.NONE)
            {
                nullable = new Movement?(this.GetMovement(tankNode));
            }
            if ((commandType & MoveCommandType.WEAPON) != MoveCommandType.NONE)
            {
                nullable3 = new float?(weaponNode.weaponRotationControl.Rotation);
            }
            MoveCommand moveCommand = new MoveCommand {
                Movement              = nullable,
                WeaponRotation        = nullable3,
                TankControlVertical   = this.GetMoveAxis(tankNode),
                TankControlHorizontal = this.GetTurnAxis(tankNode),
                WeaponRotationControl = this.GetWeaponControl(weaponNode),
                ClientTime            = (int)(PreciseTime.Time * 1000.0)
            };

            this.SendCommand(tankNode, moveCommand);
        }
示例#20
0
        /// <summary>
        /// Run the A* algorithm and put the result in path.
        /// If no path was found, return 'forever' and put only the destination in path.
        /// Returns the total path time.
        /// </summary>
        public float FindPath(
            List <PathNode> path,
            Vector3 start,
            Vector3 destination,
            MobilityData mobility,
            float unitRadius,
            MoveCommandType command)
        {
            path.Clear();
            path.Add(new PathNode(destination, false));

            PathNode cameFromDest = null;
            float    gScoreDest   = Pathfinder.FindLocalPath(this,
                                                             start,
                                                             destination,
                                                             mobility,
                                                             unitRadius);

            if (gScoreDest < Pathfinder.FOREVER)
            {
                if (command == MoveCommandType.NORMAL || command == MoveCommandType.REVERSE)
                {
                    return(gScoreDest);
                }
            }

            // Initialize with all nodes accessible from the starting point
            // (this can be optimized later by throwing out some from the start)
            _openSet.Clear();

            List <PathNode> graph = _graphRegularMove;
            float           neighborSearchDistance = Pathfinder.FOREVER;

            // if we are in fast mode our graph is much more extensive and we have to
            // limit our neighor distance to use that extensive network of nodes
            if (command == MoveCommandType.FAST)
            {
                graph = _graphFastMove;
                neighborSearchDistance = ARC_MAX_DIST;
            }

            // find the nearest neighbor start A* search
            foreach (PathNode neighbor in graph)
            {
                neighbor.IsClosed = false;
                neighbor.CameFrom = null;
                neighbor.GScore   = Pathfinder.FOREVER;

                Vector3 neighborPos = Position(neighbor);

                // and optimal search
                if ((start - neighborPos).magnitude < neighborSearchDistance)
                {
                    float gScoreNew = Pathfinder.FindLocalPath(this,
                                                               start,
                                                               neighborPos,
                                                               mobility,
                                                               unitRadius);
                    if (gScoreNew < Pathfinder.FOREVER)
                    {
                        neighbor.GScore = gScoreNew;

                        float fScoreNew = gScoreNew + TimeHeuristic(neighborPos, destination, mobility);
                        _openSet.Enqueue(neighbor, fScoreNew);
                    }
                }
            }

            // generic A* algorithm based on distance to destination and arc time's as hueristic function weights
            while (_openSet.Count > 0)
            {
                PathNode current = _openSet.Dequeue();
                current.IsClosed = true;

                if (gScoreDest < current.Priority)
                {
                    break;
                }

                foreach (PathArc arc in current.Arcs)
                {
                    PathNode neighbor = arc.Node1 == current ? arc.Node2 : arc.Node1;

                    if (neighbor.IsClosed)
                    {
                        continue;
                    }

                    float arcTime = arc.Time[mobility.Index];
                    if (arcTime >= Pathfinder.FOREVER)
                    {
                        continue;
                    }

                    float gScoreNew = current.GScore + arcTime;
                    if (gScoreNew >= neighbor.GScore)
                    {
                        continue;
                    }

                    float fScoreNew = gScoreNew + TimeHeuristic(Position(neighbor),
                                                                destination,
                                                                mobility);

                    if (!_openSet.Contains(neighbor))
                    {
                        _openSet.Enqueue(neighbor, fScoreNew);
                    }
                    else
                    {
                        _openSet.UpdatePriority(neighbor, fScoreNew);
                    }
                    neighbor.GScore   = gScoreNew;
                    neighbor.CameFrom = current;
                }

                float arcTimeDest = Pathfinder.FOREVER;
                // checks can we get to the last mile without more pathfinding
                if (Vector3.Distance(Position(current), destination) < neighborSearchDistance)
                {
                    arcTimeDest = Pathfinder.FindLocalPath(this, Position(current), destination, mobility, unitRadius);
                }
                // Debug.Log(openSet.Count + " " + Position(current) + " " + current.isRoad + " " + Vector3.Distance(Position(current), destination) + " " + (current.gScore + arcTimeDest) + " " + gScoreDest);
                if (arcTimeDest >= Pathfinder.FOREVER)
                {
                    continue;
                }
                if (arcTimeDest < Pathfinder.FOREVER && command == MoveCommandType.NORMAL)
                {
                    arcTimeDest = 0f;
                }

                float gScoreDestNew = current.GScore + arcTimeDest;
                if (gScoreDestNew < gScoreDest)
                {
                    gScoreDest   = gScoreDestNew;
                    cameFromDest = current;
                }
            }

            // Reconstruct best path
            PathNode node = cameFromDest;

            while (node != null)
            {
                path.Add(node);
                node = node.CameFrom;
            }
            return(gScoreDest);
        }
示例#21
0
        public void MoveArc(Vector3D destination, float height, float gravity, ACDTranslateArcMessage baseMessage = null)
        {
            _SetupArcMove(destination, height, gravity);
            _moveCommand = MoveCommandType.Arc;

            if (baseMessage == null)
                baseMessage = new ACDTranslateArcMessage();

            baseMessage.ActorId = (int)this.Target.DynamicID;
            baseMessage.Start = this.Target.Position;
            baseMessage.Velocity = this.Velocity;
            baseMessage.Field6 = gravity;
            baseMessage.Field9 = destination.Z;

            this.Target.World.BroadcastIfRevealed(baseMessage, this.Target);
        }
示例#22
0
 public PathData(Vector3 currentPosition, Vector3 destinationPosition, MoveCommandType command)
 {
     CurrentPosition     = currentPosition;
     DestinationPosition = destinationPosition;
     Command             = command;
 }
示例#23
0
    // Run the A* algorithm and put the result in path
    // If no path was found, return 'forever' and put only the destination in path
    // Returns the total path time
    public float FindPath(
        List <PathNode> path,
        Vector3 start, Vector3 destination,
        MobilityType mobility, float unitRadius,
        MoveCommandType command)
    {
        path.Clear();
        path.Add(new PathNode(destination, false));

        PathNode cameFromDest = null;
        float    gScoreDest   = Pathfinder.FindLocalPath(this, start, destination, mobility, unitRadius);

        if (gScoreDest < Pathfinder.Forever)
        {
            if (command == MoveCommandType.Slow || command == MoveCommandType.Reverse)
            {
                return(gScoreDest);
            }
        }

        // Initialize with all nodes accessible from the starting point
        // (this can be optimized later by throwing out some from the start)
        openSet.Clear();
        foreach (PathNode neighbor in graph)
        {
            neighbor.isClosed = false;
            neighbor.cameFrom = null;
            neighbor.gScore   = Pathfinder.Forever;
            Vector3 neighborPos = Position(neighbor);

            if ((start - neighborPos).magnitude < ArcMaxDist)
            {
                float gScoreNew = Pathfinder.FindLocalPath(this, start, neighborPos, mobility, unitRadius);
                if (gScoreNew < Pathfinder.Forever)
                {
                    neighbor.gScore = gScoreNew;
                    float fScoreNew = gScoreNew + TimeHeuristic(neighborPos, destination, mobility);
                    openSet.Enqueue(neighbor, fScoreNew);
                }
            }
        }

        while (openSet.Count > 0)
        {
            PathNode current = openSet.Dequeue();
            current.isClosed = true;

            if (gScoreDest < current.Priority)
            {
                break;
            }

            foreach (PathArc arc in current.arcs)
            {
                PathNode neighbor = arc.node1 == current ? arc.node2 : arc.node1;

                if (neighbor.isClosed)
                {
                    continue;
                }

                float arcTime = arc.time[mobility.Index];
                if (arcTime >= Pathfinder.Forever)
                {
                    continue;
                }

                float gScoreNew = current.gScore + arcTime;
                if (gScoreNew >= neighbor.gScore)
                {
                    continue;
                }

                float fScoreNew = gScoreNew + TimeHeuristic(Position(neighbor), destination, mobility);

                if (!openSet.Contains(neighbor))
                {
                    openSet.Enqueue(neighbor, fScoreNew);
                }
                else
                {
                    openSet.UpdatePriority(neighbor, fScoreNew);
                }
                neighbor.gScore   = gScoreNew;
                neighbor.cameFrom = current;
            }

            float arcTimeDest = Pathfinder.Forever;
            if (Vector3.Distance(Position(current), destination) < ArcMaxDist)
            {
                arcTimeDest = Pathfinder.FindLocalPath(this, Position(current), destination, mobility, unitRadius);
            }
            // Debug.Log(openSet.Count + " " + Position(current) + " " + current.isRoad + " " + Vector3.Distance(Position(current), destination) + " " + (current.gScore + arcTimeDest) + " " + gScoreDest);
            if (arcTimeDest >= Pathfinder.Forever)
            {
                continue;
            }
            if (arcTimeDest < Pathfinder.Forever && command == MoveCommandType.Slow)
            {
                arcTimeDest = 0f;
            }

            float gScoreDestNew = current.gScore + arcTimeDest;
            if (gScoreDestNew < gScoreDest)
            {
                gScoreDest   = gScoreDestNew;
                cameFromDest = current;
            }
        }

        // Reconstruct best path
        PathNode node = cameFromDest;

        while (node != null)
        {
            path.Add(node);
            node = node.cameFrom;
        }
        return(gScoreDest);
    }
示例#24
0
 public void SetDestination(
     Vector3 pos,
     float heading            = MovementComponent.NO_HEADING,
     MoveCommandType moveMode = MoveCommandType.FAST) =>
 _movementComponent.SetDestination(pos, heading, moveMode);
示例#25
0
 public static MoveCommand GetCommandByEnum(MoveCommandType type)
 {
     return(Instance._moveCommands[(int)type].Clone());
 }
示例#26
0
 public MoveCommand this[MoveCommandType type]
 {
     get => _moveCommands[(int)type].Clone();