How to instantiate a new & unique ScriptableObject during run-time

Brian with the Instance SO, you said the cast is inferred through it’s parameter, so the string of the name I can reduce it down to something like this?

ScriptableObject.CreateInstance("StatsEquipableItem");
// Set up all configurations AFTER creating instance...

How do I get ahold of this SO instance? I should still be assigning it to the StatsEquipableItem parameter, yes? →

StatsEquipableItem SetUpEquipableModifierItem(StatsEquipableItem item)
{
    item = ScriptableObject.CreateInstance("StatsEquipableItem");
    // this doesn't work since it requires a cast to StatsEquipableItem
    // Set up all configurations AFTER creating instance...
}

I noticed that when I instantiate the item that it doesn’t spawn with all the pre-defined configurations. Is it because I’m assigning the item to the new scriptableobject, therefore it’s wiping all the pre-configured data?

You need the actual ScriptableObject you’re creating an instance of, just like if you were Instantiating a GameObject.
Here’s an example:

[SerializeField] InventoryItem itemToInstantiate=null; //Set this in the inspector

InventoryItem CreateInstance()
{
     InventoryItem item = CreateInstance(itemToInstantiate);
     return item;
}

At this point, while our handle to the item is an InventoryItem, if the item you put in itemToInstantiate is actually a StatsEquipableItem (a child class of InventoryItem) then it will be instantiated as a StatsEquipableItem.
You can then cast that resulting item to a StatsEquipableItem to set random stats on it…

Now in your case, you’re going to want to have an array of random InventoryItems to choose from as base items

[SerializeField] InventoryItem[] itemsToInstantiate;

You’ll only want to put random stats on an item that can take random stats, in this case StatsEquipableItem. If you’re only going to drop StatsEquipableItems, then you can change the type to StatsEquipableItem

[SerializeField] StatsEquipableItem[] itemsToInstantiate;

But you probably also want to drop other things like potions and such, we we’ll test to see if the item is a StatsEquipableItem

[SerializeField] InventoryItem[] itemsToInstantiate;

public InventoryItem CreateInstance()
{
    InventoryItem template = itemsToInstanitate[Random.Range(0,itemsToInstantiate.Length)];
    InventoryItem item = ScriptableObject.CreateInstance(template);
    //At this point, you have an instance of an item, let's modify it.
    item.SetDisplayName(randomName); //I'll leave choosing a name to you
    //Keep setting parameters on all InventoryItem fields you wnat to choose
    //Then test to see if it's a StatsEquipableItem
    if(item is StatsEqupableItem statsEquipableItem)
    {
         //At this point, statsEquipableItem is a pointer to the instantiated item
         //Within this block, you can use that pointer to modify StatsEquipableItem specfic fields.
         SetUpRandomStats(statsEquipableItem); //Make this method to add stats to the item.
    }
    return item;
}

We’re almost at the finished line

I compared my new changes I made late last night and it’s almost identical to this post you made brian. The only difference and lack of understanding still on my part is, how you’re able to slot the InventoryItem ‘itemToInstantiate’ into the ScriptableObject.CreateInstance parameter and have that work?

For me my Visual Studio error tells me I can only CreateInstance a type or string… ScriptableObject.CreateInstance<Type>() or
ScriptableObject.CreateInstance("string of SO class name")

So that means this is my two options based upon my limited research and hours of testing:

public InventoryItem CreateInstance()
{
    InventoryItem item = ScriptableObject.CreateInstance<InventoryItem>();
    return item;
   // returns a brand new blank SO...
}

or

public InventoryItem CreateInstance()
{
    InventoryItem item = ScriptableObject.CreateInstance("InventoryItem") as InventoryItem;
    return item;
    // returns a brand new blank SO...
}

But as you’d know, both of these methods never create an instance of the item we wish for it to instantiate.

If I try doing the method by passing the InventoryItem itself as the parameter, it will always ask me for a string reference of the class name. Once I figure that little part out then we’re pretty much set… gonna do a bit of research again, so far what I’ve come up with however, is that it appears I need to pass a string or cast it to a scriptableobject by type.

But aforementioned, this is the last hurdle. Everything else is set up and ready to go

This is what happens when I write code from memory (either at work or in my workshop downstairs while I’m lasering coasters) instead of actually looking at my own actual code.

Replace CreateInstance with Instantiate and you’ll be right as rain.

1 Like

Works wonderfully. I actually tried Instantiate a couple days ago, but I thought after doing my research it was the CreateInstance() was what I needed.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms