You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Unity中Sprite列表与字符串列表使用相同顺序洗牌?

如何让两个列表同步洗牌(保持相同打乱顺序)

当前两次调用Shuffle方法时,每次都会生成独立的随机数序列,导致两个列表的打乱顺序不一致。要解决这个问题,核心是让两个列表使用同一组随机交换规则,以下是两种可行的解决方案:

方案一:通过统一索引序列同步洗牌

先生成一个打乱的索引数组,再根据这个索引重新排列两个列表,确保元素的对应关系完全一致。

修改后的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Linq;

public class ShuffleList : MonoBehaviour
{
    public List<Sprite> iconSprite = new List<Sprite>();
    public List<string> priceText = new List<string>();

    void Start()
    {
        // 先检查列表长度一致性,避免索引越界
        if (iconSprite.Count != priceText.Count)
        {
            Debug.LogError("iconSprite和priceText列表长度必须相同!");
            return;
        }

        // 生成0到列表长度-1的索引数组
        int[] shuffledIndices = Enumerable.Range(0, iconSprite.Count).ToArray();
        // 打乱索引数组
        shuffledIndices.Shuffle();

        // 根据打乱后的索引重新构建两个列表
        List<Sprite> newSprites = new List<Sprite>();
        List<string> newTexts = new List<string>();
        foreach (int index in shuffledIndices)
        {
            newSprites.Add(iconSprite[index]);
            newTexts.Add(priceText[index]);
        }

        // 替换原列表
        iconSprite = newSprites;
        priceText = newTexts;
    }
}

public static class IListExtensions {
    /// <summary>
    /// Shuffles the element order of the specified list.
    /// </summary>
    public static void Shuffle<T>(this IList<T> ts) {
        var count = ts.Count;
        var last = count - 1;
        for (var i = 0; i < last; ++i) {
            var r = UnityEngine.Random.Range(i, count);
            var tmp = ts[i];
            ts[i] = ts[r];
            ts[r] = tmp;
        }
    }
}

方案二:让Shuffle方法共享同一个随机数生成器

修改扩展方法,允许传入一个System.Random实例,让两次洗牌使用同一个随机数生成器,保证随机交换的顺序完全一致。

修改后的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ShuffleList : MonoBehaviour
{
    public List<Sprite> iconSprite = new List<Sprite>();
    public List<string> priceText = new List<string>();

    void Start()
    {
        if (iconSprite.Count != priceText.Count)
        {
            Debug.LogError("iconSprite和priceText列表长度必须相同!");
            return;
        }

        // 创建共享的随机数生成器(指定固定种子可让每次洗牌结果一致,比如new System.Random(123))
        System.Random sharedRng = new System.Random();
        
        // 使用同一个随机数生成器洗牌两个列表
        iconSprite.Shuffle(sharedRng);
        priceText.Shuffle(sharedRng);
    }
}

public static class IListExtensions {
    /// <summary>
    /// 使用指定的随机数生成器打乱列表
    /// </summary>
    public static void Shuffle<T>(this IList<T> ts, System.Random rng) {
        var count = ts.Count;
        var last = count - 1;
        for (var i = 0; i < last; ++i) {
            // 使用传入的随机数生成器获取索引
            var r = rng.Next(i, count);
            var tmp = ts[i];
            ts[i] = ts[r];
            ts[r] = tmp;
        }
    }

    // 保留原无参方法,兼容其他场景
    public static void Shuffle<T>(this IList<T> ts) {
        ts.Shuffle(new System.Random());
    }
}

注意事项:

  • 必须确保两个列表的长度完全相同,否则会出现索引不匹配或越界问题。
  • 如果需要每次运行游戏时洗牌结果一致,可以给System.Random指定固定种子。

内容的提问来源于stack exchange,提问作者Roy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 18:40:26