public override void OnTargetReached() { if (!_pathCompleted) { OnDestinationReached?.Invoke(); _pathCompleted = true; } }
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(); } }
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); } }
/// <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; }
/// <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(); }