Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

[Resolved] Dictionary in Scriptable Object using Ryan Hipple Method

Discussion in 'Scripting' started by Deleted User, Mar 27, 2018.

  1. Deleted User

    Deleted User

    Guest

    What I'm trying to do is create a Scriptable Object script for Dictionaries for the most part I got it working except for one part.

    I can't call to get a value from dictionary with a key

    Here is all my code:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public abstract class RuntimeTable<TKey, TValue> : ScriptableObject
    6. {
    7.     public Dictionary<TKey, TValue> KeyPair = new Dictionary<TKey, TValue>();
    8.  
    9.     public void Add(TKey key, TValue value)
    10.     {
    11.         if(!KeyPair.ContainsKey(key)){
    12.             KeyPair.Add(key, value);
    13.         }
    14.     }
    15.  
    16.     public void Remove(TKey key)
    17.     {
    18.         if(KeyPair.ContainsKey(key)){
    19.             KeyPair.Remove(key);
    20.         }
    21.     }
    22. }
    23.  
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. [CreateAssetMenu(fileName = "GeneralTable", menuName = "Data/Tables/General")]
    6. public class GeneralRuntimeTable : RuntimeTable<string, string>
    7. {}
    8.  
    Code (CSharp):
    1. public class MyScript : MonoBehaviour {
    2.  
    3.     public GeneralRuntimeTable myTable;
    4.  
    5.     void Start(){
    6.         string catName = myTable["name"];
    7.     }
    8. }
    I can't get myTable["name"] to work it keeps outputting an error

    Cannot apply indexing with [] to an expression of type 'GeneralRuntimeTable' [Assembly-CSharp, Assembly-CSharp-Editor]

    Only assignment, call, increment, decrement, and new object expressions can be used as a statement [Assembly-CSharp, Assembly-CSharp-Editor]


    If you haven't seen or understand Ryan Hipple's talk at Unite Austin 2017 then go watch it.

    https://github.com/roboryantron/Unite2017
     
    Last edited by a moderator: Mar 27, 2018
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,599
  3. Deleted User

    Deleted User

    Guest

    Do you have an example on how I would do this? I'm still very much a C# beginner.
     
  4. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Your code inherits from ScriptableObject, and not a dictionary.
    Inside the class is a dictionary.
     
  5. Deleted User

    Deleted User

    Guest

    It has to inherit from ScriptableObject. That's the the method works.
     
  6. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Sure, I get that that's your goal. What I was saying is that scriptable object doesn't have an indexer defined. So, you either have to use your methods, access the dictionary itself and use the indexer, or as mentioned implement an interface and complete it to do the same.
     
    Kurt-Dekker and Homicide like this.
  7. Deleted User

    Deleted User

    Guest

    Perfect! Thanks for the help!

    Working Code:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public interface IRuntimeTable<TKey, TValue>{
    6.     TValue this[TKey key]{
    7.         get;
    8.         set;
    9.     }
    10. }
    11.  
    12. public abstract class RuntimeTable<TKey, TValue> : ScriptableObject, IRuntimeTable<TKey, TValue>
    13. {
    14.     public Dictionary<TKey, TValue> KeyPair = new Dictionary<TKey, TValue>();
    15.  
    16.     public void Add(TKey key, TValue value)
    17.     {
    18.         if(!KeyPair.ContainsKey(key)){
    19.             KeyPair.Add(key, value);
    20.         }
    21.     }
    22.  
    23.     public void Remove(TKey key)
    24.     {
    25.         if(KeyPair.ContainsKey(key)){
    26.             KeyPair.Remove(key);
    27.         }
    28.     }
    29.  
    30.     public TValue this[TKey key]{
    31.         get{
    32.             return KeyPair[key];
    33.         }
    34.         set{
    35.             KeyPair[key] = value;
    36.         }
    37.     }
    38. }
     
    Last edited by a moderator: Mar 28, 2018
    Kurt-Dekker likes this.
  8. Deleted User

    Deleted User

    Guest

    Getting new error now:


    ArgumentNullException: Value cannot be null.
    Parameter name: key
    System.Collections.Generic.Dictionary`2[TKey,TValue].FindEntry (TKey key) (at <e1a80661d61443feb3dbdaac88eeb776>:0)
    System.Collections.Generic.Dictionary`2[TKey,TValue].get_Item (TKey key) (at <e1a80661d61443feb3dbdaac88eeb776>:0)
    RuntimeTable`2[TKey,TValue].get_Item (TKey key) (at Assets/BuilderScripts/Tables/RuntimeTable.cs:32)
     
  9. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    And the code creating the error is? Passing 'null' as a key?
     
  10. Deleted User

    Deleted User

    Guest

    I derped .....I had issue with declaring variables.

    It works perfectly now. Thanks again methos5k you've been a big help!

    This thread is officially resolved
     
  11. Palanysamy

    Palanysamy

    Joined:
    Dec 25, 2012
    Posts:
    12
    Hi Ryan, could you please share the script accessing the Table? "MyTable" with the cat string. Thanks a lot!