- Home /
ScriptableObject instances modifying their original object
I am using ScriptableObjects as a template for storable items in my project. As I tried adding a shelf life property to them, I've noticed that when that value changes at runtime, the original object from the Resources folder has it altered as well.
How the item instances are created:
public void AddStorageItem (string itemName, int amount)
{
int pos = CheckStorageForItem(itemName);
if (pos != -1)
{
GlobalVariables.storage[pos].stackSize += amount;
}
else
{
AttachedItem newItem = ScriptableObject.CreateInstance<AttachedItem>();
if (itemName.Contains("ingr_"))
{
newItem.item = Resources.Load<StorableItem>("Ingredients/" + itemName);
newItem.stackSize = amount;
newItem.item.itemName = AlchemixTextEN.ingrNames[newItem.item.namedescRef];
GlobalVariables.storage.Add(newItem);
}
if (itemName.Contains("base_"))
{
newItem.item = ScriptableObject.CreateInstance<BrewingBase>();
newItem.item = Resources.Load<StorableItem>("Bases/" + itemName);
newItem.stackSize = amount;
newItem.item.itemName = AlchemixTextEN.baseNames[newItem.item.namedescRef];
GlobalVariables.storage.Add(newItem);
}
}
}
The item itself:
public abstract class StorableItem : ScriptableObject {
public int namedescRef;
public int value;
public Sprite icon;
public int shelfLife;
[System.NonSerialized]
public string itemName;
}
Every in-game minute I subtract 1 from an item's shelfLife:
foreach (AttachedItem item in GlobalVariables.storage.ToList())
{
if (item.item.shelfLife > 0) item.item.shelfLife -= 1;
else
{
if (item.item.shelfLife != -1)
{
GameObject.FindGameObjectWithTag("Canvas").GetComponent<UIManager>().DisplayMessage(null, item.stackSize.ToString() + " " + "units of" + " " + item.item.itemName + " " + "have spoiled!");
GlobalVariables.storage.Remove(item);
}
}
}
Is there a way to prevent the instances from changing the original object or am I better off just using MonoBehaviour for it? Thank you in advance.
Answer by jkpenner · Apr 24, 2020 at 04:36 AM
Think of a ScriptableObject file as a Prefab. Currently it's like you are editing the prefab directly. You'll need to make an instance of the ScriptableObject (similarly to GameObject Prefabs).
var instance = ScriptableObject.Instantiate(loadedAsset);
Thank you very much. Added an Instantiate over ScriptableObject.CreateInstance() and it works perfectly.