Search Unity

Sprite References Changed in Version Updates?

Discussion in 'Scripting' started by spryx, Sep 27, 2015.

  1. spryx

    spryx

    Joined:
    Jul 23, 2013
    Posts:
    557
    Hi, I have a somewhat odd problem. Every time I update Unity, it seems that my sprite references change. I am using a Serialized dictionary that is matching a sprite and a gameobject as a key/value pair. An asset I am using only supports sprites, so I need to match a particular sprite to a gameobject. In this instance, I am matching sprites of light sources to a light halo.

    This script maps sprites to corresponding gameobjects:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using ProD;
    5.  
    6. public class AddToSprite : MonoBehaviour {
    7.  
    8.     public SpriteDict sprPrfabDict;
    9.  
    10.     void Start() {
    11.         GameObject pFab;
    12.  
    13.         if (sprPrfabDict.TryGetValue(this.GetComponent<SpriteRenderer>().sprite, out pFab)) {
    14.             Instantiate(pFab, this.transform.position, Quaternion.identity);
    15.         }
    16.  
    17.         Destroy(this);
    18.     }
    19. }
    20.  
    I am using a custom editor to add key/value pairs to the dictionary. I can confirm that this code works, but Unity must change the sprite references in version upgrades. In a version update, the sprites are not matched, and I am able to add the same key/value pair again. This script constitutes my editor:
    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3. using System.Collections.Generic;
    4.  
    5. [CustomEditor(typeof(AddToSprite))]
    6. public class AddToSpriteEditor : Editor {
    7.  
    8.     private Sprite nkSprite;
    9.     private GameObject nkObj;
    10.     private GUILayoutOption[] max_120 = new GUILayoutOption[] { GUILayout.MaxWidth(120f) };
    11.     private GUILayoutOption[] max_30 = new GUILayoutOption[] { GUILayout.MaxWidth(30f) };
    12.  
    13.     public override void OnInspectorGUI() {
    14.         AddToSprite myA2S = (AddToSprite)target;
    15.  
    16.         GUI.color = Color.red;
    17.         GUI.skin.button.fixedWidth = 0f;
    18.         if (GUILayout.Button("Clear Dictionary")) {
    19.             if (EditorUtility.DisplayDialog("Continue?", "Are you sure?\nThis action cannot be undone!", "Yes", "Cancel")) {
    20.                 myA2S.sprPrfabDict.Clear();
    21.                 EditorUtility.SetDirty(myA2S);
    22.             }
    23.         }
    24.  
    25.         GUI.color = Color.cyan;
    26.         if (GUILayout.Button("Set Dirty")) {
    27.             EditorUtility.SetDirty(myA2S);
    28.         }
    29.  
    30.         GUI.color = Color.white;
    31.  
    32.         GUI.skin.button.fixedWidth = 25f;
    33.  
    34.         if (myA2S.sprPrfabDict == null) {
    35.             //Init Dictionary
    36.             myA2S.sprPrfabDict = new SpriteDict();
    37.             EditorUtility.SetDirty(myA2S);
    38.         }
    39.  
    40.         foreach (KeyValuePair<Sprite, GameObject> kVal in myA2S.sprPrfabDict) {
    41.             GUILayout.BeginHorizontal();
    42.             if (GUILayout.Button("-")) {
    43.                 Debug.Log("Key removed: " + myA2S.sprPrfabDict.Remove(kVal.Key));
    44.                 EditorUtility.SetDirty(myA2S);
    45.                 break;
    46.             }
    47.             EditorGUILayout.LabelField(kVal.Key.name, max_120);
    48.             EditorGUILayout.LabelField("-+-", max_30);
    49.             EditorGUILayout.LabelField(kVal.Value.name, max_120);
    50.  
    51.             GUILayout.EndHorizontal();
    52.         }
    53.  
    54.  
    55.         GUILayout.BeginHorizontal();
    56.  
    57.         if (GUILayout.Button("+")) {
    58.             //Add the new kv pair
    59.             if ((nkSprite != null) && (nkObj != null)) {
    60.                 myA2S.sprPrfabDict.Add(nkSprite, nkObj);
    61.                 EditorUtility.SetDirty(myA2S);
    62.             }
    63.             else {
    64.                 Debug.LogError("Sprite and GameObject pair are invalid!");
    65.             }
    66.         }
    67.  
    68.         nkSprite = (Sprite)EditorGUILayout.ObjectField(nkSprite, typeof(Sprite), false, max_120);
    69.         EditorGUILayout.LabelField("-+-", max_30);
    70.         nkObj = (GameObject)EditorGUILayout.ObjectField(nkObj, typeof(GameObject), false, max_120);
    71.  
    72.         GUILayout.EndHorizontal();
    73.     }
    74. }
    75.  
    I am using a version of the dictionary that has been serialized:

    Code (CSharp):
    1. //Taken from http://forum.unity3d.com/threads/finally-a-serializable-dictionary-for-unity-extracted-from-system-collections-generic.335797/
    2. using System;
    3. using System.Linq;
    4. using System.Collections;
    5. using System.Collections.Generic;
    6. using System.Diagnostics;
    7. using UnityEngine;
    8.  
    9. [Serializable, DebuggerDisplay("Count = {Count}")]
    10. public class SerializableDictionary<TKey, TValue> : IDictionary<TKey, TValue> {
    11.     [SerializeField, HideInInspector]
    12.     int[] _Buckets;
    13.     [SerializeField, HideInInspector]
    14.     int[] _HashCodes;
    15.     [SerializeField, HideInInspector]
    16.     int[] _Next;
    17.     [SerializeField, HideInInspector]
    18.     int _Count;
    19.     [SerializeField, HideInInspector]
    20.     int _Version;
    21.     [SerializeField, HideInInspector]
    22.     int _FreeList;
    23.     [SerializeField, HideInInspector]
    24.     int _FreeCount;
    25.     [SerializeField, HideInInspector]
    26.     TKey[] _Keys;
    27.     [SerializeField, HideInInspector]
    28.     TValue[] _Values;
    29.  
    30.     readonly IEqualityComparer<TKey> _Comparer;
    31.  
    32.     // Mainly for debugging purposes - to get the key-value pairs display
    33.     public Dictionary<TKey, TValue> AsDictionary {
    34.         get { return new Dictionary<TKey, TValue>(this); }
    35.     }
    36.  
    37.     public int Count {
    38.         get { return _Count - _FreeCount; }
    39.     }
    40.  
    41.     public TValue this[TKey key, TValue defaultValue] {
    42.         get {
    43.             int index = FindIndex(key);
    44.             if (index >= 0)
    45.                 return _Values[index];
    46.             return defaultValue;
    47.         }
    48.     }
    49.  
    50.     public TValue this[TKey key] {
    51.         get {
    52.             int index = FindIndex(key);
    53.             if (index >= 0)
    54.                 return _Values[index];
    55.             throw new KeyNotFoundException(key.ToString());
    56.         }
    57.  
    58.         set { Insert(key, value, false); }
    59.     }
    60.  
    61.     public SerializableDictionary()
    62.         : this(0, null) {
    63.     }
    64.  
    65.     public SerializableDictionary(int capacity)
    66.         : this(capacity, null) {
    67.     }
    68.  
    69.     public SerializableDictionary(IEqualityComparer<TKey> comparer)
    70.         : this(0, comparer) {
    71.     }
    72.  
    73.     public SerializableDictionary(int capacity, IEqualityComparer<TKey> comparer) {
    74.         if (capacity < 0)
    75.             throw new ArgumentOutOfRangeException("capacity");
    76.  
    77.         Initialize(capacity);
    78.  
    79.         _Comparer = (comparer ?? EqualityComparer<TKey>.Default);
    80.     }
    81.  
    82.     public SerializableDictionary(IDictionary<TKey, TValue> dictionary)
    83.         : this(dictionary, null) {
    84.     }
    85.  
    86.     public SerializableDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)
    87.         : this((dictionary != null) ? dictionary.Count : 0, comparer) {
    88.         if (dictionary == null)
    89.             throw new ArgumentNullException("dictionary");
    90.  
    91.         foreach (KeyValuePair<TKey, TValue> current in dictionary)
    92.             Add(current.Key, current.Value);
    93.     }
    94.  
    95.     public bool ContainsValue(TValue value) {
    96.         if (value == null) {
    97.             for (int i = 0; i < _Count; i++) {
    98.                 if (_HashCodes[i] >= 0 && _Values[i] == null)
    99.                     return true;
    100.             }
    101.         }
    102.         else {
    103.             var defaultComparer = EqualityComparer<TValue>.Default;
    104.             for (int i = 0; i < _Count; i++) {
    105.                 if (_HashCodes[i] >= 0 && defaultComparer.Equals(_Values[i], value))
    106.                     return true;
    107.             }
    108.         }
    109.         return false;
    110.     }
    111.  
    112.     public bool ContainsKey(TKey key) {
    113.         return FindIndex(key) >= 0;
    114.     }
    115.  
    116.     public void Clear() {
    117.         if (_Count <= 0)
    118.             return;
    119.  
    120.         for (int i = 0; i < _Buckets.Length; i++)
    121.             _Buckets[i] = -1;
    122.  
    123.         Array.Clear(_Keys, 0, _Count);
    124.         Array.Clear(_Values, 0, _Count);
    125.         Array.Clear(_HashCodes, 0, _Count);
    126.         Array.Clear(_Next, 0, _Count);
    127.  
    128.         _FreeList = -1;
    129.         _Count = 0;
    130.         _FreeCount = 0;
    131.         _Version++;
    132.     }
    133.  
    134.     public void Add(TKey key, TValue value) {
    135.         Insert(key, value, true);
    136.     }
    137.  
    138.     private void Resize(int newSize, bool forceNewHashCodes) {
    139.         int[] bucketsCopy = new int[newSize];
    140.         for (int i = 0; i < bucketsCopy.Length; i++)
    141.             bucketsCopy[i] = -1;
    142.  
    143.         var keysCopy = new TKey[newSize];
    144.         var valuesCopy = new TValue[newSize];
    145.         var hashCodesCopy = new int[newSize];
    146.         var nextCopy = new int[newSize];
    147.  
    148.         Array.Copy(_Values, 0, valuesCopy, 0, _Count);
    149.         Array.Copy(_Keys, 0, keysCopy, 0, _Count);
    150.         Array.Copy(_HashCodes, 0, hashCodesCopy, 0, _Count);
    151.         Array.Copy(_Next, 0, nextCopy, 0, _Count);
    152.  
    153.         if (forceNewHashCodes) {
    154.             for (int i = 0; i < _Count; i++) {
    155.                 if (hashCodesCopy[i] != -1)
    156.                     hashCodesCopy[i] = (_Comparer.GetHashCode(keysCopy[i]) & 2147483647);
    157.             }
    158.         }
    159.  
    160.         for (int i = 0; i < _Count; i++) {
    161.             int index = hashCodesCopy[i] % newSize;
    162.             nextCopy[i] = bucketsCopy[index];
    163.             bucketsCopy[index] = i;
    164.         }
    165.  
    166.         _Buckets = bucketsCopy;
    167.         _Keys = keysCopy;
    168.         _Values = valuesCopy;
    169.         _HashCodes = hashCodesCopy;
    170.         _Next = nextCopy;
    171.     }
    172.  
    173.     private void Resize() {
    174.         Resize(PrimeHelper.ExpandPrime(_Count), false);
    175.     }
    176.  
    177.     public bool Remove(TKey key) {
    178.         if (key == null)
    179.             throw new ArgumentNullException("key");
    180.  
    181.         int hash = _Comparer.GetHashCode(key) & 2147483647;
    182.         int index = hash % _Buckets.Length;
    183.         int num = -1;
    184.         for (int i = _Buckets[index]; i >= 0; i = _Next[i]) {
    185.             if (_HashCodes[i] == hash && _Comparer.Equals(_Keys[i], key)) {
    186.                 if (num < 0)
    187.                     _Buckets[index] = _Next[i];
    188.                 else
    189.                     _Next[num] = _Next[i];
    190.  
    191.                 _HashCodes[i] = -1;
    192.                 _Next[i] = _FreeList;
    193.                 _Keys[i] = default(TKey);
    194.                 _Values[i] = default(TValue);
    195.                 _FreeList = i;
    196.                 _FreeCount++;
    197.                 _Version++;
    198.                 return true;
    199.             }
    200.             num = i;
    201.         }
    202.         return false;
    203.     }
    204.  
    205.     private void Insert(TKey key, TValue value, bool add) {
    206.         if (key == null)
    207.             throw new ArgumentNullException("key");
    208.  
    209.         if (_Buckets == null)
    210.             Initialize(0);
    211.  
    212.         int hash = _Comparer.GetHashCode(key) & 2147483647;
    213.         int index = hash % _Buckets.Length;
    214.         int num1 = 0;
    215.         for (int i = _Buckets[index]; i >= 0; i = _Next[i]) {
    216.             if (_HashCodes[i] == hash && _Comparer.Equals(_Keys[i], key)) {
    217.                 if (add)
    218.                     throw new ArgumentException("Key already exists: " + key);
    219.  
    220.                 _Values[i] = value;
    221.                 _Version++;
    222.                 return;
    223.             }
    224.             num1++;
    225.         }
    226.         int num2;
    227.         if (_FreeCount > 0) {
    228.             num2 = _FreeList;
    229.             _FreeList = _Next[num2];
    230.             _FreeCount--;
    231.         }
    232.         else {
    233.             if (_Count == _Keys.Length) {
    234.                 Resize();
    235.                 index = hash % _Buckets.Length;
    236.             }
    237.             num2 = _Count;
    238.             _Count++;
    239.         }
    240.         _HashCodes[num2] = hash;
    241.         _Next[num2] = _Buckets[index];
    242.         _Keys[num2] = key;
    243.         _Values[num2] = value;
    244.         _Buckets[index] = num2;
    245.         _Version++;
    246.  
    247.         //if (num3 > 100 && HashHelpers.IsWellKnownEqualityComparer(comparer))
    248.         //{
    249.         //    comparer = (IEqualityComparer<TKey>)HashHelpers.GetRandomizedEqualityComparer(comparer);
    250.         //    Resize(entries.Length, true);
    251.         //}
    252.     }
    253.  
    254.     private void Initialize(int capacity) {
    255.         int prime = PrimeHelper.GetPrime(capacity);
    256.  
    257.         _Buckets = new int[prime];
    258.         for (int i = 0; i < _Buckets.Length; i++)
    259.             _Buckets[i] = -1;
    260.  
    261.         _Keys = new TKey[prime];
    262.         _Values = new TValue[prime];
    263.         _HashCodes = new int[prime];
    264.         _Next = new int[prime];
    265.  
    266.         _FreeList = -1;
    267.     }
    268.  
    269.     private int FindIndex(TKey key) {
    270.         if (key == null)
    271.             throw new ArgumentNullException("key");
    272.  
    273.         if (_Buckets != null) {
    274.             int hash = _Comparer.GetHashCode(key) & 2147483647;
    275.             for (int i = _Buckets[hash % _Buckets.Length]; i >= 0; i = _Next[i]) {
    276.                 if (_HashCodes[i] == hash && _Comparer.Equals(_Keys[i], key))
    277.                     return i;
    278.             }
    279.         }
    280.         return -1;
    281.     }
    282.  
    283.     public bool TryGetValue(TKey key, out TValue value) {
    284.         int index = FindIndex(key);
    285.         if (index >= 0) {
    286.             value = _Values[index];
    287.             return true;
    288.         }
    289.         value = default(TValue);
    290.         return false;
    291.     }
    292.  
    293.     private static class PrimeHelper {
    294.         public static readonly int[] Primes = new int[]
    295.         {
    296.             3,
    297.             7,
    298.             11,
    299.             17,
    300.             23,
    301.             29,
    302.             37,
    303.             47,
    304.             59,
    305.             71,
    306.             89,
    307.             107,
    308.             131,
    309.             163,
    310.             197,
    311.             239,
    312.             293,
    313.             353,
    314.             431,
    315.             521,
    316.             631,
    317.             761,
    318.             919,
    319.             1103,
    320.             1327,
    321.             1597,
    322.             1931,
    323.             2333,
    324.             2801,
    325.             3371,
    326.             4049,
    327.             4861,
    328.             5839,
    329.             7013,
    330.             8419,
    331.             10103,
    332.             12143,
    333.             14591,
    334.             17519,
    335.             21023,
    336.             25229,
    337.             30293,
    338.             36353,
    339.             43627,
    340.             52361,
    341.             62851,
    342.             75431,
    343.             90523,
    344.             108631,
    345.             130363,
    346.             156437,
    347.             187751,
    348.             225307,
    349.             270371,
    350.             324449,
    351.             389357,
    352.             467237,
    353.             560689,
    354.             672827,
    355.             807403,
    356.             968897,
    357.             1162687,
    358.             1395263,
    359.             1674319,
    360.             2009191,
    361.             2411033,
    362.             2893249,
    363.             3471899,
    364.             4166287,
    365.             4999559,
    366.             5999471,
    367.             7199369
    368.         };
    369.  
    370.         public static bool IsPrime(int candidate) {
    371.             if ((candidate & 1) != 0) {
    372.                 int num = (int)Math.Sqrt((double)candidate);
    373.                 for (int i = 3; i <= num; i += 2) {
    374.                     if (candidate % i == 0) {
    375.                         return false;
    376.                     }
    377.                 }
    378.                 return true;
    379.             }
    380.             return candidate == 2;
    381.         }
    382.  
    383.         public static int GetPrime(int min) {
    384.             if (min < 0)
    385.                 throw new ArgumentException("min < 0");
    386.  
    387.             for (int i = 0; i < PrimeHelper.Primes.Length; i++) {
    388.                 int prime = PrimeHelper.Primes[i];
    389.                 if (prime >= min)
    390.                     return prime;
    391.             }
    392.             for (int i = min | 1; i < 2147483647; i += 2) {
    393.                 if (PrimeHelper.IsPrime(i) && (i - 1) % 101 != 0)
    394.                     return i;
    395.             }
    396.             return min;
    397.         }
    398.  
    399.         public static int ExpandPrime(int oldSize) {
    400.             int num = 2 * oldSize;
    401.             if (num > 2146435069 && 2146435069 > oldSize) {
    402.                 return 2146435069;
    403.             }
    404.             return PrimeHelper.GetPrime(num);
    405.         }
    406.     }
    407.  
    408.     public ICollection<TKey> Keys {
    409.         get { return _Keys.Take(Count).ToArray(); }
    410.     }
    411.  
    412.     public ICollection<TValue> Values {
    413.         get { return _Values.Take(Count).ToArray(); }
    414.     }
    415.  
    416.     public void Add(KeyValuePair<TKey, TValue> item) {
    417.         Add(item.Key, item.Value);
    418.     }
    419.  
    420.     public bool Contains(KeyValuePair<TKey, TValue> item) {
    421.         int index = FindIndex(item.Key);
    422.         return index >= 0 &&
    423.             EqualityComparer<TValue>.Default.Equals(_Values[index], item.Value);
    424.     }
    425.  
    426.     public void CopyTo(KeyValuePair<TKey, TValue>[] array, int index) {
    427.         if (array == null)
    428.             throw new ArgumentNullException("array");
    429.  
    430.         if (index < 0 || index > array.Length)
    431.             throw new ArgumentOutOfRangeException(string.Format("index = {0} array.Length = {1}", index, array.Length));
    432.  
    433.         if (array.Length - index < Count)
    434.             throw new ArgumentException(string.Format("The number of elements in the dictionary ({0}) is greater than the available space from index to the end of the destination array {1}.", Count, array.Length));
    435.  
    436.         for (int i = 0; i < _Count; i++) {
    437.             if (_HashCodes[i] >= 0)
    438.                 array[index++] = new KeyValuePair<TKey, TValue>(_Keys[i], _Values[i]);
    439.         }
    440.     }
    441.  
    442.     public bool IsReadOnly {
    443.         get { return false; }
    444.     }
    445.  
    446.     public bool Remove(KeyValuePair<TKey, TValue> item) {
    447.         return Remove(item.Key);
    448.     }
    449.  
    450.     public Enumerator GetEnumerator() {
    451.         return new Enumerator(this);
    452.     }
    453.  
    454.     IEnumerator IEnumerable.GetEnumerator() {
    455.         return GetEnumerator();
    456.     }
    457.  
    458.     IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator() {
    459.         return GetEnumerator();
    460.     }
    461.  
    462.     public struct Enumerator : IEnumerator<KeyValuePair<TKey, TValue>> {
    463.         private readonly SerializableDictionary<TKey, TValue> _Dictionary;
    464.         private int _Version;
    465.         private int _Index;
    466.         private KeyValuePair<TKey, TValue> _Current;
    467.  
    468.         public KeyValuePair<TKey, TValue> Current {
    469.             get { return _Current; }
    470.         }
    471.  
    472.         internal Enumerator(SerializableDictionary<TKey, TValue> dictionary) {
    473.             _Dictionary = dictionary;
    474.             _Version = dictionary._Version;
    475.             _Current = default(KeyValuePair<TKey, TValue>);
    476.             _Index = 0;
    477.         }
    478.  
    479.         public bool MoveNext() {
    480.             if (_Version != _Dictionary._Version)
    481.                 throw new InvalidOperationException(string.Format("Enumerator version {0} != Dictionary version {1}", _Version, _Dictionary._Version));
    482.  
    483.             while (_Index < _Dictionary._Count) {
    484.                 if (_Dictionary._HashCodes[_Index] >= 0) {
    485.                     _Current = new KeyValuePair<TKey, TValue>(_Dictionary._Keys[_Index], _Dictionary._Values[_Index]);
    486.                     _Index++;
    487.                     return true;
    488.                 }
    489.                 _Index++;
    490.             }
    491.  
    492.             _Index = _Dictionary._Count + 1;
    493.             _Current = default(KeyValuePair<TKey, TValue>);
    494.             return false;
    495.         }
    496.  
    497.         void IEnumerator.Reset() {
    498.             if (_Version != _Dictionary._Version)
    499.                 throw new InvalidOperationException(string.Format("Enumerator version {0} != Dictionary version {1}", _Version, _Dictionary._Version));
    500.  
    501.             _Index = 0;
    502.             _Current = default(KeyValuePair<TKey, TValue>);
    503.         }
    504.  
    505.         object IEnumerator.Current {
    506.             get { return Current; }
    507.         }
    508.  
    509.         public void Dispose() {
    510.         }
    511.     }
    512. }
    Finally, I am also using a subclass of the serializable dictionary according to my needs:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. //My own Dictionaries that are non-generic types of the serializable dictionary
    5.  
    6. [System.Serializable] public class SpriteDict : SerializableDictionary<Sprite,GameObject> {}
    7.  
    I want to know if there is a better way of doing this, so that the sprite references are not lost between updates. I had considered using the sprite names, but that creates a lot of garbage for the gc. I apologize for the amount of code presented here.
     
    Last edited: Oct 7, 2015
  2. spryx

    spryx

    Joined:
    Jul 23, 2013
    Posts:
    557
    Ok, I have solved the issue (Sort Of) by rebuilding the dictionary. This is not a true solution, because I have to rebuild the dictionary every time I launch Unity. Additionally, the functionality is still lost in builds. Unfortunately, this requires the sprites to be placed in a resources folder. This is the updated custom editor:

    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3. using System.Collections.Generic;
    4.  
    5. [CustomEditor(typeof(AddToSprite))]
    6. public class AddToSpriteEditor : Editor {
    7.  
    8.     private Sprite nkSprite;
    9.     private GameObject nkObj;
    10.     private GUILayoutOption[] max_120 = new GUILayoutOption[] { GUILayout.MaxWidth(120f) };
    11.     private GUILayoutOption[] max_30 = new GUILayoutOption[] { GUILayout.MaxWidth(30f) };
    12.  
    13.     public override void OnInspectorGUI() {
    14.         AddToSprite myA2S = (AddToSprite)target;
    15.  
    16.         GUI.color = Color.red;
    17.         GUI.skin.button.fixedWidth = 0f;
    18.         if (GUILayout.Button("Clear Dictionary")) {
    19.             if (EditorUtility.DisplayDialog("Continue?", "Are you sure?\nThis action cannot be undone!", "Yes", "Cancel")) {
    20.                 myA2S.sprPrfabDict.Clear();
    21.                 EditorUtility.SetDirty(myA2S);
    22.             }
    23.         }
    24.  
    25.         GUI.color = Color.cyan;
    26.         if (GUILayout.Button("Rebuild Dictionary")) {
    27.  
    28.             //Get all sprites
    29.             Sprite[] allSprites = (Sprite[])Resources.FindObjectsOfTypeAll(typeof(Sprite));
    30.          
    31.             //Create a place for sprite names
    32.             string[] spriteNames = new string[allSprites.Length];
    33.          
    34.             //Store names in array
    35.             for (int t=0; t<allSprites.Length; t++) {
    36.                 spriteNames[t] = allSprites[t].name;
    37.                 //Debug.Log(spriteNames[t]);
    38.             }
    39.  
    40.             //Create a new dictionary
    41.             SpriteDict newDictionary = new SpriteDict();
    42.  
    43.             foreach (KeyValuePair<Sprite, GameObject> kVal in myA2S.sprPrfabDict) {
    44.                 //Try to find sprite name in array
    45.                 int aryIdx = System.Array.IndexOf(spriteNames, kVal.Key.name);
    46.                 //Found
    47.                 if (aryIdx != -1) {
    48.                     //Add New Key
    49.                     newDictionary.Add(allSprites[aryIdx], kVal.Value);
    50.                     Debug.Log("Remapped Key:" + kVal.Key);
    51.                 }
    52.                 else {
    53.                     Debug.LogError("Could not find a new reference for sprite:" + kVal.Key);
    54.                 }
    55.             }
    56.  
    57.             //Set the dictionary to the new version!
    58.             myA2S.sprPrfabDict = newDictionary;
    59.             EditorUtility.SetDirty(myA2S);
    60.         }
    61.  
    62.         GUI.color = Color.white;
    63.  
    64.         GUI.skin.button.fixedWidth = 25f;
    65.  
    66.         if (myA2S.sprPrfabDict == null) {
    67.             //Init Dictionary
    68.             myA2S.sprPrfabDict = new SpriteDict();
    69.             EditorUtility.SetDirty(myA2S);
    70.         }
    71.  
    72.         foreach (KeyValuePair<Sprite, GameObject> kVal in myA2S.sprPrfabDict) {
    73.             GUILayout.BeginHorizontal();
    74.             if (GUILayout.Button("-")) {
    75.                 Debug.Log("Key removed: " + myA2S.sprPrfabDict.Remove(kVal.Key));
    76.                 EditorUtility.SetDirty(myA2S);
    77.                 break;
    78.             }
    79.             EditorGUILayout.LabelField(kVal.Key.name, max_120);
    80.             EditorGUILayout.LabelField("-+-", max_30);
    81.             EditorGUILayout.LabelField(kVal.Value.name, max_120);
    82.  
    83.             GUILayout.EndHorizontal();
    84.         }
    85.  
    86.  
    87.         GUILayout.BeginHorizontal();
    88.  
    89.         if (GUILayout.Button("+")) {
    90.             //Add the new kv pair
    91.             if ((nkSprite != null) && (nkObj != null)) {
    92.                 myA2S.sprPrfabDict.Add(nkSprite, nkObj);
    93.                 EditorUtility.SetDirty(myA2S);
    94.             }
    95.             else {
    96.                 Debug.LogError("Sprite and GameObject pair are invalid!");
    97.             }
    98.         }
    99.  
    100.         nkSprite = (Sprite)EditorGUILayout.ObjectField(nkSprite, typeof(Sprite), false, max_120);
    101.         EditorGUILayout.LabelField("-+-", max_30);
    102.         nkObj = (GameObject)EditorGUILayout.ObjectField(nkObj, typeof(GameObject), false, max_120);
    103.  
    104.         GUILayout.EndHorizontal();
    105.     }
    106. }
    107.  
     
    Last edited: Oct 7, 2015
  3. spryx

    spryx

    Joined:
    Jul 23, 2013
    Posts:
    557
    So, I am going to bump this....there has to be a way to keep the dictionary references without rebuilding it every time unity starts. The odd part is that the actual dictionary is kept intact, but the references in the dictionary will not match the sprites unless the dictionary is rebuilt.
     
  4. spryx

    spryx

    Joined:
    Jul 23, 2013
    Posts:
    557
    Bump once more. Any advice appreciated
     
  5. spryx

    spryx

    Joined:
    Jul 23, 2013
    Posts:
    557
    bump once more... I have changed to using a List<int> and List<GameObject> instead. I would like to know why using objects as dictionary keys is not a good idea....