更新:これはUnityの確認済みのバグであり、提出されています。Unityシリアライズされたディクショナリ「12個の項目の後にインデックスが外れる」
汎用のシリアライズ可能なディクショナリと、int:Objectの特定のディクショナリを作成しました。コンパイラが何らかの理由でエラー
IndexOutOfRangeException: Array index is out of range. System.Collections.Generic.Dictionary`2+Enumerator[System.Int32,UnityEngine.ScriptableObject].MoveNext ()
と狂気しかし
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
/// <summary>
/// Is what it sounds like
/// </summary>
[System.Serializable]
public class SerializableDictionary<TKey,TValue> : Dictionary<TKey,TValue>, ISerializationCallbackReceiver
{
[SerializeField]
protected List<TKey> keys = new List<TKey>();
[SerializeField]
protected List<TValue> values = new List<TValue>();
//Save the dictionary to lists
public void OnBeforeSerialize()
{
keys.Clear();
values.Clear();
foreach(KeyValuePair<TKey,TValue> pair in this)
{
keys.Add(pair.Key);
values.Add(pair.Value);
}
}
//Load the dictionary from lists
public void OnAfterDeserialize()
{
this.Clear();
if(keys.Count != values.Count)
{
throw new System.Exception(string.Format("there are {0} keys and {1} values after deserialization. Make sure that both key and value types are serializable."));
}
for(int i = 0; i<keys.Count; i++)
{
this.Add(keys[i], values[i]);
}
}
}
[System.Serializable]
public class DictionaryOfStringAndInt : SerializableDictionary<string, int> { }
[System.Serializable]
public class DictionaryOfIntAndSerializableObject : SerializableDictionary<int, ScriptableObject>
{
}
このライン
foreach(KeyValuePair<TKey,TValue> pair in this)
は、そのエラーをスローしますが、私のDictionaryOfIntAndSerializableObject
は12個のオブジェクトを超えた後にのみ。これは完全に私を困惑させる。
DictionaryOfIntAndSerializableObject
が12個の項目の後に範囲外の例外を投げている理由を考えることができますか? http://forum.unity3d.com/threads/serializeable-dictionary-exceptions-after-code-change.319285/
さらに説明
私はすべてのモデル(タイプ)のデータを保持するデータベースのゲームオブジェクトを持っている:
更新この投稿は、同じ問題を持っています。私がやっているのは、CSVファイルを構文解析してScriptableObjects
にして、データベースGameObjectの中に保存するということです。そうすれば、私のデータベースは実行時に一度コンパイルされ、実行時とエディタの両方で自由にアクセスできます。このデータベースオブジェクトは、DictionaryOfIntAndSerializableObject
オブジェクトを持つオブジェクトです。私はすべてのテーブルのために1つを持っている(私は武器、鎧などのために1つを持っている)。ここで
はすべての私のスクリプト可能なオブジェクトの基底クラス(それは辞書に値として格納されます)です:
public class M_Card : ScriptableObject
{
public E_CardTypes cardTypeID;
public int rankID;
public int rarityID;
public int qualityID;
public int editionID;
public Sprite sprite;
public M_Card()
{
cardTypeID = 0;
rankID = 0;
qualityID = 0;
sprite = null;
}
}
そして、ここでは(CSVから行を解析した後)のコードであるI辞書に部M_Cardのインスタンスを置く:
private void LoadActionCards()
{
List<Dictionary<string, object>> listData = CSVReader.Read("Actions");
for (var i = 0; i < listData.Count; i++)
{
Dictionary<string, object> data = listData[i];
string name = (string)data["Name"];
M_ActionCard card = ScriptableObjectCreator.createActionCard(name);
int cardTypeID = (int)data["CardTypeID"];
card.cardTypeID = (E_CardTypes)cardTypeID;
AssignActionCardValues(card, data);
Database.ACTION_CARD_LIST.Add(card);
// THIS IS WHERE I MAP THE TYPEID TO THE M_CARD OBJECT
// THIS IS WHERE THE OBJECT IS ADDED TO THE DICTIONARY
Database.ACTION_CARD_MAP[card.ID] = card;
}
}
だから今、私はデータ(武器、兜、鎧、クラス)の4つのテーブルを持っています。ただし、これらのテーブルのいずれかに12個以上のアイテムがある場合は、13番目のアイテムでそのエラーが100%発生します。私はまだ調査中ですが、どのようにキーが辞書に追加されているかを調べています。
M_HelmetCardはM_ActionCardと同じであり、両方ともM_Cardの空のサブクラスであることに注意してください。
ここに、少しだけ証拠を追加する写真があります。最初は全部で16個のヘルメットがあります。エラーが表示されます
エラーが12個を超えるリスト。実際のアイテムは問題ではありません(特定の13番目のアイテムが破損しているようではなく、13個のアイテムがこのエラーを引き起こします)。
現時点では非常に困惑しています。
(私はSprite
クラスがシリアル化されていて、データが多すぎると思っていたかもしれませんが、問題が解消されても問題は解決しませんでした)
更新ここに、この問題があるサンプルプロジェクトへのリンクがあります(削除されていないものはすべて削除されています)。
https://www.mediafire.com/?axxn3u823cm7c59は、エラーを生成するには、次のheirachyでdatabase
オブジェクトをクリックしてUpdate Database
ボタンをクリックしてください 。
次に再生を押すと、エラーが表示されます。
13番目のアイテムの見方を確認するには、Helmets CSVファイル(\Assets\Resources\ExcelData
)を開いて、13番目のアイテムを削除します。次に、データベースを再度更新します。その後、ヒットします。エラーはなくなります!
これは主要なWTFです:?
の種類の助けを借りて生成された 'ただし、コンパイラはあなたが時エラーをコンパイルし得る意味でください' ...エラーでクレイジー行きますか?それとも、実行時にこれを手に入れますか? – dotnetom
私には疑わしいと思われる... int value = keys [Random.Range(0、keys.Count)]; '特にランダムな部分... – Ian
そうではありませんが、 P)。 – Aggressor