public void CreateNewGameObject(GameObjectDataBlock dataBlock) { Debug.Log("Instantiating Raw object " + dataBlock.AssetPath); var go = new GameObject(); var saveMan = go.AddComponent<SaveManager>(); saveMan.Restore(dataBlock, true); }
/// <summary> /// Creates the game object from assetbundle or resources path. /// This call may be async in which case it will return the coroutine it works on. /// </summary> /// <returns>The game object from asset.</returns> /// <param name="dataBlock">Data block.</param> public Coroutine CreateGameObjectFromAsset(GameObjectDataBlock dataBlock) { var hook = (RequestAssetEvent)new RequestAssetEvent(dataBlock.AssetBundle, dataBlock.AssetPath, (UnityEngine.Object loadedAsset) => { Debug.Log("Instantiating asset " + dataBlock.AssetPath); var go = (GameObject)UnityEngine.Object.Instantiate(loadedAsset); Debug.Log("Restoring " + dataBlock.AssetPath); Debug.Assert(go); var sm = go.GetComponent<SaveManager>(); Debug.Assert(sm); sm.Restore(dataBlock, false); }).Call(); return hook.AssetLoadingProcess; }
/// <summary> /// Event calback. Collects all the things in saveable components into a GameObjectDataBlock. /// This is the second-most level from the top. /// The GameObjectDataBlock will then go into a list which will finally represent the savegame of a scene. /// </summary> public void OnSave(GameSavingEvent hook) { GameObjectDataBlock goBlock = new GameObjectDataBlock(uuid, gameObject.name, assetBundle, assetPath); var components = GetComponentsInChildren<Component>(); for (int i = 0; i < components.Length; ++i) { // Ignore components that are not to be saved. if (!components[i].GetType().IsDefined(typeof(SaveableComponentAttribute), true)) { continue; } var componentBlock = new ComponentDataBlock(components[i].GetType().ToString(), components[i].GetType().Assembly.GetName().Name); // Find all fields and properties that need saving. var type = components[i].GetType(); var memberSet = type.FieldsAndPropertiesWith(typeof(SaveableFieldAttribute)); for (int j = 0; j < memberSet.Count; ++j) { SaveableFieldAttribute a = memberSet[j].Attribute<SaveableFieldAttribute>(); switch (a.fieldType) { case SaveField.FIELD_PRIMITIVE: case SaveField.FIELD_SIMPLE_OBJECT: componentBlock.AddSimpleObject(memberSet[j].Name, components[i].TryGetValue(memberSet[j].Name, Flags.InstanceAnyVisibility)); break; case SaveField.FIELD_PROTOBUF_OBJECT: componentBlock.AddProtoObject(memberSet[j].Name, components[i].TryGetValue(memberSet[j].Name, Flags.InstanceAnyVisibility)); break; case SaveField.FIELD_COLOR: componentBlock.AddColor(memberSet[j].Name, (Color)components[i].TryGetValue(memberSet[j].Name, Flags.InstanceAnyVisibility)); break; case SaveField.FIELD_VECTOR_2: componentBlock.AddVector2(memberSet[j].Name, (Vector2)components[i].TryGetValue(memberSet[j].Name, Flags.InstanceAnyVisibility)); break; case SaveField.FIELD_VECTOR_3: componentBlock.AddVector3(memberSet[j].Name, (Vector3)components[i].TryGetValue(memberSet[j].Name, Flags.InstanceAnyVisibility)); break; case SaveField.FIELD_QUATERNION: componentBlock.AddQuaternion(memberSet[j].Name, (Quaternion)components[i].TryGetValue(memberSet[j].Name, Flags.InstanceAnyVisibility)); break; default: // In case we have new data types and forgot to add it here for processing Debug.LogError(memberSet[j].Name + " is of unhandled data type " + a.fieldType); break; } } goBlock.AddComponentData(componentBlock); } hook.SceneData.AddGameObjectData(goBlock); }
public void AddGameObjectData(GameObjectDataBlock data) { this.objects.Add(data); }
public void Restore(GameObjectDataBlock data, bool addComponents) { if (data == null) { Debug.LogError("Error restoring a component. Data is null!"); Destroy(this.gameObject); return; } this.uuid = data.UUID; gameObject.name = data.SceneName; this.assetPath = data.AssetPath; this.assetBundle = data.AssetBundle; if (data.ComponentList == null) { Debug.LogError("No components to restore on " + data.SceneName); return; } for (int i = 0; i < data.ComponentList.Count; ++i) { Component component = null; var componentType = Type.GetType(data.ComponentList[i].ComponentName + "," + data.ComponentList[i].AssemblyName); if (componentType == null) { Debug.LogError("Failed restoring component type " + data.ComponentList[i].ComponentName + " from assembly " + data.ComponentList[i].AssemblyName); continue; } Debug.Log("Restoring component type " + data.ComponentList[i].ComponentName + " from assembly " + data.ComponentList[i].AssemblyName); if (!typeof(Component).IsAssignableFrom(componentType)) { Debug.LogError("Restore error: " + componentType + " was expected to be a subtype of Component but isn't! Not restoring data."); continue; // Not a component :( } if (addComponents) { component = this.gameObject.AddComponent(componentType); } else { component = this.gameObject.GetComponent(componentType); if (component == null) { // try again in children because some might have their stuff deeper down the hierarchy component = this.gameObject.GetComponentInChildren(componentType); } } Debug.AssertFormat(component, "{0} is not contained on prefab or game object {0} and could not be added.", componentType, this.name); var memberSet = componentType.FieldsAndPropertiesWith(typeof(SaveableFieldAttribute)); for (int j = 0; j < memberSet.Count; ++j) { SaveableFieldAttribute a = memberSet[j].Attribute<SaveableFieldAttribute>(); switch (a.fieldType) { // Read them in as simple objects as they can be primitives or arrays of primitives. // Or they can, of course, be simple objects. case SaveField.FIELD_PRIMITIVE: case SaveField.FIELD_SIMPLE_OBJECT: component.TrySetValue(memberSet[j].Name, data.ComponentList[i].ReadSimpleObject(memberSet[j].Name), Flags.InstanceAnyVisibility); break; case SaveField.FIELD_PROTOBUF_OBJECT: component.TrySetValue(memberSet[j].Name, data.ComponentList[i].ReadProtoObject(memberSet[j].Name, memberSet[j].Type()), Flags.InstanceAnyVisibility); break; case SaveField.FIELD_VECTOR_2: component.TrySetValue(memberSet[j].Name, data.ComponentList[i].ReadVector2(memberSet[j].Name), Flags.InstanceAnyVisibility); break; case SaveField.FIELD_VECTOR_3: component.TrySetValue(memberSet[j].Name, data.ComponentList[i].ReadVector3(memberSet[j].Name), Flags.InstanceAnyVisibility); break; case SaveField.FIELD_QUATERNION: component.TrySetValue(memberSet[j].Name, data.ComponentList[i].ReadQuaternion(memberSet[j].Name), Flags.InstanceAnyVisibility); break; case SaveField.FIELD_COLOR: component.TrySetValue(memberSet[j].Name, data.ComponentList[i].ReadColor(memberSet[j].Name), Flags.InstanceAnyVisibility); break; default: // In case we have new data types and forgot to add it here for processing Debug.LogError(memberSet[j].Name + " is of unhandled data type " + a.fieldType); break; } } } }