Exemplo n.º 1
0
        /// <summary>
        /// Starts moving to the specified start location.
        /// </summary>
        /// <param name="startLocations">The locations the character can move towards. If multiple locations are possible then the closest valid location will be used.</param>
        /// <param name="onArriveAbility">The ability that should be started as soon as the character arrives at the location.</param>
        /// <returns>True if the MoveTowards ability is started.</returns>
        public bool StartMoving(AbilityStartLocation[] startLocations, Ability onArriveAbility)
        {
            // MoveTowards doesn't need to start if there is no start location.
            if (startLocations == null || startLocations.Length == 0)
            {
                return(false);
            }

            // The arrive ability must exist and be unique. If the ability is already set then StartMoving may have been triggered because the arrive ability
            // should start.
            if (onArriveAbility == null || onArriveAbility == m_OnArriveAbility)
            {
                return(false);
            }

            // No reason to start if the character is already in a valid start location.
            for (int i = 0; i < startLocations.Length; ++i)
            {
                if (startLocations[i].IsPositionValid(m_Transform.position, m_Transform.rotation, m_CharacterLocomotion.Grounded) && startLocations[i].IsRotationValid(m_Transform.rotation))
                {
                    return(false);
                }
            }

            // The character needs to move - start the ability.
            m_StartLocation   = GetClosestStartLocation(startLocations);
            m_OnArriveAbility = onArriveAbility;

            // The movement speed will depend on the current speed the character is moving.
            m_MovementMultiplier = m_StartLocation.MovementMultiplier;
            if (m_SpeedChangeAbilities != null)
            {
                for (int i = 0; i < m_SpeedChangeAbilities.Length; ++i)
                {
                    if (m_SpeedChangeAbilities[i].IsActive)
                    {
                        m_MovementMultiplier = m_SpeedChangeAbilities[i].SpeedChangeMultiplier;
                        break;
                    }
                }
            }

            if (m_OnArriveAbility.Index < Index)
            {
                Debug.LogWarning("Warning: " + m_OnArriveAbility.GetType().Name + " has a higher priority then the MoveTowards ability. This will cause unintended behavior.");
            }

            StartAbility();
            // MoveTowards may be starting when all of the inputs are being checked. If it has a lower index then the update loop won't run initially
            // which will prevent the TargetDirection from having a valid value. Run the Update loop immediately so TargetDirection is correct.
            if (Index < onArriveAbility.Index)
            {
                Update();
            }

            return(true);
        }
Exemplo n.º 2
0
        private static void DrawStartLocationGizmo(AbilityStartLocation startLocation, GizmoType gizmoType)
        {
            var transform = startLocation.transform;

            Handles.matrix = Gizmos.matrix = Matrix4x4.TRS(transform.position, transform.rotation, transform.lossyScale);

            // Wire lines will indicate the valid starting positions.
            Gizmos.color = new Color(1, 0.6f, 0, 0.7f);
            Gizmos.DrawWireCube(startLocation.Offset, startLocation.Size);

            // Draw an arc indicating the direction that the character can face.
            Handles.matrix = Gizmos.matrix = Matrix4x4.TRS(transform.TransformPoint(startLocation.Offset), transform.rotation * Quaternion.Euler(0, startLocation.YawOffset, 0), transform.lossyScale);
            Handles.color  = new Color(0, 1, 0, 0.7f);
            var radius = Mathf.Min(0.5f, Mathf.Max(Mathf.Abs(startLocation.Offset.z), 0.2f));

            Handles.DrawWireDisc(Vector3.zero, Vector3.up, radius);
            Handles.color = new Color(0, 1, 0, 0.2f);
            Handles.DrawSolidArc(Vector3.zero, Vector3.up, Quaternion.AngleAxis(startLocation.Angle / 2 - startLocation.Angle, Vector3.up) * Vector3.forward,
                                 startLocation.Angle, radius);

            // Draw arrows pointing in the direction that the character can face.
            radius       /= 2;
            Handles.color = new Color(0, 1, 0, 0.7f);
            Handles.DrawLine(Vector3.zero, (Vector3.forward * 2f) * radius);
            Handles.DrawLine((Vector3.forward * 2) * radius, ((Vector3.forward * 1.5f * radius) + (Vector3.left * 0.5f) * radius));
            Handles.DrawLine((Vector3.forward * 2) * radius, ((Vector3.forward * 1.5f * radius) + (Vector3.right * 0.5f) * radius));
            if (startLocation.Angle >= 180)
            {
                Handles.DrawLine((Vector3.left * 2) * radius, (Vector3.right * 2) * radius);
                Handles.DrawLine((Vector3.left * 2) * radius, ((Vector3.left * 1.5f * radius) + (Vector3.forward * 0.5f) * radius));
                Handles.DrawLine((Vector3.left * 2) * radius, ((Vector3.left * 1.5f * radius) + (Vector3.back * 0.5f) * radius));
                Handles.DrawLine((Vector3.right * 2) * radius, ((Vector3.right * 1.5f * radius) + (Vector3.forward * 0.5f) * radius));
                Handles.DrawLine((Vector3.right * 2) * radius, ((Vector3.right * 1.5f * radius) + (Vector3.back * 0.5f) * radius));
                if (startLocation.Angle == 360)
                {
                    Handles.DrawLine(Vector3.zero, (Vector3.back * 2f) * radius);
                    Handles.DrawLine((Vector3.back * 2) * radius, ((Vector3.back * 1.5f * radius) + (Vector3.left * 0.5f) * radius));
                    Handles.DrawLine((Vector3.back * 2) * radius, ((Vector3.back * 1.5f * radius) + (Vector3.right * 0.5f) * radius));
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Returns the closest start location out of the possible AbilityStartLocations.
        /// </summary>
        /// <param name="startLocations">The locations the character can move towards.</param>
        /// <returns>The best location out of the possible AbilityStartLocations.</returns>
        private AbilityStartLocation GetClosestStartLocation(AbilityStartLocation[] startLocations)
        {
            // If only one location is available then it is the closest.
            if (startLocations.Length == 1)
            {
                return(startLocations[0]);
            }

            // Multiple locations are available. Choose the closest location.
            AbilityStartLocation startLocation = null;
            var   closestDistance = float.MaxValue;
            float distance;

            for (int i = 0; i < startLocations.Length; ++i)
            {
                if ((distance = startLocations[i].GetTargetDirection(m_Transform.position, m_Transform.rotation).sqrMagnitude) < closestDistance)
                {
                    closestDistance = distance;
                    startLocation   = startLocations[i];
                }
            }

            return(startLocation);
        }