Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 动态协同程序名_C#_Unity3d_Coroutine - Fatal编程技术网

C# 动态协同程序名

C# 动态协同程序名,c#,unity3d,coroutine,C#,Unity3d,Coroutine,如何使协同程序的名称成为动态的? 我使用它使目标在几秒钟后自动死亡: void InitiateKill(int i) { //i is the number of the target StartCoroutine(TargetDie(i, timeAlive/1000)); //some other stuff } 当目标在计时器结束前被杀死时,我显然会得到一个错误,因为它无法再次杀死目标 这就是为什么我想停止特定目标的协同进程,但我不知道如何停止 我试过: Corout

如何使协同程序的名称成为动态的? 我使用它使目标在几秒钟后自动死亡:

void InitiateKill(int i)
{
   //i is the number of the target
   StartCoroutine(TargetDie(i, timeAlive/1000));
   //some other stuff
}
当目标在计时器结束前被杀死时,我显然会得到一个错误,因为它无法再次杀死目标

这就是为什么我想停止特定目标的协同进程,但我不知道如何停止

我试过:

Coroutine b[i] = StartCoroutine(TargetDie(i, timeAlive/1000));
但这会产生语法错误<代码>b[i]不能用于协同程序

如何以正确的方式进行此操作

更新:

这是我的TargetDie功能的(相关部分):

IEnumerator TargetDie(int i, float delayTime)
{
    yield return new WaitForSeconds(delayTime);
    Destroy(targets[i]);
}
当玩家杀死目标时,我会:

void Damage(int i)
{
   // at this time, the first Coroutine, started in InitiateKill, should stop, because otherwise it tries to destroy the target twice
   StartCoroutine(TargetDie(i, 0));
}

因此,最简单的方法是,在对象本身上移动协程

public class DieScript: MonoBehaviour
{
    private Manager manager;
    public void StartDeathProcess(Manager manager)
    {
        this.manager = manager;
        StartCoroutine(DieAsync(manager));
    }
    private IEnumerator DieAsync(Manager manager)
    {
        yield return new WaitForSeconds(timer);
        Destroy(this.gameObject);
    }
    public void Dmaage() // This is register as listener for death of the object
    {
         this.manager.PropagateDeath(this);
         Destroy(this.gameObject);
    }
}

public class Manager:MonoBehaviour
{
    private List<DieScript> die;
    void InitiateKill(int i)  
    {
        die[i].StartDeathProcess(this);
    }
}
公共类DieScript:monobhavior
{
私人经理;
公共无效StartDeathProcess(管理器)
{
this.manager=经理;
start例程(DieAsync(manager));
}
专用IEnumerator DieAncy(管理器管理器)
{
产生返回新WaitForSeconds(计时器);
摧毁(这个游戏对象);
}
public void Dmaage()//这是注册为对象死亡的侦听器
{
这个。经理。死亡(这个);
摧毁(这个游戏对象);
}
}
公共类经理:单一行为
{
私人名单;
无效启动码(int i)
{
die[i].StartDeathProcess(this);
}
}
试图在控制器上保持控制将带来更多的痛苦而不是解决方案

您可以有一个IEnumerator列表来跟踪正在运行的协同程序。但是您仍然需要来自对象的消息来通知控制器它已死亡。所以你错过了这一部分。 您需要在目标上使用脚本,以便控制器了解此类型。 控制器运行协同程序,并引用该脚本,询问每个帧是否正在死亡。当目标注定死亡时,它会设置一个布尔值来通知。使用Destroy可以将对象保留到帧结束,这样它就可以工作了


但这注定会在以后失败。让一个控制器做所有事情有点违背编程概念。您应该更多地将其视为信息的旁路

您只需在销毁null之前检查null,就不会出现任何错误:

if (targets != null)
    Destroy(targets[i]);
但是如果您想停止旧的协同程序,下面是推荐的方法


您可以使用
字典
来处理它。使用
inti
作为键,使用
Coroutine
作为值

调用InitiateKill时,将
int i
添加到字典中,启动协同程序时,将
coroutine
也添加到字典中作为值

调用
Damage
时,检查
字典中是否存在该int值。如果是,则使用它检索
协同路由
值并停止旧的协同路由。如果没有退出,则启动一个新的协同程序,然后将其添加到该字典中

字典应如下所示:

Dictionary<int, Coroutine> dyingTarget = new Dictionary<int, Coroutine>();
新的
Damage
函数现在检查项目是否已在字典中,然后重试,停止协同程序并将其从
字典中删除

void Damage(int i)
{
    // at this time, the first Coroutine, started in InitiateKill, should stop, because otherwise it tries to destroy the target twice
    StopIfAlreadyRunning(i);

    Coroutine crt = StartCoroutine(TargetDie(i, 0));
    //Add to Dictionary
    dyingTarget.Add(i, crt);
}

void StopIfAlreadyRunning(int i)
{
    Coroutine crtOut;
    //Retrieve and stop old coroutine if it exist then removes it
    if (dyingTarget.TryGetValue(i, out crtOut))
    {
        StopCoroutine(crtOut);
        dyingTarget.Remove(i);
    }
}
新的
TargetDie
函数,在杀死它后将其从
字典中删除。在销毁之前,它还会检查
null

IEnumerator TargetDie(int i, float delayTime)
{
    yield return new WaitForSeconds(delayTime);
    if (targets != null)
        Destroy(targets[i]);
    //Remove from Dictionary 
    dyingTarget.Remove(i);
}

你把目标的号码存储在什么地方了吗?如果你想让它自动停止,你可以在TargetDie函数中完成。值得解释一下这个函数在做什么,什么时候应该停止运行是的,它的名字是:target0,target1。。。这与协同程序部分有什么关系?@Programmer:我更新了我的问题,因为首先你应该在目标上运行协同程序,这样当它死亡时它会自动停止。否则,您需要从目标获取一些引用,以便目标可以传播它死亡的事实。或者某个循环,如果项目已死亡,则会中断协同程序。我了解如何在目标上运行协同程序。但是我所有的代码,包括StartCodes,都在一个叫做Controller的不同的空游戏对象上。这太棒了,谢谢你的回答和解释!很高兴你发现我的回答很有帮助
IEnumerator TargetDie(int i, float delayTime)
{
    yield return new WaitForSeconds(delayTime);
    if (targets != null)
        Destroy(targets[i]);
    //Remove from Dictionary 
    dyingTarget.Remove(i);
}