- Home /
Why does my List overwrite itself when using .Add?
So I'm working on a GameDatabase editor for my project. I've created a custom asset from a ScriptableObject and a Weapon class that extends System.Object. The goal is simple: I want an editor window I set the data for the new weapon in and hit the add button and it will populate a weapon var in the editor window and assigning that to the database asset using .Add.
The problem is: When I use .Add and pass the newly set weapon it overwrites all previous weapons in the asset's weapon list. Does anyone have any idea why? I can't for the life of me figure this out.
EDIT I updated the script below to reflect the proper way to use .add with a list to add items via the editor window.
The Editor Window:
class GameDatabase extends EditorWindow {
//Weapon Variables
var wepname : String = "Weapon Name";
var description : String;
//Database
var database : DatabaseClass;
//Create Window
@MenuItem("Window/GameDatabase")
static function Init () {
var window:GameDatabase = EditorWindow.GetWindow(GameDatabase);
window.Show();
}
function OnInspectorUpdate () {
database = Resources.Load("database");
}
function OnGUI () {
//Weapon Properties
GUILayout.Label ("Weapons", EditorStyles.boldLabel);
wepname = EditorGUILayout.TextField ("Name", wepname);
description = EditorGUILayout.TextField ("Description", description);
//Button to Generate Weapon Data for Database
if (GUILayout.Button ("Add Weapon to Database")) {
var newWeapon = new Weapon();
weapon.name = wepname;
weapon.description = description;
database.weapons.Add(weapon);
EditorUtility.SetDirty(database);
}
}
}
function AddWeapon() { database = Resources.Load("database"); // more code... }
Doesnt this line reset your database class every time you call AddWeapon? Shouldnt you initiate the database only once?
But shouldn't loading the reference from the resources load the previously saved version and not overwrite it? And from my understanding .Add should be appending a new object to the end of the list and not overwriting all the weapons from 0 and up.
You understand .Add correct. Still the database gets reset because unity cannot serialize generic lists in the first place.
Unity can serialize generic lists just fine. The only thing it has problems with is serializing lists with subclasses. for example, you have a class called Laser that extends Weapon and you store that in a list of Weapon, then it won't get deserialized properly. it will deserialize as Weapon ins$$anonymous$$d of Laser
Answer by Zerot · Oct 04, 2012 at 04:47 PM
and the problem is most likely that you don't create a new weapon when saving and it will overwrite the old one(because it is the same reference). Remove the weapon field from the top of the class and use a local variable in AddWeapon to store it; "var weapon: Weapon = new Weapon();"
Just figured that out Zerot when my friend came to help. Such a stupid mistake. Thank you.
Answer by JRule4 · Oct 04, 2012 at 05:08 PM
It looks like you're Loading database in AddWeapon(), changing it and flagging it as Dirty, but not actually saving it out. Next time you call AddWeapon() again you just re-load the original version.
Try: AssetDatabase.CreateAsset(database, AssetDatabase.GetAssetPath(database); This will save over your database with the new one. You can call this instead of EditorUtility.SetDirty().
Or: AssetDatabase.SaveAssets() Call this after EditorUtility.SetDirty() to save everything that is dirty.
I did some tests and I like this method you mentioned more, keeps my data safe from crashes and moving assets from project to project. Is there any real difference from SetDirty() and CreateAsset() if you just SaveAssets() right after SetDirty()?
The main difference is that SetDirty() + SaveAssets() will save everything that is dirty, whereas using CreateAsset() will just save that one asset.
Thanks for the info but it seems like CreateAsset() will not override and already existing asset. :(
Your answer
Follow this Question
Related Questions
Auto removing entries form a scriptableobject list when asset is deleted. 0 Answers
A node in a childnode? 1 Answer
Load ScriptableObject / asset file and save as object to list 1 Answer
[Solved]Why doesn't my ScriptableObject based asset save using a custom inspector ? 1 Answer
How to compare a string in a list with a gameobject.name from another list of gameobjects 1 Answer