- Home /
My list is overwriting the data it was holding with the newest element added to the list.
I'm not very good at coding so I'm sure this is just something dumb that I'm doing wrong or not doing, but basically I have a list its holding a class in it and it seems to be working the first time I use it. Then if I add to that list again it overwrites the data in the first element with the newest one. I'm not exactly sure what I need to do to fix it so if someone could take a look and let me know whats wrong with it that would be a big help.
I believe you can ignore everything in the NewUnitStats () Method I was using that for testing and for calling AddPlayerToList () method but, I might be wrong.
public class MakeNewUnit : MonoBehaviour {
private CreateNewPlayerCharacter createNewPlayerCharacter;
public List<CreateNewPlayerCharacter> listOfPlayerCharacters;
public string unitName;
public string unitClassName;
public string unitRaceName;
public ScriptableObjectTest[] scriptObjTester;
void Start()
{
createNewPlayerCharacter = GetComponent<CreateNewPlayerCharacter>();
}
public void NewUnitStats()
{
unitName = createNewPlayerCharacter.baseUnitStats.unitName;
unitClassName = createNewPlayerCharacter.pickedClass.className;
unitRaceName =createNewPlayerCharacter.pickedRace.raceName;
Debug.Log("click working " + unitRaceName);
scriptObjTester = createNewPlayerCharacter.baseUnitStats.scriptObjSaveTest;
foreach (ScriptableObjectTest scriptObjTester in scriptObjTester)
{
int counterValue = scriptObjTester.value;
counterValue += 25;
//counterValue = counterValue + 20;
//Debug.Log(scriptObjTester.name);
//Debug.Log(scriptObjTester.value);
//Debug.Log(counterValue);
}
AddPlayerToList();
}
private void AddPlayerToList()
{
listOfPlayerCharacters.Add(createNewPlayerCharacter);
int index = listOfPlayerCharacters.IndexOf(createNewPlayerCharacter); // finds the number in the list
foreach (CreateNewPlayerCharacter unit in listOfPlayerCharacters)
{
Debug.Log("Unit " + index + " " + unitClassName + " " + unitRaceName);
}
}
}
When you say you "add to the list again", do you mean you run the NewUnitStats()
(which eventually runs the AddPlayerToList()
) or do you manually add to the list outside of the script? I just want to clarify some things.
In this it runs NewUnitStats() which eventually runs AddPlayerToList()
Answer by Vyzier · Mar 23, 2018 at 03:51 AM
I think I know what the problem here is.
The problem is that each of the CreateNewPlayerCharacter
components in your list references the same component that's on your game object (the one which this MakeNewUnit component is on).
All the items in your list are just references to the main component (in this case, the component that you have attached to the game object) and they are not separate instances of that component.
So if you change something on the main component, when you go and print the values for each item, they all "look" at the main component and print the main component's values instead.
You have 3 choices (that I could think of) if you want to do what I think you want to do (which is to save multiple instances of the same component, right?)
1. Use scriptable objects. There are lots of tutorial about this on Youtube, and they explain it better there. But basically they're used to store data (like the different values on your component you want to store) in separate .asset files. However, this is useless when you want to procedurally create them during runtime. But if you're creating premade units (that is, you don't procedurally create them) then that's perfect to use. You can then copy their values to components when you create the new, different components using AddComponent()
2. Attach different instances of the component with different values using AddComponent()
. You can attach all of the new instances in the same object, or on different objects; that is up to you.
3. You can serialize (or save) the values to files and load them when you need them. You can save them in .json files using this, for example: https://github.com/SaladLab/Json.Net.Unity3D/releases. If you decide to use this, the documentation is here: https://www.newtonsoft.com/json/help/html/Introduction.htm
Hope this helped you out, even for a bit! If you still have more questions, please don't hesitate to ask! Happy coding!
I don't think the first two ways are going to work the way I was hoping for in the game. So if I ins$$anonymous$$d tried to save them using Json how would I do that without overwriting the data like I'm doing now? Wouldn't any list I tried to make with this data end up doing the same thing? Or am I thinking about this wrong?
Answer by Cornelis-de-Jager · Mar 23, 2018 at 03:42 AM
Your list is fine and gets updated just right, its how you choose to display the data that's wrong. Try the following:
private void AddPlayerToList()
{
// This is fine
listOfPlayerCharacters.Add(createNewPlayerCharacter);
// finds the number in the list
foreach (CreateNewPlayerCharacter unit in listOfPlayerCharacters)
{
// Find the Index
int index = listOfPlayerCharacters.IndexOf(unit);
// Assign the names
string className = unit.unitClassName;
string raceName = unit.unitRaceName;
Debug.Log("Unit " + index + " " + className + " " + raceName);
}
}
Oh wow, you can do that?! I still have much to learn about C#, I suppose.
Edit: Since OP changed his/her answer, I was surprised about the fact that you can do listOfPlayerCharacters.Add(createNewPlayerCharacter.$$anonymous$$emberwiseClone())
to create a copy of that instance.
yea sorry about the change, but as you said, memberwiseClose works when you want to add Unique objects based of the same object.
Your answer
![](https://koobas.hobune.stream/wayback/20220612155159im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Access list storing custom class variables from another script 1 Answer
Temporary GameObject Movement 0 Answers
Why is my list not filling 1 Answer
Comparing list values 1 Answer