/// <summary> /// Calculates the force to apply to the vehicle to reach a point /// </summary> /// <returns> /// A <see cref="Vector3"/> /// </returns> protected override Vector3 CalculateForce() { var difference = Target.forward; difference.Scale(_distance); return(Vehicle.GetSeekVector(Target.position - difference, _considerVelocity)); }
/// <summary> /// Force to apply to the vehicle /// </summary> /// <returns> /// A <see cref="Vector3"/> /// </returns> protected override Vector3 CalculateForce() { Vector3 force = Vector3.zero; if (_path != null) { while (force == Vector3.zero && _currentNode < _path.SegmentCount) { var node = _path.Path[_currentNode]; force = Vehicle.GetSeekVector(node, false); if (force == Vector3.zero) { _currentNode++; } } } return(force); }
/// <summary> /// Force to apply to the vehicle /// </summary> /// <returns> /// A <see cref="Vector3"/> /// </returns> protected override Vector3 CalculateForce() { Vector3 forceNode = Vector3.zero; if (_path != null) { var tStruct = new PathRelativePosition(); var futurePosition = Vehicle.PredictFuturePosition(_predictionTime); var futurePathPoint = _path.MapPointToPath(futurePosition, ref tStruct); #if TRACE_PATH Debug.DrawLine(Vehicle.Position, futurePosition, Color.red); Debug.DrawLine(Vehicle.Position, futurePathPoint, Color.green); #endif forceNode = Vehicle.GetSeekVector(futurePathPoint, false); } return(forceNode); }
/// <summary> /// Calculates the force to apply to the vehicle to reach a point /// </summary> /// <returns> /// A <see cref="Vector3"/> /// </returns> protected override Vector3 CalculateForce() { return(Vehicle.GetSeekVector(TargetPoint, _considerVelocity)); }
/// <summary> /// Should the force be calculated? /// </summary> /// <returns> /// A <see cref="Vector3"/> /// </returns> protected override Vector3 CalculateForce() { if (Path == null || Path.SegmentCount < 2) { return(Vector3.zero); } // If the vehicle's speed is 0, use a low speed for future position // calculation. Otherwise the vehicle will remain where it is if he // starts within the path, because its current position matches its // future path position float speed = (Vehicle.Speed > _minSpeedToConsider) ? Vehicle.Speed : _minSpeedToConsider + _predictionTime; // our goal will be offset from our path distance by this amount float pathDistanceOffset = _predictionTime * speed; // measure distance along path of our current and predicted positions DistanceAlongPath = Path.MapPointToPathDistance(Vehicle.Position); /* * Otherwise we need to steer towards a target point obtained * by adding pathDistanceOffset to our current path position. * * Notice that this method does not steer for the point in the * path that is closest to our future position, which is why * we don't calculate the closest point in the path to our future * position. * * Instead, it estimates how far the vehicle will move in units, * and then aim for the point in the path that is that many units * away from our current path position _in path length_. This * means that it adds up the segment lengths and aims for the point * that is N units along the length of the path, which can imply * bends and turns and is not a straight vector projected away * from our position. */ float targetPathDistance = DistanceAlongPath + pathDistanceOffset; var target = Path.MapPathDistanceToPoint(targetPathDistance); /* * Return steering to seek target on path. * * If you set the considerVelocity parameter to true, it'll slow * down at each target to try to ease its arrival, which will * likely cause it to come to a stand still at low prediction * times. * */ var seek = Vehicle.GetSeekVector(target, false); if (seek == Vector3.zero && targetPathDistance <= Path.TotalPathLength) { /* * If we should not displace but still have some distance to go, * that means that we've encountered an edge case: a relatively low * vehicle speed and short prediction range, combined with a path * that twists. In that case, it's possible that the predicted future * point just around the bend is still within the vehicle's arrival * radius. In that case, aim a bit further beyond the vehicle's * arrival radius so that it can continue moving. * * TODO: Consider simply adding the arrivalradius displacement to * where we're aiming to from the get go. Might leave as is, considering * that this is supposed to be just a sample behavior. */ target = Path.MapPathDistanceToPoint(targetPathDistance + 1.5f * Vehicle.ArrivalRadius); seek = Vehicle.GetSeekVector(target, false); } return(seek); }
protected override Vector3 CalculateForce() { if (_quarry == null) { this.enabled = false; return(Vector3.zero); } var force = Vector3.zero; var offset = _quarry.Position - Vehicle.Position; var distance = offset.magnitude; var radius = Vehicle.ScaledRadius + _quarry.ScaledRadius + _acceptableDistance; if (distance > radius) { Vector3 unitOffset = offset / distance; // how parallel are the paths of "this" and the quarry // (1 means parallel, 0 is pependicular, -1 is anti-parallel) float parallelness = Vector3.Dot(transform.forward, _quarry.transform.forward); // how "forward" is the direction to the quarry // (1 means dead ahead, 0 is directly to the side, -1 is straight back) float forwardness = Vector3.Dot(transform.forward, unitOffset); float directTravelTime = distance / Vehicle.Speed; int f = OpenSteerUtility.intervalComparison(forwardness, -0.707f, 0.707f); int p = OpenSteerUtility.intervalComparison(parallelness, -0.707f, 0.707f); float timeFactor = 0; // to be filled in below // Break the pursuit into nine cases, the cross product of the // quarry being [ahead, aside, or behind] us and heading // [parallel, perpendicular, or anti-parallel] to us. switch (f) { case +1: switch (p) { case +1: // ahead, parallel timeFactor = 4; break; case 0: // ahead, perpendicular timeFactor = 1.8f; break; case -1: // ahead, anti-parallel timeFactor = 0.85f; break; } break; case 0: switch (p) { case +1: // aside, parallel timeFactor = 1; break; case 0: // aside, perpendicular timeFactor = 0.8f; break; case -1: // aside, anti-parallel timeFactor = 4; break; } break; case -1: switch (p) { case +1: // behind, parallel timeFactor = 0.5f; break; case 0: // behind, perpendicular timeFactor = 2; break; case -1: // behind, anti-parallel timeFactor = 2; break; } break; } // estimated time until intercept of quarry float et = directTravelTime * timeFactor; float etl = (et > _maxPredictionTime) ? _maxPredictionTime : et; // estimated position of quarry at intercept Vector3 target = _quarry.PredictFuturePosition(etl); force = Vehicle.GetSeekVector(target, _slowDownOnApproach); #if ANNOTATE_PURSUIT Debug.DrawRay(Vehicle.Position, force, Color.blue); Debug.DrawLine(Quarry.Position, target, Color.cyan); Debug.DrawRay(target, Vector3.up * 4, Color.cyan); #endif } return(force); }
/// <summary> /// Calculates the force to apply to a vehicle to reach a target transform /// </summary> /// <returns> /// Force to apply <see cref="Vector3"/> /// </returns> protected override Vector3 CalculateForce() { return(Vehicle.GetSeekVector(Target.position)); }