#c# #list #unity3d #scripting
#c# #Список #unity3d #сценарии
Вопрос:
У меня есть этот скрипт для добавления выбранных мною игровых объектов в список (во время выполнения).
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. Нравится:
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));
}
РЕШАЕМАЯ,
скрипт для двух списков:
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}n{l2}");
MergeLists.text = string.Join("n", zipped);
}
}
Комментарии:
1. что именно вы имеете в виду? Используя Linq , вы могли бы , например , сделать
var texts = Objects3d.Select(obj => obj.GetComponent<Text>().text).ToList();
Или вы имеете в виду , что хотите получитьchild.gameObject.GetComponent<Text>().text
?2. @derHugo Я отредактировал свой пост, думаю, теперь он немного более описательный. по сути, я хочу сделать следующее: после добавления всех нужных мне игровых объектов в список мне нужно получить текстовый компонент каждого игрового объекта и объединить их в новую текстовую переменную. например: MergeText.text = ListIndex1.text ListIndex2.text и т. Д;
3. но получить текстовые компоненты чего? дочерние объекты, которые вы собираете в
Objects3d
?4. Правильно, мне нужно получить текстовые компоненты дочерних объектов, которые я собираю в 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.
На ваш последующий вопрос из комментариев
Для двух списков вы могли бы либо использовать первый подход, но выполнить итерацию по индексу, например
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}n{l2}");
MergeText.text = string.Join("n", zipped);
Однако могут быть и более элегантные решения (в настоящее время только на моем смартфоне).
Комментарии:
1. то есть это решение, которое я хотел, спасибо. Я добавил окончательный сценарий к своему сообщению.
2. @Elfasito рад, что мы разобрались с этим 😉
3. Хьюго, может, я еще раз побеспокоюсь?. Я добавил второй список в свой скрипт, его копию с первого, но с другим дочерним элементом. Теперь я хочу объединить два списка (текстовые компоненты) в новой текстовой переменной и отобразить результирующую текстовую переменную следующим образом: 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 Возможно ли это решить?.
4. предполагая, что оба списка имеют одинаковую длину, вы могли бы либо использовать первый фрагмент, повторяющийся вместо этого по индексу, подобному
for(var i =0; i< Objects3d.Length; i ){ stringBuilder.Append(Objects3d[i]).Append('n').Append(otherList[i]).Append('n'); }
, либо вы могли бы использовать второйLinq
подход и использовать.Zip
для «объединения» обоих списков вместе в первую очередь5. Спасибо за ответ. Я пытаюсь использовать решение linq. работает, но с проблемой. на каждой итерации объекты, которые я уже добавил в список, повторяются в переменной MergeText , например, как (результат Mergetext): первая итерация: name1 description1 name1 description1 name2 description2 name2 description2 третья итерация: name1 description1 name1 description1 name2 description2. третья итерация: name1 description1 name1 description1 name2 description2 имя2 описание2 имя2 описание2 имя3 описание3 имя3 описание3 имя3 описание3
Ответ №2:
Я не знаю, что вы имеете в виду, вы можете это сделать: var TextsList = Objects3d.Select(object => object.GetComponent<Text>()).ToList()
Чтобы получить текст всех объектов, вы можете использовать where для выбора компонента из списка, где указано ваше значение: string text = Objects3d.Where(object => object.GetComponent<Text>() = "your_value");
Это базовый C#