英文:
Coroutine keeps going after stopped
问题
以下是你要翻译的代码部分:
我正在制作一个类似《街头霸王》的游戏,并希望能够充能攻击。当你按住攻击键约1秒钟时,充能应该开始,然后每0.1秒增加0.1,直到达到最大值。当我释放键时,它应该停在当前位置并重置充能。但某种原因在我释放键后它会重新开始。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Attack : MonoBehaviour
{
    public KeyCode attackKey;
    public KeyCode stunKey;
    public int damage;
    public bool charging;
    public float maxChargeMultiplier;
    public float charge;
    public float attackDelay;
    public float attackTimer;
    public Stats target;
    private void Start()
    {
        attackTimer = attackDelay;
    }
    void Update()
    {
        // 开始充能
        if (Input.GetKeyDown(attackKey) && attackTimer >= attackDelay)
        {
            attackTimer = 0;
            StartCoroutine(ChargeAttack());
        }
        if (Input.GetKeyUp(attackKey))
        {
            Damage();
            StopCoroutine(ChargeAttack());
            charge = 0;
            StartCoroutine(RechargeAttack());
        }
    }
    public IEnumerator RechargeAttack()
    {
        for (int i = 0; i < attackDelay * 10; i++)
        {
            yield return new WaitForSecondsRealtime(0.1f);
            attackTimer += 0.1f;
        }
    }
    
    public IEnumerator ChargeAttack()
    {
        yield return new WaitForSecondsRealtime(1.25f);
        for(int c = 0; c < maxChargeMultiplier * 10; c++)
        {
            yield return new WaitForSecondsRealtime(0.1f);
            charge += 0.1f;
        }
    }
    public void Damage()
    {
        if(target != null)
        {
            if (target.blocking)
            {
                return;
            }
            else
            {
                target.health -= Mathf.RoundToInt(damage * charge);
                gameObject.GetComponent<Stats>().combo += 20;
            }
        }
        charge = 0;
    }
    private void OnTriggerEnter2D(Collider2D col)
    {
        if (col.GetComponent<Stats>())
        {
            target = col.gameObject.GetComponent<Stats>();
        }
    }
    private void OnTriggerExit2D(Collider2D col)
    {
        if (col.GetComponent<Stats>() == target)
        {
            target = null;
        }
    }
}
英文:
I am making a Street Fighter type game and want you to be able to charge an attack. it it meant to start when you hold the attack key for about 1 second, then it should count up by 0.1 every 0.1 seconds until at a maximum value. after i release the key it should stop where it is and reset the charge. Some reason it starts again after i release the key.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Attack : MonoBehaviour
{
public KeyCode attackKey;
public KeyCode stunKey;
public int damage;
public bool charging;
public float maxChargeMultiplier;
public float charge;
public float attackDelay;
public float attackTimer;
public Stats target;
private void Start()
{
attackTimer = attackDelay;
}
void Update()
{
//Start Charge
if (Input.GetKeyDown(attackKey) && attackTimer >= attackDelay)
{
attackTimer = 0;
StartCoroutine(ChargeAttack());
}
if (Input.GetKeyUp(attackKey))
{
Damage();
StopCoroutine(ChargeAttack());
charge = 0;
StartCoroutine(RechargeAttack());
}
}
public IEnumerator RechargeAttack()
{
for (int i = 0; i < attackDelay * 10; i++)
{
yield return new WaitForSecondsRealtime(0.1f);
attackTimer += 0.1f;
}
}
public IEnumerator ChargeAttack()
{
yield return new WaitForSecondsRealtime(1.25f);
for(int c = 0; c < maxChargeMultiplier * 10; c++)
{
yield return new WaitForSecondsRealtime(0.1f);
charge += 0.1f;
}
}
public void Damage()
{
if(target != null)
{
if (target.blocking)
{
return;
}
else
{
target.health -= Mathf.RoundToInt(damage * charge);
gameObject.GetComponent<Stats>().combo += 20;
}
}
charge = 0;
}
private void OnTriggerEnter2D(Collider2D col)
{
if (col.GetComponent<Stats>())
{
target = col.gameObject.GetComponent<Stats>();
}
}
private void OnTriggerExit2D(Collider2D col)
{
if (col.GetComponent<Stats>() == target)
{
target = null;
}
}
}
答案1
得分: 1
你需要停止已经启动的协程。
StartCoroutine 返回一个 Coroutine。这个 Coroutine 就是需要停止的对象。为了停止这个确切的协程,我们需要将它存储在一个变量中,这样我们以后可以在需要时再次引用它。
private Coroutine chargeAttackRoutine; // <- 存储已启动的协程的变量
private void Update()
{
    if (Input.GetKeyDown(attackKey))
    {
        chargeAttackRoutine = StartCoroutine(ChargeAttack()); // <- 存储协程
    }
    if (Input.GetKeyUp(attackKey))
    {
        StopCoroutine(chargeAttackRoutine); // <- 停止协程
    }
}
英文:
You need to stop the coroutine that was started.
StartCoroutine returns a Coroutine.  This Coroutine is what needs to be stopped.  In order to stop that exact coroutine, we need to store it in a variable so we can reference it again later when we want to stop it.
private Coroutine chargeAttackRoutine; // <- Variable for the coroutine that was started
private void Update()
{
if (Input.GetKeyDown(attackKey))
{
chargeAttackRoutine = StartCoroutine(ChargeAttack()); // <- Store the coroutine
}
if (Input.GetKeyUp(attackKey))
{
StopCoroutine(chargeAttackRoutine); // <- Stop the coroutine
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论