Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.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# 如何从列表中删除当前播放索引项,但变量“I”现在是1而不是0?_C#_Unity3d - Fatal编程技术网

C# 如何从列表中删除当前播放索引项,但变量“I”现在是1而不是0?

C# 如何从列表中删除当前播放索引项,但变量“I”现在是1而不是0?,c#,unity3d,C#,Unity3d,在脚本中: using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; public class NaviDialogue : MonoBehaviour { public ObjectsManipulation op; public bool scaling = true; public Scalin

在脚本中:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class NaviDialogue : MonoBehaviour
{
    public ObjectsManipulation op;
    public bool scaling = true;
    public Scaling scale;
    public ConversationTrigger conversationTrigger;

    private bool ended = false;
    private bool startConversation = false;

    private void Update()
    {
        if (scaling == true && DOFControl.hasFinished == true)
        {
            DOFControl.hasFinished = false;
            scaling = false;
            op.Scaling();
            PlayerController.disablePlayerController = true;
            ConversationTrigger.conversationsToPlay.Add(0);
            ConversationTrigger.conversationsToPlay.Add(1);
            ConversationTrigger.conversationsToPlay.Add(2);
            StartCoroutine(conversationTrigger.PlayConversations());
        }
}
在ConversationTrigger的顶部:

public static List<int> conversationsToPlay = new List<int>();

问题是,在PlayConversations方法中,now I的值为1,因此它将播放下一个最后一项。因此,如果有3个项目,它将播放第一个和最后一个,但不会播放中间的项目。

您不应该修改当前正在迭代的集合。您遇到的问题是原因之一。在您的情况下,有几个选项,一个简单的解决方案是复制对话列表,同时清除原始列表:

public IEnumerator PlayConversations()
{
    var conversations = conversationsToPlay.ToArray(); // Copy the list
    conversationsToPlay.Clear(); // Immediately clear the original list

    for (int i = 0; i < conversations.Length; i++) // iterate over the array
    {
        // Now you also don't need to remove items anymore, 
        // since you already cleared the list
        yield return StartCoroutine(PlayConversation(conversations[i]));
    }
}

在使用第二个示例时,您也可以使用队列而不是对话列表,因为队列是专门为先进先出访问而设计的

您不应该修改当前正在迭代的集合。您遇到的问题是原因之一。在您的情况下,有几个选项,一个简单的解决方案是复制对话列表,同时清除原始列表:

public IEnumerator PlayConversations()
{
    var conversations = conversationsToPlay.ToArray(); // Copy the list
    conversationsToPlay.Clear(); // Immediately clear the original list

    for (int i = 0; i < conversations.Length; i++) // iterate over the array
    {
        // Now you also don't need to remove items anymore, 
        // since you already cleared the list
        yield return StartCoroutine(PlayConversation(conversations[i]));
    }
}

在使用第二个示例时,您也可以使用队列而不是对话列表,因为队列是专门为先进先出访问而设计的

如果您没有维护订单的业务需求,那么在计划删除项目时,始终以相反的顺序迭代集合。这样,您可以在不中断数组顺序的情况下删除项。所以这里

public IEnumerator PlayConversations()
{
    for (int i = conversationsToPlay.Count-1; i >=0;  i++)
    {
        yield return StartCoroutine(PlayConversation(conversationsToPlay[i]));
    }
}

此方法通常适用于从集合中删除某些内容的所有情况。然而,另一方面,删除Playconversation方法中的对话只是一种不好的做法。您将得到难以维护的代码。用专门用于此目的的方法将其移除。否则,您违反了SRP

如果您没有维护订单的业务需求,那么当您计划删除项目时,请始终以相反的顺序迭代集合。这样,您可以在不中断数组顺序的情况下删除项。所以这里

public IEnumerator PlayConversations()
{
    for (int i = conversationsToPlay.Count-1; i >=0;  i++)
    {
        yield return StartCoroutine(PlayConversation(conversationsToPlay[i]));
    }
}

此方法通常适用于从集合中删除某些内容的所有情况。然而,另一方面,删除Playconversation方法中的对话只是一种不好的做法。您将得到难以维护的代码。用专门用于此目的的方法将其移除。否则,您将违反SRP

如果没有这一行“conversationsToPlay.Removeindex;”会发生什么。你试过这个吗?变量“conversations”在哪里?好吧,不用for循环,可以在计数>0时始终播放0,然后在DialogEnd时删除0。另外,一般的指导原则是,当您计划从集合中删除对象时,从结尾到结尾进行迭代。如果没有这一行“conversationsToPlay.Removeindex;”,会发生什么。你试过这个吗?变量“conversations”在哪里?好的,您可以在count>0时始终播放0,然后在dialogend时删除0,而不是for循环。另外,一般的指导原则是,当您计划从集合中删除对象时,从头到脚进行迭代。
public IEnumerator PlayConversations()
{
    while (conversationsToPlay.Count > 0)
    {
        // Better remove the item right here, close to the loop condition. 
        // Makes things easier to understand.
        var conversationIndex = conversationsToPlay[0];
        conversationsToPlay.RemoveAt(0);
        yield return StartCoroutine(PlayConversation(conversationIndex));

    }
}
public IEnumerator PlayConversations()
{
    for (int i = conversationsToPlay.Count-1; i >=0;  i++)
    {
        yield return StartCoroutine(PlayConversation(conversationsToPlay[i]));
    }
}