0

In Unity am creating an item system using the base class:

[CreateAssetMenu]
class ItemBase : ScriptableObject(){
    public string ItemName;
    public Sprite ItemSprite;

    void Spawn() {
        //Spawn Item Using The Sprite
    }
}

and then I am using the CreateAssetMenu to right click in my project folder for each item I want to add to the game and then assign their values in the editor.

When i drag my object from the editor onto a game object, everything works fine.

The issue im having is that I cannot figure out how to actually instantiate these at runtime from a script.

When I try to reference it like a class, the class is not found, when I add a script that mirrors the created item, the properties set by the editor are null upon instantiation.

Ideally what id like to do is something like:

  1. Right click and create new ItemBase called FishingRod from editor

  2. Assign name and sprite in editor

  3. \\Instantiate From Script FishingRod rod = ScriptableObject.CreateInstance(typeof(FishingRod)); // Properties should be the properties set by editor FishingRod.Spawn(); // Inserts Item Into Game

But when I instantiate the class, its properties are null;

 rod.ItemSprite //is null
 rod.ItemName //is null
2
  • I don't fully understand your use-case ... why do you need to instantiate ScriptableObjects on runtime? Usually you rather use them to pre-define a set of assets like configuration containers and don't create them on runtime Commented Jun 8, 2020 at 13:23
  • I have a world generated at runtime with certain water tile, when a user interacts with the water tile it runs a method called Fish(); and in the Fish method id like to spawn in a fishing rod sprite for a few seconds before despawning after the method runs. Im new to unity so perhaps im going about item spawning the wrong way, but this seemed to be the most intuitive way. @derHugo Commented Jun 8, 2020 at 13:26

1 Answer 1

1

From your use case description it sounds like you shouldn't need to create instances of the ScriptableObject on runtime. You rather want to reference and use the ones you already created.

So what you should do is

  1. (As you already did) create a new ItemBase instance via the Inspector's Asset create menu (Create -> ItemBase)
  2. (As you already did) fill this "container" with your data (name and sprite)
  3. Now in the file that want's to use this asset reference it via a field in the Inspector:

    // In the Inspector go to according GameObject
    // and drag the ScriptableObject you created into this slot
    [SerilaizeField] private ItemBase fishingRod;
    
  4. And then you simply use the values and methods of this instance via

    fishingRod.Spawn();
    

So if you want to switch between different items you would e.g. have a kind of controller script like

[SerilaizeField] private ItemBase fishingRod;
[SerilaizeField] private ItemBase hammer;
[SerilaizeField] private ItemBase umbrella;

Then you could switch between them like e.g.

private ItemBase _activeItem;

public void SelectFishingRod()
{
    _activeItem = fishingRod;
}

public void SelectHammer()
{
    _activeItem = hammer;
}

public void SelectUmbrella()
{
    _activeItem = umbrella;
}

and then e.g. do

public void UseActiveTool()
{
    _activeItem.Spawn();
}
Sign up to request clarification or add additional context in comments.

4 Comments

I see what youre saying, i guess im just not understanding how unity goes about things. In my particular use case, the player object has an ActiveItem component which refers to an instance of ItemBase, so in this case, its fishingRod, but it could also be any other ItemBase. Thats why i cant use the Inspector to assign the fishingRod in step 3. Ideally id be able to switch the active item from code, depending on what is being done at that moment. Any ideas? Thank you very much!
Well you can perfectly do that. Anyway at some point you need to reference them all in order to be able to switch between them on runtime. Added an example at the bottom of what I mean
Okay. Thank you!
I think it'll work, to abstract it a bit more, ill use a dict to store all the players items and their names that way i dont have to have a method for equipping each item. This really set me in the right direction. Thank you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.