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

如何实现单个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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 13:04:54