/// <summary> /// The <see cref="SteeringBehaviour.ResultDirection"/> is the direction to the desired <see /// cref="AIMArrive.Target"/>. The <see cref="SteeringBehaviour.ResultMagnitude"/> is obtained by mapping the /// current position of the agent to the two given radii. /// <para/> /// Note, with an inverse <see cref="RadiusSteeringBehaviour.RadiusMapping"/> the following holds true: the /// closer the agent is to the target, the greater the velocity increases. /// </summary> /// <returns>Returns always <c>true</c>.</returns> protected override bool StartSteering() { ResultDirection = percept.Position - self.Position; sqrOuterRadius = OuterRadius * OuterRadius; sqrInnerRadius = InnerRadius * InnerRadius; // If true, then agent is within the radius if (ResultDirection.sqrMagnitude < sqrOuterRadius) { // If true, then decreasing if (RadiusMapping == MappingType.Linear || RadiusMapping == MappingType.Quadratic || RadiusMapping == MappingType.SquareRoot) { ResultMagnitude = Mathf2.MapLinear(0f, BaseMagnitude, 0f, 1f, MapSpecialSqr(RadiusMapping, sqrInnerRadius, sqrOuterRadius, ResultDirection.sqrMagnitude)); } else { ResultMagnitude = Mathf2.MapLinear(BaseMagnitude, 1f, 0f, 1f, MapSpecialSqr(RadiusMapping, sqrInnerRadius, sqrOuterRadius, ResultDirection.sqrMagnitude)); } } else { ResultMagnitude = BaseMagnitude; } return(true); }
/// <summary> /// Maps a <paramref name="value"/> lying between <paramref name="min"/> and <paramref name="max"/> to a /// resulting value between 0 and 1. /// <para/> /// The function used for the mapping is specified via the <paramref name="mapping"/> parameter, see <see /// cref="MappingType"/>. /// </summary> /// <param name="mapping">Specifies the applied type of the mapping function.</param> /// <param name="min">The minimum of the function argument interval.</param> /// <param name="max">The maximum of the function argument interval.</param> /// <param name="value">The argument value to be mapped.</param> /// <returns>The mapped function value.</returns> public static float MapSpecial(MappingType mapping, float min, float max, float value) { if (mapping == MappingType.Constant) { return(1f); } // Clamp if value is outside of the min/max interval if (value < min + Mathf2.Epsilon) { return((int)mapping % 2 != 0 ? 0f : 1f); } else if (value > max - Mathf2.Epsilon) { return((int)mapping % 2 != 0 ? 1f : 0f); } // Map according to the specified mapping type float result; switch (mapping) { case MappingType.Linear: result = Mathf2.MapLinear(0f, 1f, min, max, value); break; case MappingType.InverseLinear: result = 1f - Mathf2.MapLinear(0f, 1f, min, max, value); break; case MappingType.Quadratic: result = Mathf2.MapLinear(0f, 1f, min, max, value); result *= result; break; case MappingType.InverseQuadratic: result = Mathf2.MapLinear(0f, 1f, min, max, value); result *= result; result = 1f - result; break; case MappingType.SquareRoot: result = Mathf.Sqrt(Mathf2.MapLinear(0f, 1f, min, max, value)); break; case MappingType.InverseSquareRoot: result = 1f - Mathf.Sqrt(Mathf2.MapLinear(0f, 1f, min, max, value)); break; default: // MappingType.Constant result = 1f; break; } return(result); }