0
\$\begingroup\$

A little bit of context; I'm still not experienced at this, I'm creating a 2D platformer and this is my enemies script (some part of it). This is supposed to be a minatour, which charges towards the player on sight. When rays hit the player I call the Charge coroutine from update. As you can see below rays are not casted during the coroutine. Everything works according to plan, but after this coroutine ends if rays hit the player in two seconds, coroutine never stops again, rays are always casted and the minatour always keep charging. But if rays hit the player after 2 seconds it's perfectly fine. What am I doing wrong?

void FixedUpdate()
{
    if (!canChargeRight && !canChargeLeft)
    {
        rightRay = Physics2D.Raycast(transform.position, Vector2.right, rayDistance, layerMask);
        leftRay = Physics2D.Raycast(transform.position, Vector2.left, rayDistance, layerMask);

        if (rightRay.collider != null)
        {
            canChargeLeft = true;
        }
        else if (leftRay.collider != null)
        {
            canChargeRight = true;
        }
    }
}

void Update()
{
    if (canChargeRight)
    {
        StartCoroutine(Charge(-1));
    } else if (canChargeLeft)
    {
        StartCoroutine(Charge(1));
    }
}

private IEnumerator Charge(int chargeDirection)
{
    myRigidBody.velocity = Vector2.right * chargeDirection * chargeSpeed;

    yield return new WaitForSeconds(2);
    canChargeLeft = false;
    canChargeRight = false;
    myRigidBody.velocity = Vector2.zero;
}
\$\endgroup\$
2
  • \$\begingroup\$ I wanted to post this as a comment, but it seems I need 50 reputation for that. Are you calling StopCoroutine anywhere? If canChargeRight and canChargeLeft are successfully being set to false as intended, I would imagine that you would want to call StopCoroutine in your Update function if those variables are false. ---------- I found this on Unity's forum, which may be of use to you: forum.unity.com/threads/… \$\endgroup\$
    – DerpKat
    Commented Mar 13, 2019 at 17:33
  • 1
    \$\begingroup\$ It looks like you're starting a copy of this coroutine every frame, as long as canChargeRight or canChargeLeft remain true. That doesn't look like what you want. \$\endgroup\$
    – DMGregory
    Commented Mar 13, 2019 at 20:01

1 Answer 1

1
\$\begingroup\$

As @DMGregory mentioned, I guess the main issue was calling the coroutine in update function. Here is the final version if anyone is interested

 void Update()
{
    if(!chargingLeft && !chargingRight)
    {
        if ((player.position.x - transform.position.x) < 0)
        {
            transform.localScale = new Vector2(1, 1);           //this is where we flip enemy 
        }
        else
        {
            transform.localScale = new Vector2(-1, 1);
        }
    }
}

void FixedUpdate()
{
    if (canCharge)
    {
        rightRay = Physics2D.Raycast(transform.position, Vector2.right, rayDistance, layerMask);
        leftRay = Physics2D.Raycast(transform.position, Vector2.left, rayDistance, layerMask);

        Debug.DrawRay(transform.position, rayDistance * Vector2.right, Color.green);
        Debug.DrawRay(transform.position, rayDistance * Vector2.left, Color.red);

        if (rightRay.collider != null)
        {
            chargingRight = true;
            StartCoroutine(Charge());
            canCharge = false;
        }
        else if (leftRay.collider != null)
        {
            chargingLeft = true;
            StartCoroutine(Charge());
            canCharge = false;
        }
    }

    if (chargingLeft)
    {
        myRigidBody.velocity = Vector2.left * chargeSpeed;
    } else if (chargingRight)
    {
        myRigidBody.velocity = Vector2.right * chargeSpeed;
    }
}

private IEnumerator Charge()
{
    myAnimator.SetBool("Charge", true);

    yield return new WaitForSeconds(2);
    myAnimator.SetBool("Charge", false);
    myRigidBody.velocity = Vector2.zero;
    chargingRight = false;
    chargingLeft = false;
    StartCoroutine(Recovery());
}

private IEnumerator Recovery()
{
    StopCoroutine(charge);
    //recovery
    yield return new WaitForSeconds(2);
    canCharge = true;
}
\$\endgroup\$
1
  • 1
    \$\begingroup\$ If this is the solution to your issue, you might want to mark it as accepted :) \$\endgroup\$
    – Vaillancourt
    Commented Dec 8, 2019 at 23:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .