[英]How to serialise HashSet for usage in inspector
Unity版本:2017.3.1f1
我正在嘗試在Unity檢查器中使用HashSet
。 具體來說,我需要一些MonoBehaviour
來具有HashSet
字段,可以通過檢查器修改其內容。
為了實現此目標,我創建了一個具體類,該類將HashSet
子類化,並在內部使用List
進行(反序列化),其方式與本指南中的Dictionary非常相似:
但是,我遇到一個列表顯示在檢查器中的問題,但是我不能在其中設置多個值。 如果我將列表的大小設置為2或更大,則立即將其設置回1。
為了調試該問題,我發現OnBeforeSerialize
(而不是 OnAfterDeserialize
)正在每幀執行一次,從而不斷重置該值。 我不確定為什么將它設置為1。
請注意,如果我在1個可用插槽中輸入了字符串,則不會被重置。 因此,此方法對於0或1個字符串(但不更多)的HashSet
當前“可用”。 另外,如果我使用HashSet
字段而不是從其繼承(如上述鏈接中所做的那樣),結果也不會改變。
這是一個最小的示例:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TEST : MonoBehaviour
{
public StringHashSet test;
}
[System.Serializable]
public class SerializableHashSet<T> : HashSet<T>, ISerializationCallbackReceiver
{
public List<T> values = new List<T> ();
public void OnBeforeSerialize ()
{
values.Clear ();
foreach (T val in this) {
values.Add (val);
}
}
public void OnAfterDeserialize ()
{
this.Clear ();
foreach (T val in values) {
this.Add (val);
}
}
}
[System.Serializable]
public class StringHashSet : SerializableHashSet<string>
{
}
HashSet
)? OnBeforeSerialize
? 更多信息
我發現這是因為更改列表的大小時,默認情況下列表中的所有新元素都具有與前一個元素相同的值,因此在HashSet
中將所有這些元素壓縮為1值。
因此,盡管問題2仍然懸而未決,但問題1已經演變為尋求一種解決方法,同時又保持了所需的HashSet
功能。
考慮到問題中“ 更多信息”部分中添加的發現,這是我解決此問題的方法:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class SerializableHashSet<T> : HashSet<T>, ISerializationCallbackReceiver
{
public List<T> values = new List<T> ();
public void OnBeforeSerialize ()
{
var cur = new HashSet<T> (values);
foreach (var val in this) {
if (!cur.Contains (val)) {
values.Add (val);
}
}
}
public void OnAfterDeserialize ()
{
this.Clear ();
foreach (var val in values) {
this.Add (val);
}
}
}
[System.Serializable]
public class StringHashSet : SerializableHashSet<string>
{
}
OnAfterDeserialize
相同。
OnBeforeSerialize
不再清除values
列表。 相反,它會將HashSet
中的新值添加到List
-特別是HashSet
中存在但List
不存在的值。
當將新元素添加到檢查器中的列表時,這將使功能得以繼續:重復和空白條目將正常工作,因為列表不會在任何時候被清除,只會被添加到列表中。
關於第二個問題,我發現了有關為何如此頻繁執行OnBeforeSerialize
以下信息: http : //answers.unity.com/answers/796853/view.html
相關資料:
如果在編輯器中打開了對象的檢查器,則調用每一幀
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.