using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public struct ImageInfo
{
public Texture texture;
public int width;
public int height;
}
public class ImagesData : MonoBehaviour
{
public ImageInfo[] images;
public static Vector2 AspectRatio(float width, float height)
{
Vector2 scale = Vector2.one;
}
}
这是为 2D 图像制作序列化字典的代码,如何使其接受 3D 模型?我希望它像照片中的那样。
这是为二维图像制作序列化字典的代码
不,不是。您显示的是 ImageInfo
的序列化
array。
对于您在图像中显示的内容,您可以简单地执行
[Serializable]
public class ModeInfo
{
public string Id;
public GameObject Value;
}
public class ModelsDataManager : MonoBehaviour
{
public ModeInfo[] InteractionModes;
}
或者如果您想要进一步支持一些词典功能
public class ModelsDataManager : MonoBehaviour
{
[SerializeField]
private List<ModeInfo> InteractionModes;
private bool TryGetInfo(string id, out ModeInfo value)
{
foreach (var info in InteractionModes)
{
if (info.Id == id)
{
value = info;
return true;
}
}
value = default;
return false;
// or same thing using Linq (needs "using System.Linq;")
//value = InteractionModes.FirstOrDefault(info => info.Id == id);
//return value != null;
}
public bool TryGetValue(string id, out GameObject value)
{
if (!TryGetInfo(id, out var info))
{
value = default;
return false;
}
// note that just like in normal dictionaries the value can still be "null" though
value = info.Value;
return true;
}
public void AddOrOverwrite(string id, GameObject value)
{
if (!TryGetInfo(id, out var info))
{
info = new ModeInfo()
{
Id = id
};
InteractionModes.Add(info);
}
info.Value = value;
}
}
如果您确实想要使用整个字典功能,包括键检查、更便宜的值访问而无需迭代 等等我建议不要从头开始实现这个,而是使用现有的解决方案,例如
Unity 自己的,它隐藏在 Core RP 库包中(作为依赖项安装,例如与 UniversialRenderPipeline 或 HighDefinitionenderPipeline 一起安装)。
但是这是非常基本的并且仅用于序列化 - 没有有用的检查器抽屉
azixMcAze 的 Unity-SerializedDictionary(也可作为包)
有一个很酷的检查员抽屉,甚至可以处理重复的钥匙检查等。
请注意,Odin Inspector 不是免费的
或者只是继续测试其他许多解决方案之一;)
这是我的统一可序列化字典的迷你包,具有 Monobehaviour 和 Scriptable Object 变体
https://github.com/Eduard-Malxa/Serialized-Dictionary-Unity
核心脚本
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class SerializableDictionarySO<TKey, TValue> : ScriptableObject, ISerializationCallbackReceiver
{
[SerializeField] private List<KeyValueEntry> entries;
private List<TKey> keys = new List<TKey>();
public Dictionary<TKey, TValue> dictionary = new Dictionary<TKey, TValue>();
[Serializable]
class KeyValueEntry
{
public TKey key;
public TValue value;
}
public void OnAfterDeserialize()
{
dictionary.Clear();
for (int i = 0; i < entries.Count; i++)
{
dictionary.Add(entries[i].key, entries[i].value);
}
}
public void OnBeforeSerialize()
{
if (entries == null)
{
return;
}
keys.Clear();
for (int i = 0; i < entries.Count; i++)
{
keys.Add(entries[i].key);
}
var result = keys.GroupBy(x => x)
.Where(g => g.Count() > 1)
.Select(x => new { Element = x.Key, Count = x.Count() })
.ToList();
if (result.Count > 0)
{
var duplicates = string.Join(", ", result);
Debug.LogError($"Warning {GetType().FullName} keys has duplicates {duplicates}");
}
}
}
public class SerializableDictionary<TKey, TValue> : MonoBehaviour, ISerializationCallbackReceiver
{
[SerializeField] private List<KeyValueEntry> entries;
private List<TKey> keys = new List<TKey>();
public Dictionary<TKey, TValue> dictionary = new Dictionary<TKey, TValue>();
[Serializable]
class KeyValueEntry
{
public TKey key;
public TValue value;
}
public void OnAfterDeserialize()
{
dictionary.Clear();
for (int i = 0; i < entries.Count; i++)
{
dictionary.Add(entries[i].key, entries[i].value);
}
}
public void OnBeforeSerialize()
{
if (entries == null)
{
return;
}
keys.Clear();
for (int i = 0; i < entries.Count; i++)
{
keys.Add(entries[i].key);
}
var result = keys.GroupBy(x => x)
.Where(g => g.Count() > 1)
.Select(x => new { Element = x.Key, Count = x.Count() })
.ToList();
if (result.Count > 0)
{
var duplicates = string.Join(", ", result);
Debug.LogError($"Warning {GetType().FullName} keys has duplicates {duplicates}");
}
}
}