存储/恢复属性值

时间:2016-05-17 09:52:10

标签: c# unity3d state

我正在使用Unity,我正在尝试创建一个可以存储特定组件状态的类,并在稍后阶段恢复它们。然而,这与Unity无关,应该能够在任何类型的属性中使用。然而,这是我将使用的示例,因为它是直观的,并且该示例的解决方案应该给出完整的答案。

我有一个GameObject,它附有一个Transform类型的对象,用于存储对象的位置,旋转和比例。这就是我想要存储的内容,并且能够在以后恢复。

存储状态

通过创建Transform的深层副本来保存对象的状态,然后将其保存在类型为键的字典中,并将副本保存为值。可以通过Serializable classObject extension来实现深层复制。请注意,使用IClonable是不可能的,因为我没有类Transform的代码。使用Object扩展名,代码很简单。在课堂内:

// The object that should have its state (re)stored
public GameObject _parent;
// Dictionary to hold the object state and its underlying type
public Dictionary<Type, object> _states;

// Store a deep copy of the component of type T
public void StoreState<T>() {
    _states.Add(typeof(T), _parent.GetComponent<T>().Copy());
}

// Alternatively
public void StoreState(Type t) {
    _states.Add(t, _parent.GetComponent(t).Copy());
} 

恢复状态

这是我被卡住的部分。我不能简单地创建Transform的新实例,并将其分配给GameObject,因为它无法访问。如何从字典值中复制所有值?

public void RestoreInitialState() {
    foreach (var pair in _states) {
        // Copy to original?
        _parent.GetComponent(pair.Key) = pair.Value.Copy();
        // Error: The left-hand side of an assignment must be a variable, property or indexer
        //        This expression cannot be used as an assignment target
    }
}

复制所有公共字段和/或属性可能就足够了吗?

3 个答案:

答案 0 :(得分:1)

使用新的unity json序列化程序http://docs.unity3d.com/Manual/JSONSerialization.html,它简单,简单,快于我使用统一的任何json库,它甚至可以顺利地对你的向量进行序列化。创建一个类并保存它的所有对象变量和恢复它们只需使用jsontoObject,所有ur值都会返回并恢复,如果这就是你要求的。

答案 1 :(得分:0)

I have been using XML serialization to achieve things like that. It feels a bit like a hack, but it's been working well for me this far.

Here are a couple of helper methods to serialize and deserialize an object, which could obviously be your "Transform" object:

        /// <summary>
        /// Serializes an object to an xml string
        /// </summary>
        public static String Serialize(Object obj)
        {
            if (obj == null)
            {
                return "";
            }

            string xml = string.Empty;          

            try
            {
                // Remove xml declaration.
                XmlWriterSettings settings = new XmlWriterSettings();
                settings.OmitXmlDeclaration = true;

                using (StringWriter sw = new StringWriter())
                {
                    using (XmlWriter xw = XmlWriter.Create(sw, settings))
                    {
                        XmlSerializer xmlSerializer = new XmlSerializer(obj.GetType());
                        xmlSerializer.Serialize(xw, obj);
                    }

                    xml = sw.ToString();
                }
            }
            catch (Exception) { }

            return xml;
        }

        /// <summary>
        /// Deserializes a xml string to an object
        /// </summary>
        public static Object Deserialize(String xml, Type type)
        {
            Object obj = null;

            try
            {
                if (xml != string.Empty)
                {
                    using (StringReader sr = new StringReader(xml))
                    {
                        XmlSerializer x = new XmlSerializer(type);
                        obj = x.Deserialize(sr);
                    }
                }
            }
            catch (Exception e)
            {
                throw new PageException("XmlDeserialization failed", e);
            }

            return obj;
        }

Like I said, I'm not sure if it's "good", but it works. =) Pointers appreciated!

答案 2 :(得分:0)

在Unity论坛上发布Serialize Helper,完整且完整(或多或少)。但我会保存并恢复值。我不是操纵运行时对象的粉丝有几个原因(脆弱,如果出现任何问题,我不知道什么,为什么以及在哪里,平台构建可能不可能等等)