Example #1
0
    void FixedUpdate()
    {
        if (target != null && !attacking && !RunningThisRoutine(fleeing))
        {
            Vector2        vectorToTarget = Vector2.zero;
            RaycastHit2D[] hits           = new RaycastHit2D[raycastDepth];
            Physics2D.RaycastNonAlloc(WC.transform.position, target.transform.position - transform.position, hits, aggroRange, collideLayerMask);
            string hitTag      = null;
            bool   hitIsTarget = false;
            foreach (RaycastHit2D hit in hits)
            {
                // go through hits from closest to farthest
                if (hit.collider != null && hit.fraction != 0)
                {
                    hitTag         = hit.collider.tag;
                    vectorToTarget = hit.point - (Vector2)transform.position;

                    // if the tag of this object is a target, then we will target this one since it is the closest
                    foreach (string tag in targetTags)
                    {
                        if (tag == hitTag)
                        {
                            hitIsTarget = true;
                            break;
                        }
                    }

                    if (hitIsTarget)
                    {
                        break;
                    }
                }
            }

            if (vectorToTarget != Vector2.zero)
            {
                if (vectorToTarget.magnitude < aggroRange) // if within aggro range
                {
                    if (vectorToTarget.magnitude > attackRange || vectorToTarget.magnitude > tooFarThreshold)
                    {
                        Move(vectorToTarget);
                        WC.AimInDirection(vectorToTarget);
                    }
                    else if (vectorToTarget.magnitude < tooCloseThreshold && hitIsTarget)
                    {
                        fleeing = MoveTo(vectorToTarget.normalized * -1 * Mathf.Abs(followDistance - vectorToTarget.magnitude));
                        WC.AimInDirection(-vectorToTarget);
                    }
                    else if (Time.time - lastAttackTime > attackCooldownLength && vectorToTarget.magnitude < attackRange && hitIsTarget)
                    {
                        if (WC.CanFire())
                        {
                            StartCoroutine(ShootAttack(vectorToTarget, attackChargeTime, postAttackPauseDuration));
                        }
                    }
                }
            }
            spriteDirection = vectorToTarget;
        }
    }
    /// <summary>
    ///     Times the attacking cycle for a sword style attack
    /// </summary>
    /// <remark>
    ///    The total time this coroutine takes to execute is equal to chargeTime+enableLength+pauseTime+retreatLength
    /// </remark>
    ///     <param name="vectorToTarget">The vector from the center of this gameObject's transform to the target</param>
    ///     <param name="chargeTime">The time this enemy waits before attacking</param>
    ///     <param name="enableLength">How long to enable the weapon's collider for</param>
    ///     <param name="pauseTime">The time after turning off the collider this enemy waits before retreating</param>
    ///     <param name="retreatLength">The length of time over which this enemy retreats</param>
    private IEnumerator SwordAttack(Vector2 vectorToTarget, float chargeTime, float pauseTime, float retreatLength)
    {
        attacking = true;
        WC.AimInDirection(vectorToTarget);
        float     startTime = Time.time;
        Coroutine retreat   = null;
        bool      doing     = true;
        bool      shot      = false;

        while (doing)
        {
            Vector3 startingPosition = transform.position;
            if (Time.time < startTime + chargeTime) // CHARGING ATTACK
            {
                attackIndicator.SetActive(true);
                // do animations here
                yield return(new WaitForSeconds(.05f));
            }
            else if (Time.time < startTime + chargeTime + pauseTime) // ATTACKING
            {
                attackIndicator.SetActive(false);
                if (!shot)
                {
                    WC.Fire(vectorToTarget);
                    shot = true;
                }
                else
                {
                    if (WC.IsFiring())
                    {
                        startTime += Time.deltaTime;// increment start time to prevent from moving on and waiting until the attack is complete
                    }
                }
                // do animations here
                yield return(new WaitForEndOfFrame());
            }
            else if (Time.time > startTime + chargeTime + pauseTime && doing) // RETREATING (jumping backwards)
            {
                if (retreat == null)
                {
                    //AimWeaponAtTarget(-vectorToTarget);
                    WC.AimInDirection(-vectorToTarget);
                    retreat = MoveTo(-vectorToTarget.normalized * retreatLength);
                }
                else if (!RunningThisRoutine(retreat))
                {
                    doing = false;
                }
                // do animations here
                yield return(new WaitForFixedUpdate());
            }
        }
        attacking = false;
    }
    void FixedUpdate()
    {
        if (Time.time - lastAttackTime <= attackCooldownLength)
        {
            return;
        }                                 // cancel if this enemy just attacked

        if (target != null && !attacking) // if the enemy is not attacking, do movement and try to attack
        {
            Vector2        vectorToTarget = Vector2.zero;
            RaycastHit2D[] hits           = new RaycastHit2D[raycastDepth];
            Physics2D.RaycastNonAlloc(WC.transform.position, target.transform.position - transform.position, hits, aggroRange, collideLayerMask);
            string hitTag      = null;
            bool   hitIsTarget = false;
            foreach (RaycastHit2D hit in hits)
            {
                // go through hits from closest to farthest
                if (hit.collider != null && hit.fraction != 0)
                {
                    hitTag         = hit.collider.tag;
                    vectorToTarget = hit.point - (Vector2)transform.position;

                    // if the tag of this object is a target, then we will target this one since it is the closest
                    foreach (string tag in targetTags)
                    {
                        if (tag == hitTag)
                        {
                            hitIsTarget = true;
                            break;
                        }
                    }

                    if (hitIsTarget)
                    {
                        break;
                    }
                }
            }

            if (vectorToTarget != Vector2.zero)
            {
                if (vectorToTarget.magnitude < aggroRange) // if within aggro range, move and aim weapon towards target
                {
                    Move(vectorToTarget);
                    WC.AimInDirection(vectorToTarget);
                }
                if (vectorToTarget.magnitude < attackRange && hitIsTarget && WC.CanFire()) // attack
                {
                    StartCoroutine(SwordAttack(vectorToTarget, attackChargeTime, postAttackPauseDuration, postAttackRetreatDistance));
                }
            }
        }
    }
Example #4
0
    private IEnumerator ShootAttack(Vector2 vectorToTarget, float chargeTime, float pauseTime)
    {
        attacking = true;
        WC.AimInDirection(vectorToTarget);
        float startTime = Time.time;
        bool  shot      = false;

        while (Time.time < startTime + chargeTime + pauseTime)
        {
            Vector3 startingPosition = transform.position;
            if (Time.time < startTime + chargeTime) // CHARGING ATTACK
            {
                attackIndicator.SetActive(true);
                chargingAttackAnim = true;
                // do animations here
                yield return(new WaitForSeconds(.05f));
            }
            else if (Time.time < startTime + chargeTime + pauseTime && !shot) // ATTACKING
            {
                attackIndicator.SetActive(false);
                // shoot gun
                WC.Fire(vectorToTarget);
                shot      = true;
                startTime = Time.time - chargeTime;
                // call an IEnumerator that makes a flag that is true while running, then wait for that to complete (just yield while its true)
                // then keep on completing this IEnumerator
                // do animations here
                yield return(new WaitForSeconds(.05f));
            }
            else if (Time.time < startTime + chargeTime + pauseTime && shot) // PLAYER RIPOSTE OPPORTUNITY
            {
                yield return(new WaitForSeconds(.05f));
            }
        }
        chargingAttackAnim = false;
        attacking          = false;
    }