/// <summary>
        /// Seeks from the specified position to a destination.
        /// </summary>
        /// <param name="position">The position from which to seek.</param>
        /// <param name="destination">The destination.</param>
        /// <param name="input">The input.</param>
        /// <param name="maxAcceleration">The maximum allowed acceleration.</param>
        /// <returns>The seek acceleration vector</returns>
        protected Vector3 Seek(Vector3 position, Vector3 destination, SteeringInput input, float maxAcceleration)
        {
            var dir = position.DirToXZ(destination);
            var desiredVelocity = dir.normalized * input.desiredSpeed;

            return Vector3.ClampMagnitude((desiredVelocity - input.currentPlanarVelocity) / input.deltaTime, maxAcceleration);
        }
        /// <summary>
        /// Gets an avoidance vector.
        /// </summary>
        /// <param name="selfPos">This unit's position.</param>
        /// <param name="currentVelocity">This unit's current velocity.</param>
        /// <param name="normalVelocity">This unit's normalized current velocity.</param>
        /// <param name="unitData">This unit's UnitFacade.</param>
        /// <param name="otherPos">The other unit's position.</param>
        /// <param name="otherVelocity">The other unit's velocity.</param>
        /// <param name="otherData">The other unit's UnitFacade.</param>
        /// <param name="combinedRadius">The combined radius.</param>
        /// <returns>An avoidance vector from the other unit's collision position to this unit's collision position - if a collision actually is detected.</returns>
        private Vector3 GetAvoidVector(Vector3 selfPos, Vector3 currentVelocity, Vector3 normalVelocity, IUnitFacade unitData, Vector3 otherPos, Vector3 otherVelocity, IUnitFacade otherData, float combinedRadius)
        {
            Vector3 avoidDirection = GetAvoidDirectionVector(selfPos, currentVelocity, otherPos, otherVelocity, combinedRadius);
            float avoidMagnitude = avoidDirection.magnitude;
            if (avoidMagnitude == 0f)
            {
                // if there is absolutely no magnitude to the found avoid direction, then ignore it
                return Vector3.zero;
            }

            float vectorLength = combinedRadius * 0.5f;
            if (vectorLength <= 0f)
            {
                // if the units' combined radius is 0, then we cannot avoid
                return Vector3.zero;
            }

            // normalize the avoid vector and then set it's magnitude to the desired vector length (half of the combined radius)
            Vector3 avoidNormalized = (avoidDirection / avoidMagnitude);
            Vector3 avoidVector = avoidNormalized * vectorLength;

            float dotAngle = Vector3.Dot(avoidNormalized, normalVelocity);
            if (dotAngle <= _cosAvoidAngle)
            {
                // the collision is considered "head-on", thus we compute a perpendicular avoid vector instead
                avoidVector = new Vector3(avoidVector.z, avoidVector.y, -avoidVector.x);
            }
            else if (preventPassingInFront && (otherData.determination > unitData.determination) && (Vector3.Dot(otherVelocity, avoidVector) > 0f && Vector3.Dot(currentVelocity, otherVelocity) >= 0f))
            {
                // if supposed to be preventing front-passing, then check whether we should prevent it in this case and if so compute a different avoid vector
                avoidVector = _selfCollisionPos.DirToXZ(selfPos);
            }

            // scale the avoid vector depending on the distance to collision, shorter distances need larger magnitudes and vice versa
            float collisionDistance = Mathf.Max(1f, selfPos.DirToXZ(_selfCollisionPos).magnitude);
            avoidVector *= currentVelocity.magnitude / collisionDistance;

            return avoidVector;
        }
Ejemplo n.º 3
0
        protected Vector3 Seek(Vector3 position, Vector3 destination, SteeringInput input, float acceleration)
        {
            var dir = position.DirToXZ(destination);
            var desiredVelocity = dir.normalized * acceleration;

            return desiredVelocity - input.currentPlanarVelocity;
        }