C# 如何使 function/Method 等待而不阻塞程序 (Unity)
C# how to Make function/Method Wait without blocking program (Unity)
我想在函数 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);
}
}
在这种情况下,如何在 C# 或 unity 中创建子进程并使其等待?
是否有 C 语言中 Fork();
的等效项?
此外,当玩家最初受到伤害时会调用此函数。
解决方法:
注意:我将 Health 更改为 Armour
public IEnumerator RestoreArmour() {
while (_Armour < _MaxArmour) {
_Armour++;
Debug.Log("Health: " + _Armour);
yield return new WaitForSeconds(ArmourRegenRate); // ArmourRegenRate is a
// float for the seconds
}
}
并用它来启动协程
void Start(){
StartCoroutine(player.RestoreArmour());
}
你可以创建一个定时器,假设你在更新方法中运行这个
private float timer = 1;
private float timerReset = 1;
private void Update(){
RestoreHealth();
}
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
if(timer > 0){
timer -= 1 * time.deltaTime;
}else{
health += 10;
Debug.Log("Health: " + health);
timer = timerReset;
}
}
}
或者你可以简单地给你的玩家每秒 1 点生命值或任何数量
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 * 1 * time.deltaTime;
Debug.Log("Health: " + health);
timer = timerReset;
}
}
因此,在这种情况下,您的玩家每秒获得 10 点生命值,但该值将始终上升,因此在一秒钟内玩家的生命值将每 100 毫秒增加 1 点生命值
基本协程概念
在 Unity 中,您使用协程来实现这种异步 "threaded" 行为
IEnumerator RestoreHealth() {
while (health != MaxHealth) {
health++;
yield return new WaitForEndOfFrame();
}
}
然后用
调用它
StartCoroutine(RestoreHealth());
重新启动协程
为了从 运行 停止一个现有的协程并启动一个新协程,您可以通过以下方式实现:
private Coroutine _myCoroutine = null;
void SomeMethod()
{
if (_myCoroutine != null)
StopCoroutine(_myCoroutine);
_myCoroutine = StartCoroutine(SomeOtherMethod());
}
当玩家受到伤害时暂停装甲恢复 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;
}
这里玩家会一直再生护甲,玩家受到伤害后 X 秒除外。如果玩家多次受到伤害,我们将简单地中止前一个协程并启动一个新的协程,这样距上次命中将是新的 X 秒。
我想在函数 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);
}
}
在这种情况下,如何在 C# 或 unity 中创建子进程并使其等待?
是否有 C 语言中 Fork();
的等效项?
此外,当玩家最初受到伤害时会调用此函数。
解决方法:
注意:我将 Health 更改为 Armour
public IEnumerator RestoreArmour() {
while (_Armour < _MaxArmour) {
_Armour++;
Debug.Log("Health: " + _Armour);
yield return new WaitForSeconds(ArmourRegenRate); // ArmourRegenRate is a
// float for the seconds
}
}
并用它来启动协程
void Start(){
StartCoroutine(player.RestoreArmour());
}
你可以创建一个定时器,假设你在更新方法中运行这个
private float timer = 1;
private float timerReset = 1;
private void Update(){
RestoreHealth();
}
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
if(timer > 0){
timer -= 1 * time.deltaTime;
}else{
health += 10;
Debug.Log("Health: " + health);
timer = timerReset;
}
}
}
或者你可以简单地给你的玩家每秒 1 点生命值或任何数量
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 * 1 * time.deltaTime;
Debug.Log("Health: " + health);
timer = timerReset;
}
}
因此,在这种情况下,您的玩家每秒获得 10 点生命值,但该值将始终上升,因此在一秒钟内玩家的生命值将每 100 毫秒增加 1 点生命值
基本协程概念
在 Unity 中,您使用协程来实现这种异步 "threaded" 行为
IEnumerator RestoreHealth() {
while (health != MaxHealth) {
health++;
yield return new WaitForEndOfFrame();
}
}
然后用
调用它StartCoroutine(RestoreHealth());
重新启动协程
为了从 运行 停止一个现有的协程并启动一个新协程,您可以通过以下方式实现:
private Coroutine _myCoroutine = null;
void SomeMethod()
{
if (_myCoroutine != null)
StopCoroutine(_myCoroutine);
_myCoroutine = StartCoroutine(SomeOtherMethod());
}
当玩家受到伤害时暂停装甲恢复 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;
}
这里玩家会一直再生护甲,玩家受到伤害后 X 秒除外。如果玩家多次受到伤害,我们将简单地中止前一个协程并启动一个新的协程,这样距上次命中将是新的 X 秒。