Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by TharosTheDragon · Oct 14, 2017 at 11:51 PM · prefabsdictionary

What's the best way to use prefabs as Dictionary values?

This is a bit of a complicated question. I have a set of items with unique behavior, and my classes refer to them using the values in an enum called TileItemType. I want to associate them with prefabs using a dictionary like this Dictionary<TileItemType, GameObject> dict;. To set those values I'm thinking I'll need to use ISerializationCallbackReceiver and create a custom property drawer. But before I get too deep into it I'm wondering if maybe there's a better way to go about all this.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by PizzaPie · Oct 15, 2017 at 11:47 AM

If your prefabs match the number of associated enum values that s too complicated for no reason, as the match is 1-1 just directly refer to the prefabs. If you have more than one prefabs associated with a single TileItemType then the dictionary should be

 Dictionary<TileItemType,List<GameObject()> dict;

and one way to serialize/ create custom editor would be this. On the other hand you could create a class

 [Serializable]
 public class ItemTileData{
       public TileItemType type;
       puclic GameObject prefab;
 }

To make the association and use a "database class" to pick them.

 public class TileDataBase /* : ScriptableObject // the easiest way to serialize it */
 {
        public list<ItemTileData> tileList;
 }

But that wouldn't be that performance efficient. And lastly you could just directly create a "database" class

 public class TileDataBase : ScriptbleObject
 {
        List<GameObject> myTypeAPrefabs;
        List<GameObect> myTypeBPrefabs;
        //and so on for each type
 
       public GameObject GetPrefabOfTileType (TileItemType type){
                    switch(type){
                              case TileItemType.TypeA :
                                        return (someObject from myTypeAPrefabs);
                   //...}
 }

but with this it is a pain to add more TileItemTypes as you need to add a new List and new case to switch but it is quite performance efficient regarding previous solutions (in the first the Serializasion/Deserializasion of the dictionary is quite heavy but look ups are fast/ second one look ups are quite slow) Cheers.

Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image TharosTheDragon · Oct 15, 2017 at 06:15 PM 0
Share

Yes, the match is just 1-1. I seem to be missing something here. How do you directly refer to prefabs? The prefabs are just in my assets folder. I thought they didn't even exist in the compiled application unless I set them as values in the inspector.

I'm now guessing you mean that my public TileItemType fields could just be GameObject fields ins$$anonymous$$d. This was the route I was going at first. However, once I start instantiating the game objects I won't be able to compare them effectively, because two instances of the same prefab don't equal each other. Using an enum to uniquely identify the "types" of objects seems effective and lightweight, though it certainly does complicate things when it comes to custom property drawers and such. I could just put an enum as a property in a script on each prefab, and now that I think of it that may be the best solution. However, this whole project is mostly for practice and now that I'm going down this route I kind of want to see if I can get custom property drawers to work.

avatar image TharosTheDragon · Oct 15, 2017 at 07:22 PM 0
Share

What do you mean by "But that wouldn't be that performance efficient"? In the examples I've seen, dictionaries are serialized using two separate lists: one for keys and one for values. It makes more sense to me to just use one list of key/value pairs. Why would that be worse for performance?

avatar image fafase TharosTheDragon · Oct 16, 2017 at 08:26 AM 1
Share

The dictionary can find an item with O(1) using hash value. Your two lists of $$anonymous$$ey/Value, you 'd have to iterate the keys to find the match, that is O(n). So dictionary will find right away, your double list system will have worst case as the size of the collection.

avatar image TharosTheDragon fafase · Oct 16, 2017 at 02:49 PM 0
Share

You misunderstand. I'm not talking about the performance of dictionaries versus lists. I'm talking about, specifically in a "serialized dictionary," the performance of two lists versus one list.

Show more comments
avatar image
1

Answer by fafase · Oct 15, 2017 at 06:48 PM

First, you create a script that you attach to the prefabs. This script is used to define the type of your prefabs. For each of the prefab, attach and set it to the needed value.

 public class PrefabType:MonoBehaviour{
      [SerializeField] private TileItemType tileType;
      public TileItemType TileType{ get { return this.tileType; } }
 }

Second, you drag all your prefabs in a collection and create a dictionary for storage. Notice the type of the collection, it is PrefabType as the above class.

 [SerializeField]private PrefabType [] prefabs = null;
 IDictionary<TileItemType, GameObject> dict = null;

Then in the start, you populate the dictionary and get rid of whatever is not needed.

 void Start(){
     this.dict = new Dictionary<TileItemType, GameObject>();
     foreach(PrefabType pt in this.prefabs){
           this.dict.Add(pt.TileType, pt.gameObject);
           Destroy(pt); 
     }
 }

Finally, you have a method for access.

 public GameObject GetPrefabByTileType(TileType tileType){
      GameObject result = null;
      this.dict.TryGetValue(tileType, out result);
      return result;
 }

if all keys are there then you can just do:

 public GameObject GetPrefabByTileType(TileType tileType){
      return this.dict[tileType];
 }








Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

72 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Dictionary Keys to Stack Enemy Types 1 Answer

GameObject.FindGameObjectsWithTag() to find Prefabs which are not in the scene 1 Answer

Whats the best way to populate a Dictionary with multiple Prefabs? 0 Answers

Prefab, referencing them, using their methods:bug or intentional? 1 Answer

file sizes of prefabs 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges