如何实现单个GameObject随机控制多个不重复的GameObject?
问题描述
我希望为每个GameObject随机分配多个可控制的GameObject,但当前代码仅能为每个GameObject分配单个控制对象。同时需要避免同一GameObject被重复分配给其他对象,不确定是否可以通过循环现有代码来实现多控制需求。
当前实现单对象分配的代码
void AssignChildren () { pieces = GameObject.FindGameObjectsWithTag("Piece").OrderBy( go => go.name ).ToArray(); int pieceCount = pieces.Length; Debug.Log (pieceCount); List<int> usedNumbers = new List<int>(); int newNumber; for (int iter = 0; iter < pieceCount; iter++) { newNumber = Random.Range (0, pieceCount); PieceScript parentToChildComp = pieces [newNumber].GetComponent<PieceScript>(); while( usedNumbers.Contains( newNumber ) || newNumber == iter || parentToChildComp.whoDoIControl == iter)//add impossible fix here. { newNumber = Random.Range( 0, pieceCount); parentToChildComp = pieces [newNumber].GetComponent<PieceScript>(); } PieceScript assignPieceChild = pieces [iter].GetComponent<PieceScript>(); assignPieceChild.whoDoIControl = newNumber; // this needs to be edited to an array whoDoIControl[iter] for multiple children I think. usedNumbers.Add( newNumber ); } cameraCenter = ((pieces[pieceCount - 1].transform.position - pieces[0].transform.position)) + pieces[0].transform.position; transform.position = new Vector3(cameraCenter.x, cameraCenter.y,-10); }
修改方案
1. 调整PieceScript的字段定义
首先把单个控制对象的字段改成列表,支持存储多个控制目标:
public class PieceScript : MonoBehaviour { // 替换原来的int whoDoIControl public List<int> whoDoIControl = new List<int>(); // 其他原有代码... }
2. 重写多对象分配逻辑
不能直接循环原代码,要维护全局的可用对象索引池,确保每个对象仅被分配一次。假设每个GameObject需要分配controlCount个控制对象,代码如下:
void AssignMultipleChildren(int controlCount) { pieces = GameObject.FindGameObjectsWithTag("Piece").OrderBy(go => go.name).ToArray(); int pieceCount = pieces.Length; Debug.Log(pieceCount); // 先做合法性检查:每个对象最多只能控制除自己外的所有对象 if (controlCount >= pieceCount - 1) { Debug.LogError("控制数量不能超过总对象数减1(每个对象不能控制自己)"); return; } // 初始化全局可用索引池,包含所有对象的索引 List<int> availableIndices = Enumerable.Range(0, pieceCount).ToList(); foreach (int iter in Enumerable.Range(0, pieceCount)) { PieceScript currentPiece = pieces[iter].GetComponent<PieceScript>(); currentPiece.whoDoIControl.Clear(); // 清空旧的分配记录 // 临时移除自身索引,避免控制自己 availableIndices.Remove(iter); // 随机选取指定数量的控制对象 for (int i = 0; i < controlCount; i++) { if (availableIndices.Count == 0) break; int randomPoolIndex = Random.Range(0, availableIndices.Count); int targetIndex = availableIndices[randomPoolIndex]; currentPiece.whoDoIControl.Add(targetIndex); availableIndices.RemoveAt(randomPoolIndex); // 移除已分配的索引,防止重复 } // 将自身放回可用池,让其他对象可以选择控制它 availableIndices.Add(iter); } // 保留原有的相机定位逻辑 cameraCenter = ((pieces[pieceCount - 1].transform.position - pieces[0].transform.position)) + pieces[0].transform.position; transform.position = new Vector3(cameraCenter.x, cameraCenter.y, -10); }
3. 核心逻辑说明
- 全局可用池
availableIndices确保每个对象只会被分配给一个控制者 - 分配时临时移除自身索引,避免对象控制自己,分配完成后放回池内
- 提前做数量合法性检查,防止出现需求超出可分配范围的错误
内容的提问来源于stack exchange,提问作者Ownedbycow
相关产品推荐
相关产品推荐

