C# FindObjectsWithTag以统一的随机顺序返回对象?

C# FindObjectsWithTag以统一的随机顺序返回对象?,c#,unity3d,user-interface,unity-ui,C#,Unity3d,User Interface,Unity Ui,我正在尝试做一个关卡选择,需要尽可能少的维护,因为我打算在Unity中添加更新以添加更多关卡Unity场景 为了解释这一点,我尝试在Unity Build设置中为每个级别选择创建按钮的级别,然后从一个预置中创建一个模板对象,它可以将创建的按钮映射到该预置中 我让它大部分工作,但出于某种原因,它以错误的顺序映射按钮,我试图向下到向上,而Unity似乎抓住游戏对象是一个随机顺序 这是我的密码: private Scene[] levels; private int currentBu

我正在尝试做一个关卡选择,需要尽可能少的维护,因为我打算在Unity中添加更新以添加更多关卡Unity场景

为了解释这一点,我尝试在Unity Build设置中为每个级别选择创建按钮的级别,然后从一个预置中创建一个模板对象,它可以将创建的按钮映射到该预置中

我让它大部分工作,但出于某种原因,它以错误的顺序映射按钮,我试图向下到向上,而Unity似乎抓住游戏对象是一个随机顺序

这是我的密码:

    private Scene[] levels;
    private int currentButtonId = 1;   

    public Transform buttonsHolder;
    public GameObject buttonPrefab;
    public GameObject buttonSlotsPrefab;

    private GameObject[] levelButtonSlots;
    private int currentLevelSlot = 0;
    private int numSlotsToMove = 0;

 private void Start()
    {            
        var sceneCount = SceneManager.sceneCountInBuildSettings;
        levels = new Scene[sceneCount];
        for (var i = 0; i < sceneCount; i++) 
        {
            // Beginning Setup
            levels[i] = SceneManager.GetSceneByBuildIndex(i);

            // Look for Level Placement Slots
            levelButtonSlots = GameObject.FindGameObjectsWithTag("Level Slot");

            // If there aren't enough Level Placement Slots make more by creating a template
            if(levelButtonSlots.Length < levels.Length)
            {
                GameObject buttonSlots = Instantiate(buttonSlotsPrefab);
                buttonSlots.transform.position = new Vector2(0, 10 * numSlotsToMove);
                numSlotsToMove++;
            }
            // Go get those new placement slots
            levelButtonSlots = GameObject.FindGameObjectsWithTag("Level Slot");

            // Create Button
            GameObject currentButton = Instantiate(buttonPrefab, buttonsHolder);
            // Move it to the next slot
            currentButton.transform.position = levelButtonSlots[currentLevelSlot].transform.position;
            currentLevelSlot++;

            // Add Text to a new button
            TextMeshProUGUI buttonText = currentButton.GetComponentInChildren<TextMeshProUGUI>();
            buttonText.text = (currentButtonId.ToString());

            // Setup what which scene clicking a button will do
            ButtonManager buttonScript = currentButton.GetComponentInChildren<ButtonManager>();
            buttonScript.sceneToLoad = currentButtonId;

            currentButtonId++;
        }             
    }
buttonsHolder变量在编辑器中设置,是画布。 buttonPrefab是我在编辑器中设置的TextMeshPro按钮预设,它有level Buttons标记和一个简单的脚本,当单击时加载指定的场景。 buttonSlotsPrefab是我在编辑器中设置的一个游戏对象预置,它有Button Placement槽标记,它包含另外8个空的游戏对象,每个都有level槽标记,我使用这8个对象作为指导,来确定在运行时按钮应该放在哪里

同样,我的目标是将按钮从下到上放置,但Unity在运行时却毫无理由地抛出了这一点:

对于一些变量的命名约定,我感到很抱歉,因为我已经连续两天在这里工作了,我很累,也很紧张。一旦我把事情做好,我会把它们修好的


经过进一步的测试,我注意到当我第一次创建ButtonSlotPrefact时,一切都很好,但是,在重新启动Unity之后,当我再次运行游戏时,没有更改任何文件。在重新启动之后,顺序变得随机。这可能是Unity引擎中的一个错误吗?

如果我理解了您的问题,那么您在按钮数量和插槽数量之间存在问题:您在y轴上有间隔的插槽,并且您不总是在屏幕底部有levelsolt[0],所以

您可以在创建按钮之前对y轴上的levelslot进行升序或降序:我正在使用Linq,所以添加时使用System.Linq


如果数组中没有值,我添加了一个测试,但可能错误不存在,我还没有测试过是否按位置值排序?这是因为这是继承人的顺序吗?很难说具体如何排序,但在调用“查找游戏对象”后,只需对游戏对象数组进行排序tag@BugFinder你可能会这么认为,但我已经检查了十几次,以确保它们的顺序正确,我在我的OP中添加了一个部分来解释我遇到的一些可能会影响事情的新情况。@vasmos我知道你说过很难说在查找标记后如何对数组进行排序,但你能想出任何方法吗?这可能是最后的解决办法。将脚本的代码发布到levelButtonSlotsHmm。。。Unity似乎无法识别OrderBy或OrderByDescending,它在两种情况下都会抛出此错误:Assets\Scripts\UI\Level Select\Level SelectManager。cs64,80:错误CS1061:“GameObject[]”不包含“OrderBy”的定义,并且没有可访问的扩展方法“OrderBy”接受类型为“GameObject[]的第一个参数找不到“”,是否缺少using指令或程序集引用?是否添加了using System.Linq;?也就是说,System.Linq是所需的依赖项,在测试OrderBy之后,它可以完美地工作。我真不敢相信我花了这么多时间尝试这么多东西来解决问题,却只有一行字来解决所有问题。非常感谢。我不能再给你6个小时的赏金了,但到时候你会得到的。对我来说,法语的难点是懂英语!!。。很高兴解决您的问题,我建议您测试levelButtonSlots。订购前长度不为零
if (levelButtonSlots.Any())//Same thing than levelButtonSlots.Length > 0
{
    levelButtonSlots = GameObject.FindGameObjectsWithTag("Level Slot").OrderBy(go => go.transform.position.y).ToArray();
}
    levelButtonSlots = GameObject.FindGameObjectsWithTag("Level Slot").OrderByDescending(go => go.transform.position.y).ToArray();