public override void LoadGame(string path)
    {
        if (string.IsNullOrEmpty(path))
        {
            Debug.Log("[LoadGame] path is null or empty!");
            return;
        }

        //Clear the refDict, which we will need later to reconnect GameObject and Component variables with their referenced objects
        refDict = new Dictionary <RefReconnecter, string>();

        //Call the static method that will attempt to load the specified file and deserialize it's data into a form that we can use
        SaveGame loadedGame = SaveLoad.LoadLevel(path);

        if (loadedGame == null)
        {
            Debug.Log("[LoadGame] " + "Level at " + path + " couldn't be found!");
            return;
        }

        //clear the SaveLoad.objectIdentifierDict which will hold all the ObjectIdentifiers whose GameObjects will be created anew from the deserialized data, with their IDs as the keys.
        //we need this dictionary later to reconnect parents with their children (or vice versa),
        //and you might want to access it in your scripts' OnLoad function so you don't ahve to load all Ois again and again.
        SaveLoad.objectIdentifierDict = new Dictionary <string, ObjectIdentifier>();

        //iterate through the loaded SaveGame's sceneObjects list to access each stored object's data and reconstruct/unpack it with all it's components
        //Simultaneously, add the loaded GameObject's ObjectIdentifier to the SaveLoad.objectIdentifierDict.
        foreach (SceneObject loadedObject in loadedGame.sceneObjects)
        {
            GameObject go = UnpackGameObject(loadedObject, null);

            if (go != null)
            {
                //Add the reconstructed GameObject to the list we created earlier.
                ObjectIdentifier oi = go.GetComponent <ObjectIdentifier>();
                SaveLoad.objectIdentifierDict.Add(oi.id, oi);
            }
        }

        //Go through the dictionary of reconstructed GameObjects and try to reassign any missing children, and reset the localPosition
        if (true)
        {
            foreach (KeyValuePair <string, ObjectIdentifier> pair in SaveLoad.objectIdentifierDict)
            {
                ObjectIdentifier oi = pair.Value;
                if (string.IsNullOrEmpty(oi.idParent) == false)
                {
                    if (SaveLoad.objectIdentifierDict.ContainsKey(oi.idParent))
                    {
                        Vector3 pos = oi.transform.position;
                        oi.transform.parent        = SaveLoad.objectIdentifierDict[oi.idParent].transform;
                        oi.transform.localPosition = pos;
                    }
                }
            }
        }

        //Now comes a quite ugly part. It will only come into play if you have loaded any members (field or properties) that held references to GameObjects or Components.
        //Basically, when we went through each member (field/property) and it was a GameObject or Component reference,
        //this field along with the referenced object's id (and some other information) is added to refDict.
        //We now go through each key of refDict and try to find to referenced object (GameObject or Component) so we can add that value to the field or property.
        if (true)
        {
            foreach (KeyValuePair <RefReconnecter, string> pair in refDict)
            {
                RefReconnecter refRec     = pair.Key;
                object         valueToSet = new object();
                Type           fieldType  = refRec.field.FieldType;

                if (debugController.currentRefRec)
                {
                    Debug.Log("[LoadGame] " + "Current RefReconnecter: " + refRec.baseInstance.GetType().Name + "/" + refRec.field.Name + " (" + fieldType + ")");
                }

                if (refRec.collectionType == CollectionType.None)
                {
                    ObjectIdentifier oi = SaveLoad.objectIdentifierDict[pair.Value];

                    if (fieldType == typeof(GameObject))
                    {
                        valueToSet = oi.gameObject;
                    }
                    else
                    {
                        Component component = oi.GetComponent(fieldType.Name.ToString());
                        if (component != null)
                        {
                            valueToSet = component;
                        }
                    }
                }
                else
                {
                    Type elementType = TypeSystem.GetElementType(fieldType);
                    Dictionary <string, object> fieldValueDict = refRec.loadedValue as Dictionary <string, object>;

                    if (refRec.collectionType == CollectionType.Array)
                    {
                        Array array = Array.CreateInstance(elementType, fieldValueDict.Count);
                        foreach (KeyValuePair <string, object> pair_fvd in fieldValueDict)
                        {
                            if (pair_fvd.Value == null)
                            {
                                continue;
                            }
                            if (SaveLoad.objectIdentifierDict.ContainsKey(pair_fvd.Value.ToString()))
                            {
                                ObjectIdentifier oi = SaveLoad.objectIdentifierDict[pair_fvd.Value.ToString()];
                                if (elementType == typeof(GameObject))
                                {
                                    array.SetValue(oi.gameObject, Int32.Parse(pair_fvd.Key));
                                }
                                else
                                {
                                    array.SetValue(oi.GetComponent(elementType), Int32.Parse(pair_fvd.Key));
                                }
                            }
                        }
                        valueToSet = array;
                    }
                    else if (refRec.collectionType == CollectionType.List)
                    {
                        object     list          = Activator.CreateInstance(fieldType);
                        MethodInfo listAddMethod = fieldType.GetMethod("Add");

                        foreach (KeyValuePair <string, object> pair_fvd in fieldValueDict)
                        {
                            if (pair_fvd.Value == null)
                            {
                                listAddMethod.Invoke(list, new object[] { null });
                                continue;
                            }
                            if (SaveLoad.objectIdentifierDict.ContainsKey(pair_fvd.Value.ToString()))
                            {
                                ObjectIdentifier oi = SaveLoad.objectIdentifierDict[pair_fvd.Value.ToString()];
                                if (elementType == typeof(GameObject))
                                {
                                    listAddMethod.Invoke(list, new object[] { oi.gameObject });
                                }
                                else
                                {
                                    listAddMethod.Invoke(list, new object[] { oi.GetComponent(elementType) });
                                }
                            }
                        }

                        valueToSet = list;
                    }
                    else if (refRec.collectionType == CollectionType.Dictionary)
                    {
                        Type keyType   = fieldType.GetGenericArguments()[0];
                        Type valueType = fieldType.GetGenericArguments()[1];

                        bool inheritsFromComponent_keyType   = SaveLoad.InheritsFrom(keyType, typeof(Component));
                        bool inheritsFromComponent_valueType = SaveLoad.InheritsFrom(valueType, typeof(Component));

                        object     dictionary          = Activator.CreateInstance(fieldType);
                        MethodInfo dictionaryAddMethod = fieldType.GetMethod("Add", new[] { keyType, valueType });

                        ConvertedDictionary convDict = refRec.loadedValue as ConvertedDictionary;

                        for (int i = 0; i < convDict.keys.Count; i++)
                        {
                            //var newKey = Activator.CreateInstance(keyType);//Can't be used since String has no such initializer
                            object newKey = new object();

                            if (keyType.Namespace == "System" || surrogateTypes.Contains(keyType.Name))
                            {
                                newKey = convDict.keys[i.ToString()];
                            }
                            else if (keyType == typeof(GameObject) || inheritsFromComponent_keyType == true)
                            {
                                string refID = convDict.keys[i.ToString()].ToString();
                                if (SaveLoad.objectIdentifierDict.ContainsKey(refID))
                                {
                                    ObjectIdentifier oi = SaveLoad.objectIdentifierDict[refID];
                                    if (keyType == typeof(GameObject))
                                    {
                                        newKey = oi.gameObject;
                                    }
                                    else
                                    {
                                        if (oi.GetComponent(keyType) != null)
                                        {
                                            newKey = oi.GetComponent(keyType.Name);
                                        }
                                        else
                                        {
                                            Debug.Log("[LoadGame] " + "oi.GetComponent(" + keyType + ") == null");
                                        }
                                    }
                                }
                            }
                            else
                            {
                                Dictionary <string, object> keyDict = convDict.keys[i.ToString()] as Dictionary <string, object>;
                                SetValues(ref newKey, keyDict);
                            }

                            //var newValue = Activator.CreateInstance(valueType);
                            object newValue = new object();

                            if (valueType.Namespace == "System" || surrogateTypes.Contains(valueType.Name))
                            {
                                newValue = convDict.values[i.ToString()];
                            }
                            else if (valueType == typeof(GameObject) || inheritsFromComponent_valueType == true)
                            {
                                string refID = convDict.values[i.ToString()].ToString();
                                if (SaveLoad.objectIdentifierDict.ContainsKey(refID))
                                {
                                    ObjectIdentifier oi = SaveLoad.objectIdentifierDict[refID];
                                    if (valueType == typeof(GameObject))
                                    {
                                        newValue = oi.gameObject;
                                    }
                                    else
                                    {
                                        if (oi.GetComponent(valueType.Name) != null)
                                        {
                                            newValue = oi.GetComponent(valueType);
                                        }
                                        else
                                        {
                                            Debug.Log("[LoadGame] " + "oi.GetComponent(" + valueType + ") == null");
                                        }
                                    }
                                }
                            }
                            else
                            {
                                Dictionary <string, object> valueDict = convDict.values[i.ToString()] as Dictionary <string, object>;
                                SetValues(ref newValue, valueDict);
                            }

                            dictionaryAddMethod.Invoke(dictionary, new object[] { newKey, newValue });
                        }
                        valueToSet = dictionary;
                    }
                }
                if (refRec.field != null)
                {
                    refRec.field.SetValue(refRec.baseInstance, valueToSet);
                }
                else if (refRec.property != null)
                {
                    refRec.property.SetValue(refRec.baseInstance, valueToSet, null);
                }
            }
        }

        //This is when you might want to call any functions that should be called when a gameobject is loaded.
        //Remember that you can access the static SaveLoad.objectIdentifierDict from anywhere to access all the ObjectIdentifiers that were reconstructed after loading the game.
        if (true)
        {
            foreach (KeyValuePair <string, ObjectIdentifier> pair in SaveLoad.objectIdentifierDict)
            {
                pair.Value.gameObject.SendMessage("OnLoad", SendMessageOptions.DontRequireReceiver);
            }
        }

        if (debugController.gameLoaded)
        {
            //Debug.Log("Game Loaded: " + loadedGame.savegameName + " (" + loadedGame.saveDate + ").");
        }
    }