示例#1
0
 public override void OnTargetReached()
 {
     if (!_pathCompleted)
     {
         OnDestinationReached?.Invoke();
         _pathCompleted = true;
     }
 }
示例#2
0
 public void SetNavMeshAgentDestination(Vector3 targetDestination, OnDestinationReached onDestinationReached)
 {
     navMeshAgent.enabled = true;
     target = targetDestination;
     navMeshAgent.destination  = targetDestination;
     this.onDestinationReached = onDestinationReached;
     IsAgentDestinationReached = false;
     StartCoroutine(WaitTillAgentTeachsToDestination());
 }
示例#3
0
    private void Update()
    {
        float dist = agent.remainingDistance;

        //if (dist != Mathf.Infinity && agent.pathStatus == NavMeshPathStatus.PathComplete && agent.remainingDistance <= .3f)
        if (agent.remainingDistance <= agent.stoppingDistance)
        {
            OnDestinationReached?.Invoke();
        }
    }
示例#4
0
 private IEnumerator Move(MovementData data)
 {
     while (data.CoveredDistance < data.TargetDistance)
     {
         var distanceToCover = Mathf.Min(data.Speed * Time.deltaTime, data.TargetDistance - data.CoveredDistance);
         transform.position   += data.Direction * distanceToCover;
         data.CoveredDistance += distanceToCover;
         yield return(null);
     }
     OnDestinationReached?.Invoke();
 }
    // Update is called once per frame
    void Update()
    {
        if (!shouldMove)
        {
            return;
        }

        Vector3 difference = targetPosition - transform.position;

        float speedMultipler = difference.magnitude >= 1 ? 1 : difference.magnitude;

        if (difference.magnitude < 0.001f)
        {
            OnDestinationReached?.Invoke(this, new System.EventArgs());
            ForgetTarget();
        }
        else
        {
            difference.Normalize();
            mover.Move(difference.x * speedMultipler, difference.z * speedMultipler);
        }
    }
示例#6
0
    /// <summary>
    /// Make the agent follows the path
    /// </summary>
    /// <param name="_speed">speed</param>
    /// <returns></returns>
    public IEnumerator FollowPath(float _speed)
    {
        isMoving = true;
        TDS_CustomNavPath _pathToFollow = CurrentPath;
        int _index = 1;

        while (Vector3.Distance(transform.position, _pathToFollow.NavigationPoints.Last().Position) > .5f)
        {
            if (Vector3.Distance(transform.position, _pathToFollow.NavigationPoints[_index].Position) <= .5f)
            {
                _index = _index + 1;
            }
            transform.position = Vector3.MoveTowards(transform.position, _pathToFollow.NavigationPoints[_index].Position, Time.deltaTime * _speed);
            yield return(new WaitForEndOfFrame());
        }
        yield return(new WaitForEndOfFrame());

        pathState = CalculatingState.Waiting;
        isMoving  = false;
        CurrentPath.ClearPath();
        OnDestinationReached?.Invoke();
        yield break;
    }
示例#7
0
    /// <summary>
    /// Make the agent follows the path
    /// </summary>
    /// <returns></returns>
    IEnumerator FollowPath()
    {
        OnMovementStarted?.Invoke();
        isMoving = true;
        int            _pathIndex     = 1;
        List <Vector3> _followingPath = currentPath.PathPoints;  //List of points in the path

        /*STEERING*/
        //Predicted position is the position of the agent at the next frame
        Vector3 _predictedPosition;


        // Previous Position
        Vector3 _previousPosition = OffsetPosition;
        //Next Position
        Vector3 _nextPosition = _followingPath[1];


        Vector3 _dir;
        Vector3 _targetPosition;
        Vector3 _normalPoint;


        float _distance = 0;
        // Angle theta is the angle between forward and velocity direction
        float _theta;
        float _scalarProduct;

        RaycastHit _hitInfo;
        Ray        _ray;
        // List of directions to apply on the avoidance
        List <Vector3> _obstaclesPos = new List <Vector3>();


        /* First the velocity is equal to the normalized direction from the agent position to the next position */

        /* LEGACY
         * if (velocity == Vector3.zero)
         *  velocity = (_nextPosition - OffsetPosition) * speed;
         * Seek(_nextPosition);
         */

        while (Vector3.Distance(OffsetPosition, LastPosition) > radius)
        {
            /* Apply the velocity to the transform position multiply by the speed and by Time.deltaTime to move*/
            velocity            = velocity.normalized * speed;
            velocity            = Vector3.ClampMagnitude(velocity, speed);
            transform.position += velocity * Time.deltaTime;

            /* If the agent is close to the next position
             * Update the previous and the next point
             * Also update the pathIndex
             * if the pathindex is greater than the pathcount break the loop
             * else continue in the loop
             */
            if (Vector3.Distance(OffsetPosition, _nextPosition) <= radius)
            {
                //set the new previous position
                _previousPosition = _followingPath[_pathIndex];
                //Increasing path index
                _pathIndex++;
                if (_pathIndex > _followingPath.Count - 1)
                {
                    break;
                }
                //Set the new next Position
                _nextPosition = _followingPath[_pathIndex];
                Seek(_nextPosition);
                continue;
            }
            // Theta is equal to the angle between the velocity and the forward vector
            _theta = Vector3.SignedAngle(Vector3.forward, velocity, Vector3.up);

            //Cast each ray of the fieldOfView Array
            for (int i = 0; i < fieldOfView.Length; i++)
            {
                // Apply a offset rotation on the direction equal to the angle between the forward and the velocity (theta angle)
                _ray = new Ray(OffsetPosition,
                               new Vector3(Mathf.Sin(_theta * Mathf.Deg2Rad) * fieldOfView[i].z + Mathf.Cos(_theta * Mathf.Deg2Rad) * fieldOfView[i].x,
                                           0,
                                           Mathf.Cos(_theta * Mathf.Deg2Rad) * fieldOfView[i].z - Mathf.Sin(_theta * Mathf.Deg2Rad) * fieldOfView[i].x));
                //Cast the ray
                if (Physics.Raycast(_ray, out _hitInfo, detectionRange, avoidanceLayer.value))
                {
                    //If the hit object isn't a navsurface's child or the agent itself
                    if (!_hitInfo.transform.GetComponentInParent <NavMeshSurface>() && _hitInfo.collider.gameObject != this.gameObject)
                    {
                        // Add the direction to avoid to the list
                        _dir   = velocity - (_hitInfo.point - transform.position);
                        _dir.y = 0;
                        _obstaclesPos.Add(_dir);
                    }
                }
            }
            //If the obstacle position contains directions to follow in order to avoid the obstacle
            if (_obstaclesPos.Count > 0)
            {
                // Get the average direction to follow and avoid in this direction
                Vector3 _v = Vector3.zero;
                _obstaclesPos.ForEach(p => _v += p);
                Avoid(_v);
                _obstaclesPos = new List <Vector3>();
                yield return(null);

                continue;
            }
            /* Get the predicted Velocity and the Predicted position*/
            _predictedPosition = OffsetPosition + velocity;

            /*Get the transposed Position of the predicted position on the segment between the previous and the next point
             * The agent has to get closer while it's to far away from the path
             */
            _normalPoint = GeometryHelper.GetNormalPoint(_predictedPosition, _previousPosition, _nextPosition);


            /* Direction of the segment between the previous and the next position normalized in order to go further on the path
             * Targeted position is the normal point + an offset defined by the direction of the segment to go a little further on the path
             * If the target is out of the segment between the previous and the next position, the target position is the next position
             */
            _dir            = (_nextPosition - _previousPosition).normalized;
            _targetPosition = _normalPoint + _dir;

            /* Distance between the predicted position and the normal point on the segment
             * If the distance is greater than the radius, it has to steer to get closer
             */
            _distance      = Vector3.Distance(_predictedPosition, _normalPoint);
            _scalarProduct = Vector3.Dot(velocity.normalized, _dir.normalized);
            if (_distance > pathRadius / 2 || _scalarProduct == -1 || velocity == Vector3.zero)
            {
                Seek(_targetPosition);
            }
            yield return(null);
        }
        StopAgent();
        OnDestinationReached?.Invoke();
    }
 private void RaiseOnDestinationReached()
 {
     OnDestinationReached?.Invoke();
 }