如何在列表中获取游戏对象的组件

Posted

技术标签:

【中文标题】如何在列表中获取游戏对象的组件【英文标题】:How to get component of gameobjects in a list 【发布时间】:2020-12-20 12:37:43 【问题描述】:

我有这个脚本可以将我选择的游戏对象添加到列表中(在运行时)。

public Transform ParentOfList;
public List<GameObject> Objects3d = new List<GameObject>();
public GameObject ActualSelected;

public void add3DtoList()

    foreach (Transform child in ParentOfList) // iterate through all first level children
    
        if (child.gameObject.activeSelf)
        
            Debug.Log($"The child child.name is active!");
            ActualSelected = child.gameObject;
            if (Objects3d.Contains(ActualSelected))
            
                Debug.Log("Already exist in list");
            
            else
            
                Objects3d.Add(ActualSelected); //add the actual gameobject selected in runtime to list
            
        
    

PD:父游戏对象同时只有一个子对象处于活动状态。

添加到列表中的每个游戏对象都有一个文本组件,我想从列表中获取这些单独的文本组件并将其放入一个新的变量文本中。 喜欢:

Text MergeText;
MergeText.text = ListIndex1.text + ListIndex2.text + etc;

我不知道如何实现。一些指导?谢谢。

已解决, 脚本一列表:

public Transform ParentOfList;
    public List<GameObject> Objects3d = new List<GameObject>();
    public GameObject ActualSelected;
    public Text MergeText;

    public void add3DtoList()
    
        foreach (Transform child in ParentOfList) // iterate through all first level children
        
            if (child.gameObject.activeSelf)
            
                Debug.Log($"The child child.name is active!");
                ActualSelected = child.gameObject;
                if (Objects3d.Contains(ActualSelected))
                
                    Debug.Log("Already exist in list");
                
                else
                
                    Objects3d.Add(ActualSelected); //add the actual gameobject selected in runtime to list
                
            
        
        MergeText.text = string.Join("\n", Objects3d.Select(obj => obj.GetComponent<Text>().text));
    

已解决, 两个 List 的脚本:

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

public class LIST3DOBJECTS : MonoBehaviour

    public Transform ParentOfListCodigo;
    public Transform ParentOfListDesc;
    public List<GameObject> Objects3dCodigo = new List<GameObject>();
    public List<GameObject> Objects3dDesc = new List<GameObject>();
    public GameObject ActualSelectedCode;
    public GameObject ActualSelectedDesc;
    public Text MergeTextCode;
    public Text MergeTextDesc;
    public Text MergeLists;

    public void add3DtoList()
           
        foreach (Transform child in ParentOfListCodigo) // iterate through all first level children
        
            if (child.gameObject.activeSelf)
            
                Debug.Log($"The child child.name is active!");
                ActualSelectedCode = child.gameObject;
                if (Objects3dCodigo.Contains(ActualSelectedCode))
                
                    Debug.Log("Already exist in list");
                
                else
                
                    Objects3dCodigo.Add(ActualSelectedCode); //add the actual gameobject selected in runtime to list
                
            
        
        MergeTextCode.text = string.Join("\n", Objects3dCodigo.Select(obj => obj.GetComponent<Text>().text)); //first list, show the code (name), of the children gameobject


        foreach (Transform child in ParentOfListDesc) // iterate through all first level children
        
            if (child.gameObject.activeSelf)
            
                Debug.Log($"The child child.name is active!");
                ActualSelectedDesc = child.gameObject;
                if (Objects3dDesc.Contains(ActualSelectedDesc))
                
                    Debug.Log("Already exist in list");
                    
                
                else
                
                    Objects3dDesc.Add(ActualSelectedDesc); //add the actual gameobject selected in runtime to list
                    
                
            
        
        MergeTextDesc.text = string.Join("\n", Objects3dDesc.Select(obj => obj.GetComponent<Text>().text)); //second list, show the description of the children gameobject
        CleanText();
    

    private void CleanText()
    
        var list1 = Objects3dCodigo.Select(child => child.GetComponent<Text>().text);
        var list2 = Objects3dDesc.Select(child => child.GetComponent<Text>().text);
        var zipped = list1.Zip(list2, (l1, l2) => $"l1\nl2");
        MergeLists.text = string.Join("\n", zipped);
    


【问题讨论】:

你到底是什么意思?使用 Linq 你可以例如做var texts = Objects3d.Select(obj =&gt; obj.GetComponent&lt;Text&gt;().text).ToList(); 还是你的意思是你想得到child.gameObject.GetComponent&lt;Text&gt;().text @derHugo 我编辑了我的帖子,我认为现在更具描述性。基本上我想要做的是:在将所有我需要的游戏对象添加到列表中之后,我需要获取每个游戏对象的文本组件并将它们合并到一个新的文本变量中。比如:MergeText.text = ListIndex1.text + ListIndex2.text + etc; 但是得到的文本组件是什么?您在Objects3d 中收集的子对象? 正确,我需要获取我在 Objects3d 中收集的子对象的文本组件 【参考方案1】:

听起来你想做的事情就像例如

var stringBuilder = new StringBuilder();
foreach(var child in Objects3d)

    stringBuilder.Append(child.GetComponent<Text>().text);

MergeText.text = stringBuilder.ToString();

或者如果你想使用Linq 你也可以例如做类似的事情

MergeText.text = string.Join("", Objects3d.Select(child => child.GetComponent<Text>().text));

除了"",您还可以使用“分隔符” - 分隔符字符串,例如" "", ""\n"

同样的东西,你当然也可以使用 upper 方法附加。


关于 cmets 的后续问题

对于两个列表,您可以采用第一种方法,但可以通过索引进行迭代,例如

for(var i =0; i< Objects3d.Length; i++)
  
    stringBuilder.Append(Objects3d[i]).Append('\n')
        .Append(otherList[i]).Append('\n'); 

或者您可以使用第二种Linq 方法并使用.Zip 首先我认为将两个列表“合并”在一起,例如像这样

var list1 = Objects3d.Select(child => child.GetComponent<Text>().text);
var list2 = OtherList.Select(child => child.GetComponent<Text>().text);
var zipped = list1.Zip(list2, (l1, l2) => $"l1\nl2");
MergeText.text = string.Join("\n", zipped);

可能还有更优雅的解决方案(目前仅在我的智能手机上)

【讨论】:

就是这样,这就是我想要的解决方案,谢谢。我将最终脚本添加到我的帖子中。 @Elfasito 很高兴我们知道了 ;) 雨果,我可以再打扰一次吗?我在脚本中添加了第二个列表,它是第一个列表的副本,但还有另一个孩子。现在我想组合两个列表(文本组件),在一个新的文本变量中并显示结果文本变量,如下所示: list1-child1.text + list2-child1.text list1-child2.text + list2-child2 .text 我试过这个:codeshare.io/2KOxOY 但我的功能尝试向我展示了如下内容:list1-child1.text + list1-child2.text。 list2-child1.text + list2-child2.text 有可能解决吗?。 假设两个列表的长度相同,您可以使用第一个 sn-p 迭代,而不是使用像 for(var i =0; i&lt; Objects3d.Length; i++) stringBuilder.Append(Objects3d[i]).Append('\n').Append(otherList[i]).Append('\n'); 这样的索引,或者您可以使用第二个 Linq 方法并使用 .Zip 来“合并" 两个列表首先一起列出 感谢您的回答。我正在尝试使用 linq 解决方案。有效,但有问题。在每次迭代中,我已经添加到列表中的对象在 MergeText var 中重复,例如(Mergetext 结果):第一次迭代: i> name1 + description1 第二次迭代: name1 + description1 name1 + description1 name2 + description2 name2 + description2 第三次迭代: name1 + description1 name1 + description1 name1 + description1 name2 + description2 name2 + description2 name2 + description2 name3 + description3 name3 + description3 name3 + description3【参考方案2】:

我不知道你的意思,你可以这样做:var TextsList = Objects3d.Select(object =&gt; object.GetComponent&lt;Text&gt;()).ToList() 要获取所有对象文本,或者你可以使用 where 从列表中选择组件的值在哪里:string text = Objects3d.Where(object =&gt; object.GetComponent&lt;Text&gt;() = "your_value"); 它是基本的 C#

【讨论】:

以上是关于如何在列表中获取游戏对象的组件的主要内容,如果未能解决你的问题,请参考以下文章

如何从预制件中获取场景中游戏对象的引用

如何在脚本中仅使用游戏对象启用 Unity C# 中的部件/组件

在游戏子系统中注册游戏对象组件? (基于组件的游戏对象设计)

如何在帖子中从 ViewComponent 获取对象?

如何使游戏对象列表消失动画? (或如何在设置 alpha 值时解决奇怪的行为)

如何获取嵌套的 JSON 数据列表并将其显示在 MatTable 中?