C# 在Unity C中序列化类似ObservableCollection的类ObservableList#
由于到目前为止还不支持在Unity中序列化C#的C# 在Unity C中序列化类似ObservableCollection的类ObservableList#,c#,unity3d,C#,Unity3d,由于到目前为止还不支持在Unity中序列化C#的observativeCollection,因此我使用一个脚本扩展List,并创建一个名为observativeList的可序列化类,如Unity论坛的回答中所述。以下是相同的代码: [Serializable] public class ObservedList<T> : List<T> { public event Action<int> Changed = delegate { };
observativeCollection
,因此我使用一个脚本扩展List
,并创建一个名为observativeList
的可序列化类,如Unity论坛的回答中所述。以下是相同的代码:
[Serializable]
public class ObservedList<T> : List<T>
{
public event Action<int> Changed = delegate { };
public event Action Updated = delegate { };
public new void Add(T item)
{
base.Add(item);
Updated();
}
public new void Remove(T item)
{
base.Remove(item);
Updated();
}
public new void AddRange(IEnumerable<T> collection)
{
base.AddRange(collection);
Updated();
}
public new void RemoveRange(int index, int count)
{
base.RemoveRange(index, count);
Updated();
}
public new void Clear()
{
base.Clear();
Updated();
}
public new void Insert(int index, T item)
{
base.Insert(index, item);
Updated();
}
public new void InsertRange(int index, IEnumerable<T> collection)
{
base.InsertRange(index, collection);
Updated();
}
public new void RemoveAll(Predicate<T> match)
{
base.RemoveAll(match);
Updated();
}
public new T this[int index]
{
get
{
return base[index];
}
set
{
base[index] = value;
Changed(index);
}
}
}
[可序列化]
公共类观察列表:列表
{
公共事件操作已更改=委托{};
公共事件操作更新=委托{};
新增公共作废(T项)
{
基础。添加(项目);
更新();
}
公共新作废删除(T项)
{
底座。移除(项目);
更新();
}
public new void AddRange(IEnumerable集合)
{
base.AddRange(集合);
更新();
}
公共新无效删除范围(整数索引、整数计数)
{
基本参数(索引、计数);
更新();
}
公共新空白清除()
{
base.Clear();
更新();
}
公共新空白插入(整数索引,T项)
{
基础。插入(索引,项目);
更新();
}
public new void InsertRange(int索引,IEnumerable集合)
{
base.InsertRange(索引、集合);
更新();
}
public new void RemoveAll(谓词匹配)
{
基础。移除所有(匹配);
更新();
}
公共新T此[int索引]
{
得到
{
返回基数[指数];
}
设置
{
基准[指数]=数值;
变更(索引);
}
}
}
它仍然没有被序列化,我无法在Unity编辑器中看到它。任何帮助都将不胜感激
编辑#1
预期用例:
public class Initialize : MonoBehaviour
{
public ObservedList<int> percentageSlider = new ObservedList<int>();
void Start()
{
percentageSlider.Changed += ValueUpdateHandler;
}
void Update()
{
}
private void ValueUpdateHandler(int index)
{
// Some index specific action
Debug.Log($"{index} was updated");
}
}
公共类初始化:单行为
{
public ObservedList percentageSlider=新建ObservedList();
void Start()
{
percentageSlider.Changed+=ValueUpdateHandler;
}
无效更新()
{
}
私有void ValueUpdateHandler(int索引)
{
//一些指标具体行动
Log($“{index}已更新”);
}
}
我将这个脚本作为一个组件附加到一个游戏对象上,这样我就可以输入这个列表的大小
,处理这些值(就像我可以处理列表
),并执行一些操作,这些操作只有在可观察列表
中的某个值更新时才会触发
我想看什么
我所看到的
[Serializable]
public class ObservedList<T>
{
public event Action<int> Changed;
public event Action Updated;
[SerializeField] private List<T> _value;
public T this[int index]
{
get
{
return _value[index];
}
set
{
//you might want to add a check here to only call changed
//if _value[index] != value
_value[index] = value;
Changed?.Invoke(index);
}
}
public void Add(T item)
{
_value.Add(item);
Updated?.Invoke();
}
public void Remove(T item)
{
_value.Remove(item);
Updated?.Invoke();
}
public void AddRange(IEnumerable<T> collection)
{
_value.AddRange(collection);
Updated?.Invoke();
}
public void RemoveRange(int index, int count)
{
_value.RemoveRange(index, count);
Updated?.Invoke();
}
public void Clear()
{
_value.Clear();
Updated?.Invoke();
}
public void Insert(int index, T item)
{
_value.Insert(index, item);
Updated?.Invoke();
}
public void InsertRange(int index, IEnumerable<T> collection)
{
_value.InsertRange(index, collection);
Updated?.Invoke();
}
public void RemoveAll(Predicate<T> match)
{
_value.RemoveAll(match);
Updated?.Invoke();
}
}
[可序列化]
公共类观察列表
{
公共事件行动改变;
更新公共活动行动;
[SerializeField]私有列表\u值;
公共T此[int索引]
{
得到
{
返回_值[索引];
}
设置
{
//您可能需要在此处添加一个复选框,以仅更改呼叫
//如果_值[索引]!=值
_值[索引]=值;
已更改?.Invoke(索引);
}
}
公共作废新增(T项)
{
_增值(项目);
已更新?.Invoke();
}
公共作废删除(T项)
{
_价值。删除(项目);
已更新?.Invoke();
}
公共void AddRange(IEnumerable集合)
{
_value.AddRange(集合);
已更新?.Invoke();
}
公共无效删除范围(整数索引、整数计数)
{
_移除范围(索引、计数);
已更新?.Invoke();
}
公共空间清除()
{
_value.Clear();
已更新?.Invoke();
}
公共空白插入(整数索引,T项)
{
_插入(索引,项目);
已更新?.Invoke();
}
公共void InsertRange(int索引,IEnumerable集合)
{
_value.InsertRange(索引、集合);
已更新?.Invoke();
}
public void RemoveAll(谓词匹配)
{
_value.RemoveAll(匹配);
已更新?.Invoke();
}
}
[Serializable]
public class ObservedList<T>
{
public event Action<int> Changed;
public event Action Updated;
[SerializeField] private List<T> _value;
public T this[int index]
{
get
{
return _value[index];
}
set
{
//you might want to add a check here to only call changed
//if _value[index] != value
_value[index] = value;
Changed?.Invoke(index);
}
}
public void Add(T item)
{
_value.Add(item);
Updated?.Invoke();
}
public void Remove(T item)
{
_value.Remove(item);
Updated?.Invoke();
}
public void AddRange(IEnumerable<T> collection)
{
_value.AddRange(collection);
Updated?.Invoke();
}
public void RemoveRange(int index, int count)
{
_value.RemoveRange(index, count);
Updated?.Invoke();
}
public void Clear()
{
_value.Clear();
Updated?.Invoke();
}
public void Insert(int index, T item)
{
_value.Insert(index, item);
Updated?.Invoke();
}
public void InsertRange(int index, IEnumerable<T> collection)
{
_value.InsertRange(index, collection);
Updated?.Invoke();
}
public void RemoveAll(Predicate<T> match)
{
_value.RemoveAll(match);
Updated?.Invoke();
}
}
[可序列化]
公共类观察列表
{
公共事件行动
public class Example : MonoBehaviour
{
public ObservedList<int> percentageSlider = new ObservedList<int>();
private void Start()
{
percentageSlider.Changed += ValueUpdateHandler;
// Just as an example
percentageSlider[3] = 42;
}
private void ValueUpdateHandler(int index, int oldValue, int newValue)
{
// Some index specific action
Debug.Log($"Element at index {index} was updated from {oldValue} to {newValue}");
}
}
public abstract class ObservedList { }
[Serializable]
public class ObservedList<T> : ObservedList, IList<T>
{
...
}
[CustomPropertyDrawer(typeof(ObservedList), true)]
public class ObservedListDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
// NOTE: Now here is the dirty hack
// even though the ObservedList itself doesn't have that property
// we can still look for the field called "_list" which only the
// ObservedList<T> has
var list = property.FindPropertyRelative("_list");
EditorGUI.PropertyField(position, list, label, true);
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
var list = property.FindPropertyRelative("_list");
return EditorGUI.GetPropertyHeight(list, label, true);
}
}
[Serializable]
public class ObservedListInt : ObservedList<int>{ }
public class Example : MonoBehaviour
{
public ObservedListInt percentageSlider = new ObservedListInt();
private void Start()
{
percentageSlider.Changed += ValueUpdateHandler;
// Just as an example
percentageSlider[3] = 42;
}
private void ValueUpdateHandler(int index, int oldValue, int newValue)
{
// Some index specific action
Debug.Log($"Element at index {index} was updated from {oldValue} to {newValue}");
}
}