【问题标题】:Problems with C # Lists - RemoveAtC# 列表的问题 - RemoveAt
【发布时间】:2022-11-14 09:26:32
【问题描述】:

我在 Unity 中练习 C# 列表,但遇到了问题。 我的测试脚本实例化了 5 个添加到游戏对象列表中的预制件。然后我编写了一个生成随机整数的代码,并从该数字移动使用该索引(indexof)实例化的预制件。一切正常,但移动和删除预制件的方法对场景中的所有游戏对象重复,其索引高于所选的一个。我附上这两个脚本以更好地解释问题。 (我只需要执行一次 unlist 方法。

如何解决此问题并一次从列表中删除一项? (每次按下按钮时,都不是现在这样。谢谢)

脚本:

  • NpcController:在每个实例化的预制件中添加
  • ListCOntroller:添加到场景中。

    public class ListCOntroller : MonoBehaviour
{
    public GameObject cubePrefab;
    private GameObject cubeInstance;
    public static List<GameObject> cubeList = new List<GameObject> ();

    public TextMeshProUGUI checkText;

    public static event Action chooseNpc;
    public static int randNpcValue;

    int rand;
    private void Start()
    {
        for(int i =0; i < 5; i++)
        {
            cubeInstance = Instantiate(cubePrefab, new Vector3(i, -2, 0), Quaternion.identity);
            cubeList.Add(cubeInstance);
        }
    }

    public void CheckListText()
    {
        checkText.text = "Npc in list: " + cubeList.Count.ToString();
    }

    public static void SelectRandomCube()
    {
        
        randNpcValue = Random.Range(0, cubeList.Count);
        chooseNpc?.Invoke();
    }

    
}

公共类 NpcController : MonoBehaviour {

void Start()
{
    ListCOntroller.chooseNpc += NpcEvent;
}

private void NpcEvent()
{

    if (ListCOntroller.cubeList.IndexOf(gameObject) == ListCOntroller.randNpcValue)
    {
        transform.localPosition = new Vector3(transform.position.x, 2, 0);
        DeleteFromList();
        
    }
}

private void DeleteFromList()
{
    ListCOntroller.cubeList.RemoveAt(ListCOntroller.randNpcValue);

    Debug.Log($"Delete from list: {ListCOntroller.randNpcValue}");
    
}

}


附图中生成的 int 随机数为:2

【问题讨论】:

  • 首先,一个格式很好的问题,做得很好。关于这个问题,你的代码对我来说看起来不错,我真的无法发现一个问题,我担心......日志消息是否也打印了多次?可能是按钮调用了 chooseNpc 函数。不知何故多次?
  • 这段代码有很多问题。 1) ListCOntroller 可以被多次实例化 2) ListCOntroller 应该是一个单例,但是它的编写方式不是 Unity-singleton 安全的 3) 使用 static 和引用类型 4) 使用 static 和预制件等 Unity 引用类型可能导致您的代码引用已被 Unity 销毁的对象
  • 在 Unity 中使用 static 时要小心 - thar be dragons。团结是一个CLR 主机它可以而且将扎普主应用程序域连同你所有的物品包括单身人士不仅在运行时,而且在使用编辑.也可以看看Details of disabling Domain and Scene Reload.
  • @MickyD 实际上,我在销毁使用静态方法和变量的实例化对象时遇到了麻烦。我怎样才能解决这个问题? (不幸的是,除了使用静态事件和方法之外,我不知道管理实例化对象事件的任何其他解决方案)。我是团结的新手,我为琐碎的问题道歉
  • @sommmen 谢谢,我尽我所能使它易于阅读和理解我的问题:) 我在按下按钮时输入了一条调试消息,它被调用一次,问题似乎是每个调用的事件对象,所以 indexof 总是更新的。

标签: c# unity3d


【解决方案1】:

因为事件是一个接一个执行的。

假设您有 3 个 NPC:NPC0, NPC1, NPC2

现在你选择的随机数为1,当NPC1的NpcEvent运行时,ListCOntroller.cubeList.IndexOf(gameObject)为1等于randNpcValue,然后NPC1将从列表中删除。

请注意,现在列表还剩下 2 项:NPC0, NPC2。接下来NPC2的NpcEvent依次运行,此时ListCOntroller.cubeList.IndexOf(gameObject)仍为1,因为列表只有2项,所以NPC2也从列表中删除。

一个解决方案是您可以在移除 NPC 时将randNpcValue 更改为无效值。

if (ListCOntroller.cubeList.IndexOf(gameObject) == ListCOntroller.randNpcValue)
{
    transform.localPosition = new Vector3(transform.position.x, 2, 0);
    DeleteFromList();
    ListCOntroller.randNpcValue = -2;
}

【讨论】:

  • 谢谢,您已经非常清楚地解释了调用事件时会发生什么,现在一切都更清楚了。您的代码有效,使用 try-catch 可能会更好,对吧?
  • 试着抓?为什么??? try-catch是用来捕捉异常的,但是代码中并没有抛出异常。但是我在回答中发现了一个问题请注意,randNpcValue不能设置为-1,因为IndexOf在找不到对象时返回-1。
  • “randNpcValue 不能设置为 -1,因为 IndexOf 在找不到对象时返回 -1。”我的意思是这个错误,使用 try-catch 代替代码可以正常工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-03
  • 2012-10-07
  • 1970-01-01
  • 2020-09-27
  • 1970-01-01
  • 1970-01-01
  • 2017-06-14
相关资源
最近更新 更多