如何在 Unity 中的特定位置生成预制件,然后删除该值?
Posted
技术标签:
【中文标题】如何在 Unity 中的特定位置生成预制件,然后删除该值?【英文标题】:How can I spawn a prefab in Unity in a specific position and then delete that value? 【发布时间】:2021-06-05 00:59:50 【问题描述】:我正在制作一个游戏,一个迷宫,你必须在其中收集 10 个拾取物才能赢得游戏。其中一些拾音器将始终在相同的位置,但还有一些会在开始时使用 for 循环在随机位置生成(之前在代码中声明了所有可能的选项)。这个想法是,当一个元素被生成时,包含该位置的 Vector3 必须从 List 中删除,因此它不能在同一位置再次生成。
我试过用数组来做这件事,但我不能轻易地删除那个值,所以我决定试试 Lists。我发现this post 旨在使用列表并提供解决方案,但是当我尝试时它不起作用。没有生成拾取器,但我无法找到错误。
代码如下:
public GameObject pointPrefab;
List<Vector3> positions = new List<Vector3>();
public Vector3[] vectorPositions =
new Vector3 (237.05f, 0,- 34.02419f), // Position 0
// ... More positions here
new Vector3 (207.1207f, 0, -74.42f), // Position 8
;
void Start()
positions.Add(new Vector3(237.05f, 0, -34.02419f));
// ... More positions here
positions.Add(new Vector3(207.1207f, 0, -74.42f));
for (int i = 0; i < 6; i++)
spawnItem();
void spawnItem()
int index = selectRandom();
Vector3 vector = RemoveAndGet(positions, index);
Instantiate(pointPrefab, vector, Quaternion.identity);
int selectRandom()
return Random.Range(0, positions.Count);
public T RemoveAndGet<T>(IList<T> list, int index)
lock (list)
T value = list[index];
list.RemoveAt(index);
return value;
此外,您还看到了一个名为 vectorPositions 的数组。我想声明该数组中的所有 Vector3,然后只需使用 position.AddRange(vectorPosition) 将它们全部分配给 List(这对我来说更容易阅读)。但这也不起作用(好吧,我不知道它是否起作用,因为没有生成拾取器)
希望你能帮帮我,我看不出这里出了什么问题。
谢谢!
【问题讨论】:
检查你的程序是否工作以及它如何工作、出现什么问题以及甚至没有开始工作的最佳方法是使用 PRINT() 或 DEBUG.LOG() 调试你的程序的 我现在去看看调试的时候有没有明白的,谢谢分享! HashSet 或 Dictionary 可能更适合这里。 Debug.Log() 应该打印我在控制台中作为参数输入的内容,对吧?因为 spawnItem() 没有被初始化。我也要检查 HashSet 和 Dictionary。 你为什么不“洗牌”列表并选择 6 个连续的值呢?真的需要从原始列表中删除它们吗?为什么lock
?我没有看到涉及任何多线程,所以这似乎毫无意义。你也知道你可以使用例如positions = vectorPositions.ToList();
或 positions = new List<Vector3>(vectorPositions);
...
【参考方案1】:
有多种方法可以做到这一点。例如。你可以简单地写
positions = vectorPositions.ToList();
也可以
positions = new List<Vector3>(vectorPositions);
但是,为什么还要创建数组的副本?
你也可以做到
public List<Vector3> vectorPositions = new List<Vector3> ... ;
如果您确实需要在运行时删除项目。
无论如何,您还可以使用 Linq OrderBy
和 Random.value
作为排序标准和 Take
更轻松地生成 6 个随机元素,以便从该随机列表中获取前 6 个连续条目
using System.Linq;
...
var sixRandomPositions = vectorPositions.OrderBy(p => Random.value).Take(6);
foreach(var position in sixRandomPositions)
Instantiate(pointPrefab, position, Quaternion.identity);
不改变原来的vectorPositions
。
【讨论】:
以上是关于如何在 Unity 中的特定位置生成预制件,然后删除该值?的主要内容,如果未能解决你的问题,请参考以下文章