- Home /
Problem is not reproducible or outdated
Add every ScriptableObject to a dictionary?
Hi. I am trying to make an item system. I got the inventory down. And i am making a way to get any item using a variable attached to all ScriptableObjects called ID. And i want to be able to find the ScriptableObject that has the ID. And the best way to do it that i found was to use a Dictionary. Here's my ScriptableObject script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu]
public class Items : ScriptableObject {
public Sprite itemSprite;
public string itemName;
public int itemId;
}
But i cannot add the item to a Dictionary inside the ScriptableObject class. So. Any idea on how to do this? The dictionary i am trying to add the item to takes an Int and a String. The int is the ID. And the string is the name
What's the problem with adding a string and an int to a dictionary within a scrip$$anonymous$$ble object? Please provide more code. :) Where is your dictionary set up and how are you trying to add to it?
Answer by RobAnthem · Feb 12, 2017 at 06:04 PM
I wouldn't use a dictionary, as it isn't much faster than a simple
public List<Item> ItemsList;
public Item GetItem(int ID)
{
return ItemsList.Find(item => item.ID == ID);
}
Now if your problem is adding the objects, then you need to make sure you are creating instances, and if you are doing so in the editor, you will need a custom editor window or inspector to create them. You can code up an inspector for the ItemDatabase class you make, then have inside your inspector a way to create and save the assets.
Like this
public int IDs;
public void CreateNew()
{
Item tempItem;
AssetDatabase.CreateAsset(tempItem = CreateInstance<Item>(), "Assets/Resources/Items/" + "Item_" + IDs++.ToString() + ".asset");
ItemsList.Add(tempItem);
}
or
public int IDs;
public void Init()
{
AssetDatabase.CreateAsset(CreateInstance<ItemDatabase>(), "Assets/Resources/" + "ItemDatabase" + ".asset");
}
public void AddNew()
{
AssetDatabase.AddObjectToAsset(CreateInstance<Item>(), "Assets/Resources/ + "ItemDatabase" + ".asset");
}
After the object exists, in your OnGUI of your custom inspector you can easily have an expanding list by saying.
void OnGUI()
{
ItemDatabase Items = target as ItemDatabase;
EditorGUILayout.BeginVertical();
for (int i = 0; i < Items .ItemsList.Count; i++)
{
if (Items .ItemsList[i] != null)
{
Items .ItemsList[i] = (Item)EditorGUILayout.ObjectField("Item", Items .ItemsList[i], typeof(Item), false);
}
}
if (GUILayout.Button("Add New")
{
Items.AddNew();
}
EditorGUILayout.EndVertical();
}
I'm still confused. Is there a more simple way of doing that?
A dictionary is $$anonymous$$UCH $$anonymous$$UCH faster than searching all elements in a list. A dictionary search is O(1) and a list search is O(N). This means that if your list contains 10000000 entities, it will have to check every single element in the worst case. Still, it is not likely that he is going to have thousands of elements anyway.
Follow this Question
Related Questions
How to use ScriptableObject for Inventory System 0 Answers
Serializing Dictionary: Data lost between sessions 0 Answers
[Solved]How to serialize Dictionary with Unity Serialization System 6 Answers
Dictionaries don't serialize within scriptable objects 0 Answers
please help me, Scriptable object's variable serialization issue 1 Answer