Beispiel #1
0
 /** \copydoc Pathfinding::IAstarAI::Teleport */
 public virtual void Teleport(Vector3 newPosition, bool clearPath = true)
 {
     if (clearPath)
     {
         CancelCurrentPathRequest();
     }
     prevPosition1 = prevPosition2 = simulatedPosition = newPosition;
     if (updatePosition)
     {
         tr.position = newPosition;
     }
     if (rvoController != null)
     {
         rvoController.Move(Vector3.zero);
     }
     if (clearPath)
     {
         SearchPath();
     }
 }
Beispiel #2
0
    public virtual void Update()
    {
        if (uLogic.isMoving == true)
        {
            canMove   = true;
            canSearch = true;
        }
        else
        {
            canMove   = false;
            canSearch = false;
        }

        if (!canMove)
        {
            return;
        }

        Vector3 dir = CalculateVelocity(GetFeetPosition());

        //Rotate towards targetDirection (filled in by CalculateVelocity)
        RotateTowards(targetDirection);

        if (rvoController != null && canMove == true)
        {
            rvoController.Move(dir);
        }
        else
        if (controller != null)
        {
            controller.SimpleMove(dir);
        }
        else if (rigid != null)
        {
            rigid.AddForce(dir);
        }
        else
        {
            tr.Translate(dir * Time.deltaTime, Space.World);
        }
    }
Beispiel #3
0
        public virtual void Update()
        {
            if (!CanMove)
            {
                return;
            }

            if (m_CurrentMovePosition != m_Controller.Creature.Move.MovePosition)
            {
                TrySearchPath();
            }

            Vector3 _dir = CalculateVelocity(GetFeetPosition());

            //Rotate towards targetDirection (filled in by CalculateVelocity)
            RotateTowards(m_TargetDirection);

#if RVOImp
            if (m_RVOController != null)
            {
                m_RVOController.maxSpeed      = m_Controller.MoveForwardVelocity;
                m_RVOController.rotationSpeed = m_Controller.MoveAngularVelocity;
                m_RVOController.Move(_dir);
            }
            else
#endif
            if (m_CharacterController != null)
            {
                m_CharacterController.SimpleMove(_dir);
            }
            else if (m_Rigidbody != null)
            {
                m_Rigidbody.AddForce(_dir);
            }
            else
            {
                m_Transform.Translate(_dir * Time.deltaTime, Space.World);
            }
        }
Beispiel #4
0
    public virtual void Update()
    {
        if (!canMove)
        {
            return;
        }

        Vector3 dir = CalculateVelocity(GetFeetPosition());

        //Rotate towards targetDirection (filled in by CalculateVelocity)
        if (targetDirection != Vector3.zero)
        {
            RotateTowards(targetDirection);
        }

        if (rvoController != null)
        {
            rvoController.Move(dir);
        }
        else
        if (navController != null)
        {
            navController.SimpleMove(GetFeetPosition(), dir);
        }
        else if (controller != null)
        {
            controller.SimpleMove(dir);
        }
        else if (rigid != null)
        {
            rigid.AddForce(dir);
        }
        else
        {
            transform.Translate(dir * Time.deltaTime, Space.World);
        }
    }
Beispiel #5
0
    public void Update()
    {
        //
        if (Time.time >= nextRepath && canSearchAgain)
        {
            RecalculatePath();
        }
        //
        Vector3 dir = Vector3.zero;
        Vector3 pos = transform.position;

        //
        if (vectorPath != null && vectorPath.Count != 0)
        {
            Vector3 waypoint = vectorPath[wp];
            waypoint.y = pos.y;

            while ((pos - waypoint).sqrMagnitude < moveNextDist * moveNextDist && wp != vectorPath.Count - 1)
            {
                wp++;
                waypoint   = vectorPath[wp];
                waypoint.y = pos.y;
            }

            dir = waypoint - pos;
            float magn = dir.magnitude;
            if (magn > 0)
            {
                float newmagn = Mathf.Min(magn, controller.maxSpeed);
                dir *= newmagn / magn;
            }
            //dir = Vector3.ClampMagnitude (waypoint - pos, 1.0f) * maxSpeed;
        }
        //
        controller.Move(dir);
    }
Beispiel #6
0
        /** Update is called once per frame */
        protected virtual void Update()
        {
            deltaTime = Mathf.Min(Time.smoothDeltaTime * 2, Time.deltaTime);

            if (rp != null)
            {
                //System.Diagnostics.Stopwatch w = new System.Diagnostics.Stopwatch();
                //w.Start();
                RichPathPart pt = rp.GetCurrentPart();
                var          fn = pt as RichFunnel;
                if (fn != null)
                {
                    //Clear buffers for reuse
                    Vector3 position = UpdateTarget(fn);

                    //tr.position = ps;

                    //Only get walls every 5th frame to save on performance
                    if (Time.frameCount % 5 == 0 && wallForce > 0 && wallDist > 0)
                    {
                        wallBuffer.Clear();
                        fn.FindWalls(wallBuffer, wallDist);
                    }

                    /*for (int i=0;i<wallBuffer.Count;i+=2) {
                     *  Debug.DrawLine (wallBuffer[i],wallBuffer[i+1],Color.magenta);
                     * }*/

                    //Pick next waypoint if current is reached
                    int tgIndex = 0;

                    /*if (buffer.Count > 1) {
                     *  if ((buffer[tgIndex]-tr.position).sqrMagnitude < pickNextWaypointDist*pickNextWaypointDist) {
                     *      tgIndex++;
                     *  }
                     * }*/


                    //Target point
                    Vector3 tg  = buffer[tgIndex];
                    Vector3 dir = tg - position;
                    dir.y = 0;

                    bool passedTarget = Vector3.Dot(dir, currentTargetDirection) < 0;
                    //Check if passed target in another way
                    if (passedTarget && buffer.Count - tgIndex > 1)
                    {
                        tgIndex++;
                        tg = buffer[tgIndex];
                    }

                    if (tg != lastTargetPoint)
                    {
                        currentTargetDirection   = (tg - position);
                        currentTargetDirection.y = 0;
                        currentTargetDirection.Normalize();
                        lastTargetPoint = tg;
                        //Debug.DrawRay (tr.position, Vector3.down*2,Color.blue,0.2f);
                    }

                    //Direction to target
                    dir   = (tg - position);
                    dir.y = 0;
                    float magn = dir.magnitude;

                    //Write out for other scripts to read
                    distanceToWaypoint = magn;

                    //Normalize
                    dir = magn == 0 ? Vector3.zero : dir / magn;
                    Vector3 normdir = dir;

                    Vector3 force = Vector3.zero;

                    if (wallForce > 0 && wallDist > 0)
                    {
                        float wLeft  = 0;
                        float wRight = 0;

                        for (int i = 0; i < wallBuffer.Count; i += 2)
                        {
                            Vector3 closest = VectorMath.ClosestPointOnSegment(wallBuffer[i], wallBuffer[i + 1], tr.position);
                            float   dist    = (closest - position).sqrMagnitude;

                            if (dist > wallDist * wallDist)
                            {
                                continue;
                            }

                            Vector3 tang = (wallBuffer[i + 1] - wallBuffer[i]).normalized;

                            //Using the fact that all walls are laid out clockwise (seeing from inside)
                            //Then left and right (ish) can be figured out like this
                            float dot = Vector3.Dot(dir, tang) * (1 - System.Math.Max(0, (2 * (dist / (wallDist * wallDist)) - 1)));
                            if (dot > 0)
                            {
                                wRight = System.Math.Max(wRight, dot);
                            }
                            else
                            {
                                wLeft = System.Math.Max(wLeft, -dot);
                            }
                        }

                        Vector3 norm = Vector3.Cross(Vector3.up, dir);
                        force = norm * (wRight - wLeft);

                        //Debug.DrawRay (tr.position, force, Color.cyan);
                    }

                    //Is the endpoint of the path (part) the current target point
                    bool endPointIsTarget = lastCorner && buffer.Count - tgIndex == 1;

                    if (endPointIsTarget)
                    {
                        //Use 2nd or 3rd degree motion equation to figure out acceleration to reach target in "exact" [slowdownTime] seconds

                        //Clamp to avoid divide by zero
                        if (slowdownTime < 0.001f)
                        {
                            slowdownTime = 0.001f;
                        }

                        Vector3 diff = tg - position;
                        diff.y = 0;

                        if (preciseSlowdown)
                        {
                            //{ t = slowdownTime
                            //{ diff = vt + at^2/2 + qt^3/6
                            //{ 0 = at + qt^2/2
                            //{ solve for a
                            dir = (6 * diff - 4 * slowdownTime * velocity) / (slowdownTime * slowdownTime);
                        }
                        else
                        {
                            dir = 2 * (diff - slowdownTime * velocity) / (slowdownTime * slowdownTime);
                        }
                        dir = Vector3.ClampMagnitude(dir, acceleration);

                        force *= System.Math.Min(magn / 0.5f, 1);

                        if (magn < endReachedDistance)
                        {
                            //END REACHED
                            NextPart();
                        }
                    }
                    else
                    {
                        dir *= acceleration;
                    }

                    //Debug.DrawRay (tr.position+Vector3.up, dir*3, Color.blue);

                    velocity += (dir + force * wallForce) * deltaTime;

                    if (slowWhenNotFacingTarget)
                    {
                        float dot = (Vector3.Dot(normdir, tr.forward) + 0.5f) * (1.0f / 1.5f);
                        //velocity = Vector3.ClampMagnitude (velocity, maxSpeed * Mathf.Max (dot, 0.2f) );
                        float xzmagn = Mathf.Sqrt(velocity.x * velocity.x + velocity.z * velocity.z);
                        float prevy  = velocity.y;
                        velocity.y = 0;
                        float mg = Mathf.Min(xzmagn, maxSpeed * Mathf.Max(dot, 0.2f));
                        velocity = Vector3.Lerp(tr.forward * mg, velocity.normalized * mg, Mathf.Clamp(endPointIsTarget ? (magn * 2) : 0, 0.5f, 1.0f));

                        velocity.y = prevy;
                    }
                    else
                    {
                        // Clamp magnitude on the XZ axes
                        float xzmagn = Mathf.Sqrt(velocity.x * velocity.x + velocity.z * velocity.z);
                        xzmagn = maxSpeed / xzmagn;
                        if (xzmagn < 1)
                        {
                            velocity.x *= xzmagn;
                            velocity.z *= xzmagn;
                            //Vector3.ClampMagnitude (velocity, maxSpeed);
                        }
                    }

                    //Debug.DrawLine (tr.position, tg, lastCorner ? Color.red : Color.green);


                    if (endPointIsTarget)
                    {
                        Vector3 trotdir = Vector3.Lerp(velocity, currentTargetDirection, System.Math.Max(1 - magn * 2, 0));
                        RotateTowards(trotdir);
                    }
                    else
                    {
                        RotateTowards(velocity);
                    }

                    //Applied after rotation to enable proper checks on if velocity is zero
                    velocity += deltaTime * gravity;

                    if (rvoController != null && rvoController.enabled)
                    {
                        //Use RVOController
                        tr.position = position;
                        rvoController.Move(velocity);
                    }
                    else
                    if (controller != null && controller.enabled)
                    {
                        //Use CharacterController
                        tr.position = position;
                        controller.Move(velocity * deltaTime);
                    }
                    else
                    {
                        //Use Transform
                        float lasty = position.y;
                        position += velocity * deltaTime;

                        position = RaycastPosition(position, lasty);

                        tr.position = position;
                    }
                }
                else
                {
                    if (rvoController != null && rvoController.enabled)
                    {
                        //Use RVOController
                        rvoController.Move(Vector3.zero);
                    }
                }

                if (pt is RichSpecial)
                {
                    if (!traversingSpecialPath)
                    {
                        StartCoroutine(TraverseSpecial(pt as RichSpecial));
                    }
                }
                //w.Stop();
                //Debug.Log ((w.Elapsed.TotalMilliseconds*1000));
            }
            else
            {
                if (rvoController != null && rvoController.enabled)
                {
                    //Use RVOController
                    rvoController.Move(Vector3.zero);
                }
                else
                if (controller != null && controller.enabled)
                {
                }
                else
                {
                    tr.position = RaycastPosition(tr.position, tr.position.y);
                }
            }
        }
Beispiel #7
0
        public void Move()
        {
            Debug.Log("Move");
            // previous path is not cleared on reload. That's why it's finishing and why there's no error !!!!!!
            if (controllerType == ControllerType.rvoController || (controllerType == ControllerType.available && controller2 != null))
            {
                if (controller2 != null)
                {
                    controller2.Move(direction);
                    controller2.maxSpeed = (direction).magnitude;
                }
                else
                {
                    if (LogEvents.Value)
                    {
                        Debug.Log("Astar Move To failed. The controller was removed");
                    }

                    Fsm.Event(failedEvent);
                    Finish();
                    return;
                }
            }

            if (controllerType == ControllerType.characterController || (controllerType == ControllerType.available && controller != null))
            {
                if (controller != null)
                {
                    controller.SimpleMove(direction);
                }
                else
                {
                    if (LogEvents.Value)
                    {
                        Debug.Log("Astar Move To failed. The controller was removed");
                    }
                    Fsm.Event(failedEvent); Finish(); return;
                }
            }
            if (controllerType == ControllerType.rigidbody || controllerType == ControllerType.rigidbodyVelocity)
            {
                if (controllerType == ControllerType.rigidbody && rigidbody != null)
                {
                    rigidbody.AddForce(direction * Time.deltaTime * 100 * rigidbody.mass);
                }

                else if ((controllerType == ControllerType.rigidbodyVelocity || controllerType == ControllerType.available) && rigidbody != null)
                {
                    if (ignoreY.Value)
                    {
                        rigidbody.velocity = new Vector3(direction.x, rigidbody.velocity.y, direction.z) * 110;
                    }
                    else
                    {
                        rigidbody.velocity = direction * Time.deltaTime * 110;
                    }

                    rigidbody.WakeUp();
                }
                else
                {
                    if (LogEvents.Value)
                    {
                        Debug.Log("Astar Move To failed. The rigidbody controller was removed");
                    }
                    Fsm.Event(failedEvent);
                    Finish();
                    return;
                }
            }

            if (controllerType == ControllerType.transform || (controllerType == ControllerType.available && controller2 == null && controller == null && rigidbody == null))
            {
                go.transform.position += direction * Time.deltaTime;
            }
        }
Beispiel #8
0
        public override void OnEnter()
        {
            if (moveMode == MoveMode.followPath)
            {
                path = FsmConverter.GetPath(inputPath);
                if (path == null)
                {
                    if (LogEvents.Value)
                    {
                        Debug.Log("Astar Follow Path failed. The path is null");
                    }

                    Fsm.Event(failedEvent);
                    Finish();
                    return;
                }
                else if (path.vectorPath.Count == 0)
                {
                    if (LogEvents.Value)
                    {
                        Debug.Log("Astar Follow Path failed. The path contains no nodes");
                    }

                    Fsm.Event(failedEvent);
                    Finish();
                    return;
                }
            }

            currentWaypoint = 0;
            go = actor.OwnerOption == OwnerDefaultOption.UseOwner ? Owner : actor.GameObject.Value;
            if (go == null)
            {
                if (LogEvents.Value)
                {
                    Debug.Log("Astar Move To failed. The actor is null");
                }

                Fsm.Event(failedEvent);
                Finish();
                return;
            }            //finish the action if any of the requirements are not met

            controller  = go.GetComponent <CharacterController>();
            controller2 = go.GetComponent <RVOController>();
            rigidbody   = go.GetComponent <Rigidbody>();

            if (controllerType == ControllerType.characterController && controller == null)
            {
                controller = go.AddComponent <CharacterController>();
            }
            else if (controllerType == ControllerType.rvoController && controller2 == null)
            {
                if (AstarPath.HasPro)
                {
                    controller2 = go.AddComponent <RVOController>();
                    controller2.Move(new Vector3(0, 0, 0));
                }
                else
                {
                    controllerType = ControllerType.characterController;                    //free version can't use RVOControllers

                    if (controller == null)
                    {
                        controller = go.AddComponent <CharacterController>();
                    }
                }
            }
            else if (controllerType == ControllerType.rigidbody && rigidbody == null)
            {
                rigidbody                = go.AddComponent <Rigidbody>();
                rigidbody.drag           = 0.5f;
                rigidbody.freezeRotation = true;
            }
            else if (controllerType == ControllerType.rigidbodyVelocity && rigidbody == null)
            {
                rigidbody = go.AddComponent <Rigidbody>();
                rigidbody.freezeRotation = true;
            }

            if (moveMode != MoveMode.followPath)
            {
                CalculatePath();
            }

            if (moveMode == MoveMode.followPath && !startAtStart.Value)
            {
                currentWaypoint = getClosest();
            }


            if (moveMode == MoveMode.followPath && connectPath.Value)
            {
                done = false;
                ConnectPathX();
            }
        }
	void Start()
	{
        rvo = GetComponent<RVOController>();
        rvo.Move(Vector3.right * speed);
        rvo.maxSpeed = speed;
	}
        public void Update()
        {
            if (stop)
            {
                return;
            }
            UpdatePath();

            //nextWaypointDistance = Vector3.Distance(go.transform.position,nextPos);
            // If there is no InputPath yet.
            if (InputPath == null)
            {
                return;
            }
            if (currentWaypoint >= (InputPath.vectorPath).Count)
            {
                InputPath = null;
                if (controller2 != null)                 //NVO controller needs to be set to 0/0/0 , else it continues running.
                {
                    controller2.Move(new Vector3(0, 0, 0));
                }
                Destroy(go.GetComponent <FsmMoveOnPath>());
                return;
            }
            nextPos = InputPath.vectorPath[currentWaypoint];

            // Direction to the next waypoint.
            direction    = (nextPos - go.transform.position).normalized;
            directionOut = direction;

            if (ignoreY)
            {
                direction.y = 0;
                direction   = direction.normalized;
            }

            var multiplier = (float)((1 / Math.Exp(costDependendSpeed * InputPath.path[currentWaypoint].penalty)) * speed * Time.fixedDeltaTime);

            direction.x *= multiplier;
            direction.y *= multiplier;
            direction.z *= multiplier;

            if (controller2 != null)
            {
                controller2.Move(direction);
                controller2.maxSpeed = (float)((1 / Math.Exp(costDependendSpeed * InputPath.path[currentWaypoint].penalty)) * speed);
            }
            else
            {
                controller.SimpleMove(direction);
            }

            // Check if we are close enough to the next waypoint.
            dist = Vector3.Distance(go.transform.position, nextPos);
            if (dist < nextWaypointDistance)
            {                   //Debug.Log(doo.Value.vectorPath[currentWaypoint]);
                if (currentWaypoint >= (InputPath.vectorPath).Count - 1)
                {
                    if (dist >= finishDistance)
                    {
                        return;
                    }
                }
                // Proceed to follow the next waypoint.
                currentWaypoint++;
                return;
            }
        }
Beispiel #11
0
    /// <summary>
    /// Moves and Rotates the Character
    /// </summary>
    public TaskStatus MoveCharacter()
    {
        // Move Character towards next waypoint
        if (path != null)
        {
            // Path only has one Waypoint - NPC is at target position already
            if (path.vectorPath.Count == 1)
            {
                path = null;
                currentPathWaypoint = 1;
                if (useRVO)
                {
                    controller.Move(Vector3.zero);
                }
                return(TaskStatus.Success);
            }

            ///////////////////////
            // SET POSITION
            // Get new Position
            Vector2 currentPos  = new Vector2(transform.position.x, transform.position.z);
            Vector2 waypointPos = new Vector2(path.vectorPath[currentPathWaypoint].x, path.vectorPath[currentPathWaypoint].z);
            Vector2 dir         = (waypointPos - currentPos).normalized;
            Vector2 newPos      = currentPos + dir * moveSpeed * Time.deltaTime;

            // Get position Height
            RaycastHit hit;
            float      height = 0;
            if (Physics.Raycast(new Vector3(newPos.x, transform.position.y + characterHeight, newPos.y), -Vector3.up * characterHeight * 2, out hit))
            {
                height = hit.point.y;
            }

            /////////////////////
            // SET ROTATION
            Quaternion currentRotation = transform.rotation;
            transform.LookAt(new Vector3(newPos.x, transform.position.y, newPos.y));
            Quaternion newRotation = transform.rotation;
            transform.rotation = Quaternion.Slerp(currentRotation, newRotation, rotSpeed * Time.deltaTime);

            // Move Character
            if (!useRVO)
            {
                transform.position = new Vector3(newPos.x, height, newPos.y);
            }
            else
            {
                controller.Move((new Vector3(newPos.x, transform.position.y, newPos.y) - transform.position).normalized * moveSpeed);
            }

            // Check if the Character's distance to the target location is close enough to move on to the next waypoint
            if (Vector2.Distance(newPos, waypointPos) < errorMargin)
            {
                currentPathWaypoint++;
            }

            // Target Reached - Abort Movement
            if (currentPathWaypoint == path.vectorPath.Count)
            {
                path = null;
                currentPathWaypoint = 1;
                if (useRVO)
                {
                    controller.Move(Vector3.zero);
                }
                return(TaskStatus.Success);
            }
            else
            {
                return(TaskStatus.Running);
            }
        }
        else
        {
            return(TaskStatus.Running);
        }
    }
Beispiel #12
0
        /** Update is called once per frame */
        protected virtual void Update()
        {
            deltaTime = Mathf.Min(Time.smoothDeltaTime * 2, Time.deltaTime);

            if (rp != null)
            {
                RichPathPart currentPart = rp.GetCurrentPart();
                var          fn          = currentPart as RichFunnel;
                if (fn != null)
                {
                    // Clamp the current position to the navmesh
                    // and update the list of upcoming corners in the path
                    // and store that in the 'nextCorners' variable
                    Vector3 position = UpdateTarget(fn);

                    // Only get walls every 5th frame to save on performance
                    if (Time.frameCount % 5 == 0 && wallForce > 0 && wallDist > 0)
                    {
                        wallBuffer.Clear();
                        fn.FindWalls(wallBuffer, wallDist);
                    }

                    // Target point
                    int     tgIndex     = 0;
                    Vector3 targetPoint = nextCorners[tgIndex];
                    Vector3 dir         = targetPoint - position;
                    dir.y = 0;

                    bool passedTarget = Vector3.Dot(dir, currentTargetDirection) < 0;
                    // Check if passed target in another way
                    if (passedTarget && nextCorners.Count - tgIndex > 1)
                    {
                        tgIndex++;
                        targetPoint = nextCorners[tgIndex];
                    }

                    // Check if the target point changed compared to last frame
                    if (targetPoint != lastTargetPoint)
                    {
                        currentTargetDirection   = targetPoint - position;
                        currentTargetDirection.y = 0;
                        currentTargetDirection.Normalize();
                        lastTargetPoint = targetPoint;
                    }

                    // Direction to target
                    dir   = targetPoint - position;
                    dir.y = 0;

                    // Normalized direction
                    Vector3 normdir = VectorMath.Normalize(dir, out distanceToWaypoint);

                    // Is the endpoint of the path (part) the current target point
                    bool targetIsEndPoint = lastCorner && nextCorners.Count - tgIndex == 1;

                    // When very close to the target point, move directly towards the target
                    // instead of using accelerations as they tend to be a bit jittery in this case
                    if (targetIsEndPoint && distanceToWaypoint < 0.01f * maxSpeed)
                    {
                        // Velocity will be at most 1 times max speed, it will be further clamped below
                        velocity = (targetPoint - position) * 100;
                    }
                    else
                    {
                        // Calculate force from walls
                        Vector3 wallForceVector = CalculateWallForce(position, normdir);
                        Vector2 accelerationVector;

                        if (targetIsEndPoint)
                        {
                            accelerationVector = CalculateAccelerationToReachPoint(To2D(targetPoint - position), Vector2.zero, To2D(velocity));
                            //accelerationVector = Vector3.ClampMagnitude(accelerationVector, acceleration);

                            // Reduce the wall avoidance force as we get closer to our target
                            wallForceVector *= System.Math.Min(distanceToWaypoint / 0.5f, 1);

                            if (distanceToWaypoint < endReachedDistance)
                            {
                                // END REACHED
                                NextPart();
                            }
                        }
                        else
                        {
                            var nextNextCorner = tgIndex < nextCorners.Count - 1 ? nextCorners[tgIndex + 1] : (targetPoint - position) * 2 + position;
                            var targetVelocity = (nextNextCorner - targetPoint).normalized * maxSpeed;

                            accelerationVector = CalculateAccelerationToReachPoint(To2D(targetPoint - position), To2D(targetVelocity), To2D(velocity));
                        }

                        // Update the velocity using the acceleration
                        velocity += (new Vector3(accelerationVector.x, 0, accelerationVector.y) + wallForceVector * wallForce) * deltaTime;
                    }

                    var currentNode = fn.CurrentNode;

                    Vector3 closestOnNode;
                    if (currentNode != null)
                    {
                        closestOnNode = currentNode.ClosestPointOnNode(position);
                    }
                    else
                    {
                        closestOnNode = position;
                    }

                    // Distance to the end of the path (as the crow flies)
                    var distToEndOfPath = (fn.exactEnd - closestOnNode).magnitude;

                    // Max speed to use for this frame
                    var currentMaxSpeed = maxSpeed;
                    currentMaxSpeed *= Mathf.Sqrt(Mathf.Min(1, distToEndOfPath / (maxSpeed * slowdownTime)));

                    // Check if the agent should slow down in case it is not facing the direction it wants to move in
                    if (slowWhenNotFacingTarget)
                    {
                        // 1 when normdir is in the same direction as tr.forward
                        // 0.2 when they point in the opposite directions
                        float directionSpeedFactor = Mathf.Max((Vector3.Dot(normdir, tr.forward) + 0.5f) / 1.5f, 0.2f);
                        currentMaxSpeed *= directionSpeedFactor;
                        float currentSpeed = VectorMath.MagnitudeXZ(velocity);
                        float prevy        = velocity.y;
                        velocity.y   = 0;
                        currentSpeed = Mathf.Min(currentSpeed, currentMaxSpeed);

                        // Make sure the agent always moves in the forward direction
                        // except when getting close to the end of the path in which case
                        // the velocity can be in any direction
                        velocity = Vector3.Lerp(velocity.normalized * currentSpeed, tr.forward * currentSpeed, Mathf.Clamp(targetIsEndPoint ? distanceToWaypoint * 2 : 1, 0.0f, 0.5f));

                        velocity.y = prevy;
                    }
                    else
                    {
                        velocity = VectorMath.ClampMagnitudeXZ(velocity, currentMaxSpeed);
                    }

                    // Apply gravity
                    velocity += deltaTime * gravity;

                    if (rvoController != null && rvoController.enabled)
                    {
                        // Send a message to the RVOController that we want to move
                        // with this velocity. In the next simulation step, this velocity
                        // will be processed and it will be fed back the rvo controller
                        // and finally it will be used by this script when calling the
                        // CalculateMovementDelta method below

                        // Make sure that we don't move further than to the end point of the path
                        // If the RVO simulation FPS is low and we did not do this, the agent
                        // might overshoot the target a lot.
                        var rvoTarget = position + VectorMath.ClampMagnitudeXZ(velocity, distToEndOfPath);
                        rvoController.SetTarget(rvoTarget, VectorMath.MagnitudeXZ(velocity), maxSpeed);
                    }

                    // Direction and distance to move during this frame
                    Vector3 deltaPosition;
                    if (rvoController != null && rvoController.enabled)
                    {
                        // Use RVOController to get a processed delta position
                        // such that collisions will be avoided if possible
                        deltaPosition = rvoController.CalculateMovementDelta(position, deltaTime);

                        // The RVOController does not know about gravity
                        // so we copy it from the normal velocity calculation
                        deltaPosition.y = velocity.y * deltaTime;
                    }
                    else
                    {
                        deltaPosition = velocity * deltaTime;
                    }

                    if (targetIsEndPoint)
                    {
                        // Rotate towards the direction that the agent was in
                        // when the target point was seen for the first time
                        // TODO: Some magic constants here, should probably compute them from other variables
                        // or expose them as separate variables
                        Vector3 trotdir = Vector3.Lerp(deltaPosition.normalized, currentTargetDirection, System.Math.Max(1 - distanceToWaypoint * 2, 0));
                        RotateTowards(trotdir);
                    }
                    else
                    {
                        // Rotate towards the direction we are moving in
                        RotateTowards(deltaPosition);
                    }

                    if (controller != null && controller.enabled)
                    {
                        // Use CharacterController
                        tr.position = position;
                        controller.Move(deltaPosition);
                        // Grab the position after the movement to be able to take physics into account
                        position = tr.position;
                    }
                    else
                    {
                        // Use Transform
                        float lastY = position.y;
                        position += deltaPosition;
                        // Position the character on the ground
                        position = RaycastPosition(position, lastY);
                    }

                    // Clamp the position to the navmesh after movement is done
                    var clampedPosition = fn.ClampToNavmesh(position);

                    if (position != clampedPosition)
                    {
                        // The agent was outside the navmesh. Remove that component of the velocity
                        // so that the velocity only goes along the direction of the wall, not into it
                        var difference = clampedPosition - position;
                        velocity -= difference * Vector3.Dot(difference, velocity) / difference.sqrMagnitude;

                        // Make sure the RVO system knows that there was a collision here
                        // Otherwise other agents may think this agent continued to move forwards
                        // and avoidance quality may suffer
                        if (rvoController != null && rvoController.enabled)
                        {
                            rvoController.SetCollisionNormal(difference);
                        }
                    }

                    tr.position = clampedPosition;
                }
                else
                {
                    if (rvoController != null && rvoController.enabled)
                    {
                        //Use RVOController
                        rvoController.Move(Vector3.zero);
                    }
                }
                if (currentPart is RichSpecial)
                {
                    // The current path part is a special part, for example a link
                    // Movement during this part of the path is handled by the TraverseSpecial coroutine
                    if (!traversingSpecialPath)
                    {
                        StartCoroutine(TraverseSpecial(currentPart as RichSpecial));
                    }
                }
            }
            else
            {
                if (rvoController != null && rvoController.enabled)
                {
                    // Use RVOController
                    rvoController.Move(Vector3.zero);
                }
                else
                if (controller != null && controller.enabled)
                {
                }
                else
                {
                    tr.position = RaycastPosition(tr.position, tr.position.y);
                }
            }
        }
Beispiel #13
0
    public void Update()
    {
        if (Time.time >= nextRepath && canSearchAgain)
        {
            RecalculatePath();
        }

        Vector3 velocity = controller.velocity;

        if (velocity != Vector3.zero)
        {
            transform.rotation = Quaternion.LookRotation(velocity);
        }

        Vector3 dir = Vector3.zero;

        Vector3 pos = transform.position;

        if (vectorPath != null && vectorPath.Count != 0)
        {
            Vector3 waypoint = vectorPath[wp];
            waypoint.y = pos.y;

            while ((pos - waypoint).sqrMagnitude < moveNextDist * moveNextDist && wp != vectorPath.Count - 1)
            {
                wp++;
                waypoint   = vectorPath[wp];
                waypoint.y = pos.y;
            }

            dir = waypoint - pos;
            float magn = dir.magnitude;
            if (magn > 0)
            {
                float newmagn = Mathf.Min(magn, controller.maxSpeed);
                dir *= newmagn / magn;
            }
            //dir = Vector3.ClampMagnitude (waypoint - pos, 1.0f) * maxSpeed;
        }

        controller.Move(dir);

        /*Vector3 pos = position;
         *
         * RaycastHit hit;
         #if !AstarRelease
         * float height = astarRVO ? rvoAgent.Height : RVO.Simulator.Instance.getAgentHeight	(agentID);
         #else
         * float height = rvoAgent.Height;
         #endif
         *
         * Vector3 realPos = rvoAgent.Position;
         *
         * if (Physics.Raycast	(realPos + Vector3.up*height,Vector3.down, out hit, float.PositiveInfinity, mask)) {
         *      realPos.y = hit.point.y;
         * } else {
         *      realPos.y = 0;
         * }
         *
         #if !AstarRelease
         * if (!astarRVO)
         *      RVO.Simulator.Instance.setAgentYPosition(agentID,pos.y);
         * else
         #endif
         *      rvoAgent.Position = realPos;
         *
         * Vector3 velocity;
         *
         #if !AstarRelease
         * if (!astarRVO) {
         *      RVO.Vector2 _vel = RVO.Simulator.Instance.getAgentVelocity (agentID);
         *      velocity = new Vector3(-_vel.x(),0,-_vel.y());
         * } else
         #endif
         *      velocity = rvoAgent.Velocity;
         *
         * transform.position = pos;
         *
         *
         *
         * //Debug.DrawRay (pos,dir*10,Color.blue);
         *
         * if (astarRVO) {
         *      List<ObstacleVertex> obst = rvoAgent.NeighbourObstacles;
         *
         *      Vector3 force = Vector3.zero;
         *
         *      for (int i=0;i<obst.Count;i++) {
         *              Vector3 a = obst[i].position;
         *              Vector3 b = obst[i].next.position;
         *
         *              Vector3 closest = position - Mathfx.NearestPointStrict (a,b,position);
         *
         *              if (closest == a || closest == b) continue;
         *
         *              float dist = closest.sqrMagnitude;
         *              closest /= dist*falloff;
         *              force += closest;
         *      }
         *      Debug.DrawRay (position, dir + force*wallAvoidForce);
         *
         *      rvoAgent.DesiredVelocity = dir + force*wallAvoidForce;
         * } else {
         #if !AstarRelease
         *      RVO.Simulator.Instance.setAgentPrefVelocity (agentID, new RVO.Vector2 (dir.x,dir.z));
         #endif
         * }*/
    }
Beispiel #14
0
    public virtual void Update()
    {
        //if armor broken, cancel effect.
        if (armorOn && armorCount <= 0)
        {
            armorOn    = false;
            armorCount = 0;
        }

        GameObject target = null;

        if (!armorOn /*armor in line of sight*/)
        {
            //interrupt module
            //target = armor;
        }

        if (enemyHP < 5 /*&& medpack in line of sight*/)
        {
            //interrupt module
            //if(medPack is closer than current target)
            //target = medPack;
        }

        if (target != null)
        {
            goTo(target);
        }

        if (medPack > 0 /*&& ((enemy in com-check circle && has < some HP) || enemy is Boss)*/)
        {
            //interrupt module
            //useMedPack(enemy);
        }

        if (enemyHP <= 0)
        {
            if (medPack > 0)
            {
                dropItem();
            }
            Destroy(this.gameObject);
        }

        if (!canMove)
        {
            return;
        }

        Vector3 dir = CalculateVelocity(GetFeetPosition());

        //Rotate towards targetDirection (filled in by CalculateVelocity)
        RotateTowards(targetDirection);

        if (rvoController != null)
        {
            rvoController.Move(dir);
        }
        else
        if (navController != null)
        {
#if FALSE
            navController.SimpleMove(GetFeetPosition(), dir);
#endif
        }
        else if (controller != null)
        {
            controller.SimpleMove(dir);
        }
        else if (rigid != null)
        {
            rigid.AddForce(dir);
        }
        else
        {
            transform.Translate(dir * Time.deltaTime, Space.World);
        }
    }
        public void Update()
        {
            if (stop)
            {
                return;
            }
            if ((path == null || !(path.GetState() >= PathState.Returned)))
            {
                return;
            }

            if (pUpdate >= GoUpdate)
            {
                CalculatePath();
            }

            pUpdate += 1;             // count one frame on

            if (currentWaypoint >= (path.vectorPath).Count)
            {
                if (finishOnEnd)
                {
                    InputPath = null;
                    Destroy(go.GetComponent <FsmFollowTargetHelper>());
                }
                return;
            }
            nextPos = path.vectorPath[currentWaypoint];

            // Direction to the next waypoint.
            direction    = (nextPos - go.transform.position).normalized;
            directionOut = direction;

            if (ignoreY)
            {
                direction.y    = 0;
                directionOut.y = 0;
                directionOut   = directionOut.normalized;
                direction      = direction.normalized;
            }
            var multiplier = (float)((1 / Math.Exp(costDependendSpeed * path.path[currentWaypoint].penalty)) * speed * Time.fixedDeltaTime);

            direction.x *= multiplier;
            direction.y *= multiplier;
            direction.y *= multiplier;

            if (controller2 != null)
            {
                controller2.Move(direction);
                controller2.maxSpeed = (float)((1 / Math.Exp(costDependendSpeed * path.path[currentWaypoint].penalty)) * speed);
            }
            else
            {
                controller.SimpleMove(direction);
            }

            // Check if we are close enough to the next waypoint.
            dist = Vector3.Distance(go.transform.position, nextPos);
            if (dist < nextWaypointDistance)
            {
                if (currentWaypoint >= (path.vectorPath).Count - 1)
                {
                    if (dist >= finishDistance)
                    {
                        return;
                    }
                }
                // Proceed to follow the next waypoint.
                currentWaypoint++;
                return;
            }
        }