C#如何使函数/方法在不阻塞程序的情况下等待(Unity)
我想在unity的游戏中,在函数C#如何使函数/方法在不阻塞程序的情况下等待(Unity),c#,unity3d,fork,wait,C#,Unity3d,Fork,Wait,我想在unity的游戏中,在函数RestoreHealth()中模拟生命再生 我是不是想创建一个子进程而想得太多了,所以当我调用wait时,它不会影响任何当前正在运行的进程或线程,并且当函数完成时,子进程将死亡 public void RestoreHealth() { if (health >= MaxHealth) return; // health and MaxHealth are Class variables if (health % 10 != 0) {
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);
}
}
然后用它来启动协同程序
void Start(){
StartCoroutine(player.RestoreArmour());
}
您可以创建一个计时器,假设您在update方法中运行它
private float timer=1;
专用浮动时间设置=1;
私有void更新(){
恢复健康();
}
公共卫生(恢复健康){
if(health>=MaxHealth)return;//health和MaxHealth是类变量
如果(运行状况%10!=0){//如果运行状况不能除以10
int temp=health%10;//然后我们将其四舍五入到最接近的十分之一
温度=10-温度;
健康+=温度;
}
int i=健康;
对于(;i0){
计时器-=1*time.deltaTime;
}否则{
健康+=10;
Debug.Log(“运行状况:+Health”);
定时器=定时器设置;
}
}
}
或者你可以简单地给你的玩家每秒1点生命值,或者任何数量的生命值
public void RestoreHealth(){
if(health>=MaxHealth)return;//health和MaxHealth是类变量
如果(运行状况%10!=0){//如果运行状况不能除以10
int temp=health%10;//然后我们将其四舍五入到最接近的十分之一
温度=10-温度;
健康+=温度;
}
int i=健康;
对于(;i
因此,在这种情况下,玩家每秒获得10点生命值,但值始终会上升,因此在一秒钟内,玩家的生命值将每100ms增加1点生命值
在Unity中,您与协同程序一起工作以实现这种非同步的“线程化”行为
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秒。
fork()
不会创建进程。它创建了一个线程。是的,您可以在C#中创建线程。在unity中,您不能创建线程,因为unity仅在多线程的主线程上运行,您必须使用服务器并查询服务器以执行操作。这不是一个无限循环,因为计时器总是重置为1吗?另外,当玩家最初受到伤害时,这个函数被调用。只有当计时器一直倒计时到零时,它才会被重置。是的,我可以工作,但我想要一个更明显的缓慢增量。谢谢,虽然我替换了“WaitForEndOfFrame();“返回新的等待秒(ArmourRegenRate);”相反,太棒了!无论什么对你有用,我只是想在这里展示这个概念。记住,这些东西是异步的,这意味着你应该确保一次只启动其中一个,当然,除非你需要多个异步运行;这个实现看起来很棒!嗯,所以每次玩家受到伤害时都会调用这个RestoreArmour()函数,如果玩家在盔甲再生时再次被击中,那就不好了,我需要停止当前运行的函数并重新启动itAh,是的。常见用例;去抖功能。我将更新我的代码,向您展示我通常如何实现这一点。1秒
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;
}