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

如何将3个GameObject随机分配到3个指定位置且无重复?

基于Random.Range的基础实现

你的需求核心是保证每个位置仅被分配一次,我们可以通过维护临时待选位置列表的方式实现,每次从剩余位置中随机选取后移除已用位置,避免重复:

using System.Collections.Generic;
using UnityEngine;

public class RandomPosAssign : MonoBehaviour
{
    public GameObject[] myObjs;
    public Vector3[] myPos;

    void Start()
    {
        // 前置校验,避免数组长度不匹配报错
        if (myObjs.Length != myPos.Length)
        {
            Debug.LogError("物体数组和位置数组长度不一致,请检查配置");
            return;
        }

        List<Vector3> unusedPos = new List<Vector3>(myPos);
        for (int i = 0; i < myObjs.Length; i++)
        {
            // Random.Range整数重载为左闭右开,取[0, unusedPos.Count)刚好覆盖所有剩余位置索引
            int randomIdx = Random.Range(0, unusedPos.Count);
            myObjs[i].transform.position = unusedPos[randomIdx];
            // 移除已分配位置,避免后续重复抽取
            unusedPos.RemoveAt(randomIdx);
        }
    }
}
更优实现方案:Fisher-Yates洗牌算法

上面的方案用到了List.RemoveAt,数组长度较大时会产生O(n²)的时间复杂度,性能较差。更推荐用原地乱序的Fisher-Yates洗牌算法,时间复杂度仅为O(n),内存占用也更低:

using UnityEngine;

public class RandomPosAssign : MonoBehaviour
{
    public GameObject[] myObjs;
    public Vector3[] myPos;

    void Start()
    {
        if (myObjs.Length != myPos.Length)
        {
            Debug.LogError("物体数组和位置数组长度不一致,请检查配置");
            return;
        }

        // 原地打乱位置数组
        for (int i = myPos.Length - 1; i > 0; i--)
        {
            int randomIdx = Random.Range(0, i + 1);
            // 交换当前索引与随机索引的位置
            (myPos[i], myPos[randomIdx]) = (myPos[randomIdx], myPos[i]);
        }

        // 按顺序分配已乱序的位置即可,天然不重复
        for (int i = 0; i < myObjs.Length; i++)
        {
            myObjs[i].transform.position = myPos[i];
        }
    }
}
注意事项
  • Random.Range的整数重载为左闭右开,如果最大值填写为数组/列表长度,不会产生索引越界问题
  • 如果后续需要保留原始位置数组的顺序,只需提前拷贝一份临时数组做乱序操作即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 20:45:04