Dictionary in inspector
Asked Answered
S

7

0

We all know Dictionaries do not appear in the Editor. What would be a way to get them to appear?

Suppose I have:

[Serializable]
public class MySerializableObject
{
   public float Name;
   public float Description;
}

public Dictionary<string, MySerializableObject> MyDictionary;

Strings and Serializable objects both appear in the editor. How would I get MyDictionary (and all Dictionaries really) to display with their default inspectors for Key types and Value types?

Would a PropertyDrawer be the solution?

Any help / examples / solutions would be appreciated.

Scifi answered 19/10, 2023 at 18:39 Comment(0)
A
0

It’s a PITA but you’d have to do the rendering yourself. Also note that Unity will not serialize/save/load dictionary for you. For this reason, a lot of people store things in Lists and then build a Dictionary at Start to make lookups faster.

Autoplasty answered 30/9, 2023 at 20:1 Comment(3)

What does PITA mean?

Scifi

Sorry. Pain in the...butt.

Autoplasty

I'd suggest building the dictionary using the ISerializationCallbackReceiver interface, not on Start.

Warrantor
B
0

You could just do a hack, like you do for anything serious in Unity.

Expose a normal array.

[Serializable]
public struct NamedImage {
    public string name;
    public Texture2D image;
}

public NamedImage[] pictures;

Then at the Start() or Awake(), or whenever your mind is flipped for it. Put the array manually in a Hashmap, Dictionary or whatever. It looks alright in the Inspector.

If it looks like a Hashtable, walks like a Hashtable, acts like a Hashtable, guess what, its a Hashtable.

Blub answered 19/10, 2023 at 18:41 Comment(5)

Genius! Thank you.

Deerhound

While this is a nice workaround it DOES not act like a Hashtable. This implementaton allows any number of images to share the same name. You should at least test if the resukting Dictonary has the same number of members as the source array.

Mohr

"If it looks like a Hashtable, walks like a Hashtable, acts like a Hashtable, guess what, its a Hashtable." yes but it doesn't act like one and completely defeats the point of having one, this is a junk answer

Unassailable

Indeed. And I'd also point out that unless your objective is to end up with a mess, Unity is not all about cutting corners. That's a recipe for pain, regardless of whether you're in low level c++ or nice friendly unity. Not good advice.

Haihaida

It's always funny to watch the Unity community come up with new hacks. And the developers of the engine cannot make elementary functionality. Ordinary Unity team dev: "Make SerializeField for Dictionary? Why?" "Making the community suffer? This is what we need!"

Disfavor
M
0

Use ISerializationCallbackReceiver to let Unity serialize the keys and values of your dictionary. From there, you can access both lists and create your custom editor.

Motherofpearl answered 19/10, 2023 at 19:8 Comment(2)

can you show an example?

Blub

You have an example on how to properly serialize a dictionary in the link [I provided before][1]. That will render the dictionary as two different lists, so it will be actually visible. For a editor/layout implementation, I let you investigate on your own :) (if you're starting editor scripting, this tutorial is a [really good one][2]) [1]: http://docs.unity3d.com/ScriptReference/ISerializationCallbackReceiver.OnBeforeSerialize.html [2]: http://catlikecoding.com/unity/tutorials/editor/custom-data/

Motherofpearl
S
0

I was just facing this problem. I tried some custom serialization, to find that it gives me trouble when switching to the HTML5 platform. I am not really savvy on serialization and its shenanigans, so I needed to implement a different solution.

In the end, my solution is a variation on the hack @Blub described:

  1. Using platform-dependent compilation, I declare a serialized key-value struct for the dictionary I want to fill, and an array of this struct. This struct, array, and the function to use them, will only exist for the editor.

  2. Create a scriptable object to contain the dictionary. This object I will be using in the game.

  3. Run an editor function that stores the data from the array into the dictionary in the scriptableObject. Since it is an asset, you will need to use the AssetDatabase class to 1) set it dirty before modifying it; 2) save the AssetDatabase, 3) reload the assetDatabase.

The result is a visible list of items available in the editor, a plain old dictionary that will leave no extra trash and require no extra processing in the application, and an editor function that saves the first into the second.

Of couse, as some have mentioned, nothing stops you from putting duplicated key values into the array, so you need to be careful, or have the “Dumping” function check for errors like this. Other than that, I think it is a good compromise. This process of using editor-only variables and functions to process and store data into scriptableObjects has been pretty reliable to me, and I have been using it quite frequently with no problems.

Seignior answered 6/6, 2023 at 2:41 Comment(0)
A
0

You can used Odin Inspector, it showing dictionary in inspector =>

[DictionaryDrawerSettings]
[ShowInInspector]
public Dictionary craftMaterialsData = new Dictionary();
Alrick answered 19/10, 2023 at 18:42 Comment(1)

Looks very useful, but $55 is very expensive if all you want to do is expose Dictionaries in the inspector. Better to use Helical's fix and save the money.

Nottingham
L
0

You can build your own custom inspector as well.

Lorenzalorenzana answered 14/1, 2023 at 17:9 Comment(0)
T
0

There’s a free asset currently on the Unity Store that solves this issue. I had to restart my Unity Client and Visual Studio to make it work, but it seems to work well.
—Unity Asset Store Link—

Trossachs answered 18/3 at 9:28 Comment(1)

thank you, that really helps me

Davison

© 2022 - 2024 — McMap. All rights reserved.