Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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 /
This post has been wikified, any user with enough reputation can edit it.
avatar image
0
Question by cookiepuss · Sep 01, 2012 at 11:18 PM · c#guiscrollviewdictionary

Putting dictionary items in GUI ScrollView

I want to get items from my dictionary and put them in a scrollable box. The code I have below works fine so far. How do I access the objects related to each field in the scroll box? Is there a better method to do this with dictionaries?

public class Menu : MonoBehaviour {

     public GameObject player;
     public Vector2 position;
     public Vector2 size;
     private Vector2 OriginalPosition;
     public Vector2 scrollPosition = Vector2.zero;
     
     // Use this for initialization
     void Start () { 
         player.GetComponent<PlayerStatus>();
         OriginalPosition = position;
         
     
     }
     
 
     void OnGUI()
     {
         position = OriginalPosition;
         
         
         scrollPosition = GUI.BeginScrollView(new Rect(10, 300, 100, 100), scrollPosition, new Rect(0, 0, 220, 200));
         foreach(KeyValuePair<Items,int> pair in Inventory.Potions){
         position.y += 30;    
         GUI.Box(new Rect(0, position.y, 100, 20), pair.Key.itemName + " : " + pair.Value);
         }
         GUI.EndScrollView();
     
     }
 }
Comment
Add comment · Show 5
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 Bunny83 · Sep 02, 2012 at 01:45 AM 0
Share

I have no idea what you mean. You already access the objects in the dictionary!?!

Btw, for such things GUILayout is really nice since it automatically calculates the positions / sizes of all GUI elements.

Also why do you use a dictionary here? what does the int value mean? the count? It would be enough to give the item class a count field. When i really wanted to use a dictionary i would do it the other way round and use an int (the item ID) as key. Either way a Dictionary prevents you from storing the same thing several times. If that's what you want it's ok.

Still i'm not sure what you're asking here ;) Can you explain it a bit more in detail what's your problem or what you want to do?

avatar image cookiepuss · Sep 02, 2012 at 05:15 AM 0
Share

I'm using a dictionary as an inventory. $$anonymous$$ey corresponds to an item object. value corresponds to the number of each item. Adding extra values for each key is not a problem for me, I've fixed that issue by overriding gethashcode and equals. I'd like to know how to retrieve each object and value from the dictionary after the adding them to the scrollview. for example: in my inventory.potions dictionary. I have (health potion : 2) and (mana potion : 3). They show up correctly in the scroll box. I'd like to know if there is a reference to each key in the scroll box. If so, how do I retrieve it? If my method doesn't provide a reference, how can get a reference onto the scroll box (or somewhere accessible) to my health potions and mana potions from my dictionary?

As far as count field goes. Is that better than my dictionary method?

avatar image Bunny83 · Sep 02, 2012 at 01:19 PM 0
Share

Well, it depends on how you want it. A lot of games allow multiple "stacks" or the same type. That's not possible with a dictionary. If you don't need / want this, it's ok that way.

I'll write an answer ;)

avatar image cookiepuss · Sep 02, 2012 at 03:51 PM 0
Share

can you explain what you mean by multiple stacks? like an example? $$anonymous$$y class "items" has several subclasses: potions, armor, weapons etc. are you saying I won't be able to add any of the subclasses together into one dictionary?

avatar image Bunny83 · Sep 02, 2012 at 05:11 PM 0
Share

No, no that should be no problem as long as your Item has a unique Hash value. I just take $$anonymous$$ineCraft as example. You can have a "stack" of wood in your inventory. One stack is limited to 64 items so if you collect more wood it creates a new stack of the same type. When you want unlimited stacking of items it's ok.

Next example of $$anonymous$$inecraft ;) Weapons have unique properties especially the durability / health. That's why it's a non-stackable item, so you have to store multiple seperate items when you have more than one. In your case it all depends on your Hash function.

1 Reply

· Add your reply
  • Sort: 
avatar image
1

Answer by Bunny83 · Sep 02, 2012 at 01:39 PM

It seems you have trouble to wrap your head around the immediate GUI system in Unity ;)

Your code in OnGUI does not "create" a GUI, it just "displays" it. OnGUI is called every frame like Update. Well it's actually called multiple times per frame to process other events. The Event class is strongly connected to OnGUI. All the GUI function use the event class to determine the current event and perform the proper action.

Are you sure your item class is called "Items"? I used "Item" in my example below.

Here's an example:

 void OnGUI()
 {
     GUILayout.BeginArea(new Rect(10, 300, 100, 100));
     scrollPosition = GUILayout.BeginScrollView(scrollPosition);
     foreach(KeyValuePair<Item,int> pair in Potions)
     {
         GUILayout.BeginHorizontal("box", GUILayout.Height(20)); // style the group like a box
           GUILayout.Label(pair.Key.itemName + " : " + pair.Value);
           if (pair.Value > 0)
           {
               if (GUILayout.Button("Reduce", GUILayout.Width(70)))
               {
                   Potions[pair.Key] = Potions[pair.Key] - 1;
               }
           }
         GUILayout.EndHorizontal();
     }
     GUILayout.EndScrollView();
     GUILayout.EndArea();
 }


This will display a button behind each item in the list. When you press the button, it will decrement the count of that element.

Comment
Add comment · Show 3 · 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 cookiepuss · Sep 02, 2012 at 04:26 PM 0
Share

this sort of works but I get an out of sync exception. You can't edit items in a dictionary while iterating through it.

avatar image Bunny83 · Sep 02, 2012 at 05:02 PM 0
Share

Sure, that's mainly an issue of the foreach loop. That's also a reason why a list would be better ;) You can modify the elements in the dictionary, but you can't remove or add them inside the foreach loop. Another problem is that $$anonymous$$eyValuePair is a struct, so the Value also can't be changed inside the forloop.

There are workarounds for deleting objects. For example storing the element you want to delete and remove it later:

 Item removeThis = null;
 foreach($$anonymous$$eyValuePair<Item,int> pair in Potions)
 {
     // [...]
           if (GUILayout.Button("Remove", GUILayout.Width(70)))
           {
               removeThis = pair.$$anonymous$$ey;
           }
     // [...]
 }
 if (removeThis != null)
 {
     Potions.Remove(removeThis);
     removeThis = null;
 }
avatar image cookiepuss · Sep 02, 2012 at 05:10 PM 0
Share

lol man that just seems like too much of a hassle. I think I'm just going to use your method and make a count field for my items class. thanks for your help!

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

8 People are following this question.

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

Related Questions

Putting Dictionary/List using foreach as buttons in a scroll view? 3 Answers

Create a Button Scrollview 0 Answers

How to hide GUI and chilren? 0 Answers

Multiple Cars not working 1 Answer

UGUI ScrollRect automatic scroll? (Chat) 1 Answer


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