Why is my List adding to same array object again and again in update?
I'm trying to build an alternative system to tagging as my project will abuse it.
All GameObjects of interest have a common "tag" which are added to an array called 'typeList'.
Then a List<> called 'nameList' looks through the array and adds those with a certain (name) which is equal to a public string.
The issue is the object added to the List seem to be looping, so it adds over and over again in update. What mistake am I making? or is there a much better way to do this?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class AmountUI : MonoBehaviour
{
public string compoundVarible;
public List<Object> nameList;
public GameObject[] typeList;
void Start()
{
List<Object> nameList = new List<Object>();
if (gameObject.GetComponentInParent<UISystems>().Isotope > 0)
{
compoundVarible = gameObject.GetComponentInParent<UISystems>().Isotope + gameObject.GetComponentInParent<UISystems>().Symbol;
}
else if (gameObject.GetComponentInParent<UISystems>().Isotope == 0)
{
compoundVarible = gameObject.GetComponentInParent<UISystems>().Symbol;
}
else
{
return;
}
}
void Update()
{
this.GetComponent<Text>().text = number.ToString();
typeList = (GameObject.FindGameObjectsWithTag("Element"));
for (int i = 0; i < typeList.Length; i++) //for loop (Foreach?/ while)
{
if (typeList[i].name.Contains(compoundVarible))
{
nameList.Add(typeList[i]);
break;
}
else
{
return;
}
}
}
}
Thanks, - as you can see I am fairly new to programming.
Answer by lcplrice · May 30, 2020 at 11:09 PM
Not sure inside Update is the best place for this code this will run and update the typeList and add new objects every single frame. However, to answer the question to prevent the loop from adding multiple items:
using System.Linq;
...
if (nameList.Where(n => n == typeList[i]).FirstOrDefault() == null)
nameList.Add(typeList[i]);
else
// item already exists in nameList.
Ah yes that works however, if another object shows in typeList[i] with a different name to (compoundVarible), it stops counting through the array for any other objects.
$$anonymous$$y aim is to have this script attached to a GUI child attached to many GameObjects with different names - where the script will add Tagged objects from hierarchy into the array 'typeList' and look through them to find matching names to (compoundVarible) and add them to nameList.
The main idea is so the 'nameList' can be counted and compared to other objects 'namelist'. Very similar to counting how many tags there are in scene.
the original code using tags:
void Update()
{
GameObject[]
gameObjects = (GameObject.FindGameObjectsWithTag(compoundVarible));
number = gameObjects.Length;
this.GetComponent<Text>().text = number.ToString();
Hmm, have you thought about a ScriptableObject setup for this? Then have a script you can attach to the GameObject that will register itself to the list, OnEnable would be the best choice, the unregister OnDisable. This would lower the overhead of the call on every loop and create a shareable list of all active objects.
$$anonymous$$y thought is something like object pooling. Unless I am completely missing the point, in that case I'm sorry. :)
Sample just off the top of my head without testing.
public class NameList : ScriptableObject
{
public List<GameObject> $$anonymous$$yList;
public void Register(GameObject go)
{
if ($$anonymous$$yList.Where(i => i == go).FirstOrDefault() == null) { $$anonymous$$yList.Add(go); }
}
public void UnRegister(GameObject go)
{
if ($$anonymous$$yList.Where(i => i == go).FirstOrDefault() == null) return;
$$anonymous$$yList.Remove(go);
}
}
then on your game objects something like
public class RegisterNameList : $$anonymous$$onoBehaviour
{
public NameList nameList; // attach the scriptable object here from inspector
private void OnEnable()
{
nameList.Register(this);
}
private void OnDisable()
{
nameList.UnRegister(this);
}
}
Thankyou! It looks promising, though at the moment I cant use :
private void OnEnable()
{
nameList.Register(this);
}
private void OnDisable()
{
nameList.UnRegister(this);
}
on a gameobject as it comes up with error : Argument 1: cannot convert from 'RegisterObjectList' to 'UnityEngine.GameObject.
('RegisterObjectList' = script name. )