C#如何在不阻塞程序的情况下使函数/方法等待(Unity)

Elf*_*onz 3 c# fork wait unity-game-engine

我想在函数中统一模拟游戏中的健康恢复RestoreHealth()

我是否想通过创建子进程来过分考虑它,所以当我调用wait时,它不会影响任何当前正在运行的进程或线程,并且该子进程将在函数完成后死亡。

public void RestoreHealth() {
    if (health >= MaxHealth) return; // health and MaxHealth are Class variables

    if (health % 10 != 0) {     // if health is not dividable by 10
        int temp = health % 10; // then we round it to the closest 
                                //tenth
        temp = 10 - temp;
        health += temp;
    }

    int i = health;

    for (; i < MaxHealth; i += 10) {  // where the health grows till 100
        health += 10;
        // sleep(1000);  // make function wait for '1 second' to iterate again

        Debug.Log("Health: " + health);
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,如何在C#或unity中创建子进程并使其等待?

Fork();在C中有没有一个类似于like的东西?

另外,当玩家最初受到伤害时,会调用此函数。

解决方案

注意:我将“健康”更改为“护甲”

public IEnumerator RestoreArmour() {
        while (_Armour < _MaxArmour) {
            _Armour++;
            Debug.Log("Health: " + _Armour);
            yield return new WaitForSeconds(ArmourRegenRate); // ArmourRegenRate is a 
                                                             // float for the seconds
        }
    }
Run Code Online (Sandbox Code Playgroud)

并用它来启动协程

 void Start(){

    StartCoroutine(player.RestoreArmour());
}
Run Code Online (Sandbox Code Playgroud)

Fre*_*hön 5

协程基本概念

在Unity中,您可以与协同程序一起实现这种异步的“线程化”行为

IEnumerator RestoreHealth() {
   while (health != MaxHealth) {
       health++;
       yield return new WaitForEndOfFrame();
   }
}
Run Code Online (Sandbox Code Playgroud)

然后用

StartCoroutine(RestoreHealth());
Run Code Online (Sandbox Code Playgroud)

重新启动协程

为了停止运行现有的协程并启动新的协程,这是您要达到的目的:

private Coroutine _myCoroutine = null;

void SomeMethod()
{
    if (_myCoroutine != null)
        StopCoroutine(_myCoroutine);

    _myCoroutine = StartCoroutine(SomeOtherMethod());
}

Run Code Online (Sandbox Code Playgroud)

玩家受到伤害时暂停盔甲恢复X秒

一种常见的功能是在玩家未受到X秒的伤害时拥有一些恢复盔甲的功能:

private bool _shouldRestoreArmour = true;
private Coroutine _pauseArmorCoroutine = null;

void Update()
{
    if (_shouldRestoreArmour)
        Armor += ArmorRegenerationPerSecond * Time.deltaTime;
}

void PlayerTakeDamage() 
{
    if (_pauseArmorCoroutine != null) 
        StopCoroutine(_pauseArmorCoroutine);

    _pauseArmorCoroutine = StartCoroutine(PauseRestoreArmor());

    // Take damage code
}

IEnumerator PauseRestoreArmor()
{
    _shouldRestoreArmor = false;
    yield return new WaitForSeconds(RESTORE_ARMOR_DELAY_TIME);
    _shouldRestoreArmor = true;
}
Run Code Online (Sandbox Code Playgroud)

在此情况下,玩家将一直恢复装甲,但在受到伤害后的X秒内除外。如果玩家多次受到伤害,我们将简单地放弃先前的协程并开始一个新的协程,这样距最后一次命中将有X秒钟的时间。