Пример #1
0
        protected T Write <T>(T dst, PersistentData src, Dictionary <long, UnityObject> objects)
        {
            if (src == null)
            {
                return(default(T));
            }

            if (dst == null)
            {
                try
                {
                    dst = Activator.CreateInstance <T>();
                }
                catch (MissingMethodException)
                {
                    Debug.LogWarningFormat("Unable to instantiate object. {0} default constructor missing", typeof(T).FullName);
                }
            }

            return((T)src.WriteTo(dst, objects));
        }
Пример #2
0
        public static void RestoreDataAndResolveDependencies(PersistentData[] dataObjects, Dictionary <long, UnityObject> objects)
        {
            //3. Create persistent data dictionary (new object id -> Persistent Data)
            Dictionary <UnityObject, PersistentData> persistentData = new Dictionary <UnityObject, PersistentData>();

            for (int i = 0; i < dataObjects.Length; ++i)
            {
                PersistentData data = dataObjects[i];

                UnityObject obj;
                if (objects.TryGetValue(data.InstanceId, out obj))
                {
                    persistentData.Add(obj, data);
                }
            }

            //4. Create replacement prefabs and replace PersistentIgnoreObjects
            foreach (KeyValuePair <UnityObject, PersistentData> kvp in persistentData)
            {
                PersistentIgnore persistentIgnore = kvp.Key as PersistentIgnore;
                if (persistentIgnore == null)
                {
                    continue;
                }

                GameObject go = persistentIgnore.gameObject;

                PersistentData goData        = persistentData[go];
                PersistentData scriptData    = kvp.Value;
                PersistentData transformData = persistentData[go.transform];

                //Recover go data
                goData.WriteTo(go, objects);

                //Recover script data
                scriptData.WriteTo(persistentIgnore, objects);

                //Recover transform data
                transformData.WriteTo(go.transform, objects);

                /*
                 * if (persistentIgnore.ReplacementPrefab != null)
                 * {
                 *  //make sure that Replacement prefab is not active,
                 *  //this will prevent Awake and other methods from running too early
                 *  persistentIgnore.ReplacementPrefab.gameObject.SetActive(false);
                 *
                 *  PersistentIgnore replacementScript = UnityObject.Instantiate(persistentIgnore.ReplacementPrefab);
                 *  List<GameObject> destroy = new List<GameObject>();
                 *  //Destroy prefab children according to PersistentIgnore component settings
                 *  foreach (Transform childTransform in replacementScript.transform)
                 *  {
                 *      if (!replacementScript.IsChildOfReplacementPrefab(childTransform))
                 *      {
                 *          destroy.Add(childTransform.gameObject);
                 *      }
                 *  }
                 *  for (int i = 0; i < destroy.Count; ++i)
                 *  {
                 *      UnityObject.DestroyImmediate(destroy[i]);
                 *  }
                 *
                 *  //replace gameObject with repacementPrefab in objects dictionary
                 *  //Thereby all other objects will reference replacementPrefab instad of gameObject
                 *  objects[goData.InstanceId] = replacementScript.gameObject;
                 *  objects[scriptData.InstanceId] = replacementScript;
                 *  objects[transformData.InstanceId] = replacementScript.transform;
                 *
                 *  //insert replacementPrefab to hierarchy
                 *  replacementScript.transform.SetParent(go.transform.parent);
                 *  foreach (Transform childTransform in go.transform)
                 *  {
                 *      childTransform.SetParent(replacementScript.transform);
                 *  }
                 *
                 *  UnityObject.Destroy(go); //Destroy gameObject which was replaced by replacement Prefab
                 * }
                 */
            }

            List <GameObject> goList           = new List <GameObject>();
            List <bool>       goActivationList = new List <bool>();

            //5. Recover data using scene.Data
            for (int i = 0; i < dataObjects.Length; ++i)
            {
                PersistentData data = dataObjects[i];
                if (!objects.ContainsKey(data.InstanceId))
                {
                    Debug.LogWarningFormat("objects does not have object with instance id {0} however PersistentData of type {1} is present", data.InstanceId, data.GetType());
                    continue;
                }

                UnityObject obj = objects[data.InstanceId];
                data.WriteTo(obj, objects);

                if (obj is GameObject)
                {
                    goList.Add((GameObject)obj);
                    goActivationList.Add(data.ActiveSelf);
                }
            }

            for (int i = 0; i < goList.Count; ++i)
            {
                bool       activeSelf = goActivationList[i];
                GameObject go         = goList[i];
                go.SetActive(activeSelf);
            }
        }
Пример #3
0
        public override object WriteTo(object obj, Dictionary <long, UnityObject> objects)
        {
            obj = base.WriteTo(obj, objects);

            if (baseObjectData != null)
            {
                //prevent name to be overriden with name stored m_baseObjectData.name
                PersistentObjects.PersistentObject persistentObj = baseObjectData.AsPersistentObject;
                if (persistentObj != null)
                {
                    persistentObj.name = name;
                }
                baseObjectData.WriteTo(obj, objects);
            }

            Type type = obj.GetType();

            if (!type.IsScript())
            {
                throw new ArgumentException(string.Format("obj of type {0} is not subclass of {1}", type, typeof(MonoBehaviour)), "obj");
            }

            do
            {
                FieldInfo[] fields = type.GetSerializableFields();
                for (int i = 0; i < fields.Length; ++i)
                {
                    FieldInfo field = fields[i];
                    string    name  = field.Name;
                    if (!this.fields.ContainsKey(field.Name))
                    {
                        FormerlySerializedAsAttribute formelySerializedAs = field.GetCustomAttributes(typeof(FormerlySerializedAsAttribute), false).FirstOrDefault() as FormerlySerializedAsAttribute;
                        if (formelySerializedAs == null)
                        {
                            continue;
                        }
                        name = formelySerializedAs.oldName;
                        if (!this.fields.ContainsKey(name))
                        {
                            continue;
                        }
                    }

                    bool isArray   = field.FieldType.IsArray;
                    Type fieldType = field.FieldType;
                    if (isArray)
                    {
                        fieldType = fieldType.GetElementType();
                    }

                    DataContract value = this.fields[name];
                    if (fieldType.IsSubclassOf(typeof(UnityObject)) || fieldType == typeof(UnityObject))
                    {
                        if (isArray)
                        {
                            if (value.AsPrimitive == null)
                            {
                                continue;
                            }

                            if (!(value.AsPrimitive.ValueBase is long[]))
                            {
                                continue;
                            }

                            long[] instanceIds = (long[])value.AsPrimitive.ValueBase;
                            Array  objectsFoundByInstanceId = Array.CreateInstance(fieldType, instanceIds.Length);
                            for (int j = 0; j < instanceIds.Length; ++j)
                            {
                                object o = objects.Get(instanceIds[j]);
                                objectsFoundByInstanceId.SetValue(o, j);
                            }
                            field.SetValue(obj, objectsFoundByInstanceId);
                        }
                        else
                        {
                            if (value.AsPrimitive == null)
                            {
                                continue;
                            }
                            if (!(value.AsPrimitive.ValueBase is long))
                            {
                                continue;
                            }

                            long instanceId = (long)value.AsPrimitive.ValueBase;
                            if (!objects.ContainsKey(instanceId))
                            {
                                continue;
                            }

                            object objectFoundByInstanceId = objects[instanceId];
                            try
                            {
                                field.SetValue(obj, objectFoundByInstanceId);
                            }
                            catch
                            {
                                Debug.LogError(instanceId);
                                throw;
                            }
                        }
                    }
                    else
                    {
                        if (value == null)
                        {
                            if (field.FieldType.IsValueType())
                            {
                                continue;
                            }
                            field.SetValue(obj, value);
                        }
                        else
                        {
                            if (field.FieldType.IsSubclassOf(typeof(UnityEventBase)))
                            {
                                if (value.AsUnityEvent == null)
                                {
                                    continue;
                                }
                                PersistentUnityEventBase persistentUnityEvent = value.AsUnityEvent;
                                UnityEventBase           unityEvent           = (UnityEventBase)Activator.CreateInstance(field.FieldType);
                                persistentUnityEvent.WriteTo(unityEvent, objects);
                                field.SetValue(obj, unityEvent);
                            }
                            else
                            {
                                if (!field.FieldType.IsEnum())
                                {
                                    object fieldValue;
                                    if (field.FieldType.IsPrimitive() || field.FieldType.IsArray())
                                    {
                                        PrimitiveContract primitive = value.AsPrimitive;
                                        if (primitive == null ||
                                            primitive.ValueBase == null && field.FieldType.IsValueType() ||
                                            primitive.ValueBase != null && !field.FieldType.IsAssignableFrom(primitive.ValueBase.GetType()))
                                        {
                                            continue;
                                        }
                                        fieldValue = primitive.ValueBase;
                                    }
                                    else
                                    {
                                        fieldValue = value.Data;
                                    }

                                    field.SetValue(obj, fieldValue);
                                    if (fieldValue is IEnumerable)
                                    {
                                        IEnumerable enumerable = (IEnumerable)fieldValue;
                                        foreach (object o in enumerable)
                                        {
                                            if (o is IRTSerializable)
                                            {
                                                IRTSerializable rtSerializable = (IRTSerializable)o;
                                                rtSerializable.Deserialize(objects);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        if (fieldValue is IRTSerializable)
                                        {
                                            IRTSerializable rtSerializable = (IRTSerializable)fieldValue;
                                            rtSerializable.Deserialize(objects);
                                        }
                                    }
                                }
                                else// if (field.FieldType.IsEnum)
                                {
                                    PrimitiveContract primitive = value.AsPrimitive;
                                    if (primitive == null ||
                                        primitive.ValueBase == null && field.FieldType.IsValueType() ||
                                        primitive.ValueBase != null && primitive.ValueBase.GetType() != typeof(uint))
                                    {
                                        continue;
                                    }

                                    var val = Enum.ToObject(field.FieldType, primitive.ValueBase);
                                    field.SetValue(obj, val);
                                }
                            }
                        }
                    }
                }
                type = type.BaseType();
            }while (type.IsScript());

            return(obj);
        }