c# - 在 Unity C# 中序列化 ObservableCollection 类 ObservableList
问题描述
由于目前ObservableCollection
尚不支持在 Unity 中对 C# 进行序列化,因此我使用了一个脚本,该脚本扩展List<>
并创建了一个名为 Serializable 的类ObservableList
,如本统一论坛答案ObservableList中所述。以下是相同的代码:
[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);
}
}
}
它仍然没有被序列化,我在 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");
}
}
我将此脚本作为组件附加到 GameObject 上,以便我可以输入size
此列表的 ,玩弄这些值(就像我可以使用 一样)并执行一些操作,这些操作只有在更新List
内部的某些值时才会触发。ObservableList
我想看的
我所看到的
解决方案
如果您希望对操作进行序列化,则必须使用 UnityEvents(它与 Unity 的序列化事件系统挂钩)。
确保在要序列化的所有类型之前使用 [SerializedField] 属性。
主要问题可能源于继承,它不能很好地与 Unity 的序列化系统配合使用。一般来说,我永远不会从 List 继承(这里有一些原因)相反,我会让你的 observable 类型成为 List 的包装器,并带有一些附加功能(List 将是 Observable 中的成员)。
编辑 1
添加了经过测试的代码示例。ObservedList<T> 不是继承,而是充当 List<T> 的包装器。您将能够订阅 Changed 和 Updated 事件,但它们没有被序列化。如果您想访问任何其他列表功能,您只需在 ObservedList<t> 类中添加一个公共方法,该方法充当其包装器。如果您有任何其他问题,请告诉我。
[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();
}
}
推荐阅读
- python - 将 curl 请求转换为 python 请求
- laravel - 如何从多个关系中获取数据
- javascript - 验证月/年是否大于当前日期
- flutter - 在 Flutter 中将 Widget 从单独文件添加到主文件
- javascript - 在 JavaScript 中,属性名称周围的花括号是什么?
- osisoft - 如何在 PI-Web API 中通过属性名称和属性值查找元素
- laravel - Laravel - 如何在不活动 30 分钟后自动注销并重定向到登录页面
- python - 如何在情节中为ticktext着色?
- python - 过滤查询集时forms.py中的Django MultiValueKeyDictError
- android - FusedLocationProviderClient 无法通过 3G 或 4G 网络获取 GPS 位置,除非先连接到 WIFI 网络