Home > Enterprise >  I want not the return value to be returned until the coroutine is finished in Unity
I want not the return value to be returned until the coroutine is finished in Unity

Time:10-17

public class W_02_Bow : WeaponDefault
{

    public override int Attack(int attackMove)
    {`enter code here`
        StartCoroutine(ChargeAttack(attackMove));
        return attackMove;
    }

    private IEnumerator ChargeAttack(int attackMove)
    {
        float chargeTime = 0f;

        while (chargeTime <= 5f && Input.GetMouseButton(0))
        {
            Debug.Log("Charging...");
            chargeTime  = Time.deltaTime;
            yield return null;
        }

        if (chargeTime >= 5f)
            Debug.Log("Charged!");

        chargeTime = 0;
        
        yield return new WaitUntil(() => Input.GetMouseButtonUp(0));

        attackMove = attackMove % 3   1;
    }

}

This code was written to implement a charge attack.

But I don't know how to make the function not return a return value until the coroutine is finished.

In code structure, a function must return an int type.

Also I've used abstract, and that's the only script I'm trying to implement a charge attack on.

Below is the code to trigger an Attack, and all actions under Attack must not be executed until the Attack returns a value.

public void Attack()
    {
        if (Input.GetMouseButton(0) && isLand)
        {
            if (IsCanAct((int)weaponType   5) && !isAttack)
            {
                isAttack = true;
                playerNowStamina -= (int)weaponType   5;

                playerAnim.SetInteger(_triggerNum, (int)AnimState.Attack);

                attackMove = weapons[(int)weaponState].GetComponent<WeaponDefault>().Attack(attackMove);

                playerAnim.SetInteger(_action, attackMove);

                playerAnim.SetTrigger(_trigger, () =>
                {
                    isAttack = false;
                    Variables.Instance?.WeaponVfx?[0]?.gameObject.SetActive(false);
                }, (float)weaponType * 0.2f   0.6f
                );
            }
        }
    }

CodePudding user response:

I think you can use Action to achieve what you want, this is the definition of action:

Encapsulates a method that has a single parameter and does not return a value.

Basically, you pass a function to your coroutine and call it when coroutine is done.

First of all, make Attack return type void and define an input of type Action. Pass an Action to your Coroutine and Invoke it at the end of your coroutine with attackMove. (I have added the StartOfAttack and EndOfAttack methods to demonestrate. Replace them with the method that calls Attack and the method that wants the result )

    public void StartOfAttack()
    {
        Attack(0, EndOfAttack);
    }

    public void EndOfAttack(int attackMove)
    {
        print(attackMove);
    }
    
    public void Attack(int attackMove, Action<int> callback)
    {
        StartCoroutine(ChargeAttack(attackMove, callback));
    }

    private IEnumerator ChargeAttack(int attackMove, Action<int> callback)
    {
        float chargeTime = 0f;

        while (chargeTime <= 5f && Input.GetMouseButton(0))
        {
            Debug.Log("Charging...");
            chargeTime  = Time.deltaTime;
            yield return null;
        }

        if (chargeTime >= 5f)
            Debug.Log("Charged!");

        chargeTime = 0;

        yield return new WaitUntil(() => Input.GetMouseButtonUp(0));

        attackMove = attackMove % 3   1;
        
        callback.Invoke(attackMove);
    }
  • Related