private void Initialize(BundleResourceMap resourceMap)
        {
            if (resourceMap == null)
            {
                Debug.LogWarning("ResourceMap is null. Create Resource map using Tools->Runtime SaveLoad->Create Resource Map menu item");
                return;
            }
            m_idToId   = new Dictionary <int, int>();
            m_instance = this;

            ResourceGroup[] allGroups   = Resources.FindObjectsOfTypeAll <ResourceGroup>();
            ResourceGroup[] sceneGroups = allGroups.Where(rg => !rg.gameObject.IsPrefab()).ToArray();

            ResourceGroup[] resourceGroups = resourceMap.GetComponentsInChildren <ResourceGroup>();
            if (resourceGroups.Length == 0)
            {
                Debug.LogWarning("No resource groups found. Create Resource map using Tools->Runtime SaveLoad->Create Resource Map menu item");
                return;
            }

            for (int j = 0; j < resourceGroups.Length; ++j)
            {
                ResourceGroup group           = resourceGroups[j];
                bool          ignoreConflicts = true;
                LoadMappings(group, ignoreConflicts);
            }


            for (int i = 0; i < sceneGroups.Length; ++i)
            {
                ResourceGroup group = sceneGroups[i];
                LoadMappings(group);
            }
        }
        public static void Internal_Initialize(BundleResourceMap bundleResourceMap)
        {
            m_instance = null;
            IdentifiersMap resourceMap = new IdentifiersMap();

            resourceMap.Initialize(bundleResourceMap);
        }
예제 #3
0
        /// <summary>
        /// Create GameObjects with Components using data from PersistentScene object
        /// </summary>
        /// <param name="scene">PersistentScene</param>
        public static void InstantiateGameObjects(PersistentScene scene)
        {
            if (IdentifiersMap.Instance == null)
            {
                Debug.LogError("Create Runtime Resource Map");
                return;
            }

            DestroyGameObjects();
            if (scene.Data == null && scene.Descriptors == null)
            {
                return;
            }

            if (scene.Data == null && scene.Descriptors != null || scene.Data != null && scene.Descriptors == null)
            {
                throw new ArgumentException("data is corrupted", "scene");
            }

            if (scene.Descriptors.Length == 0)
            {
                return;
            }


            bool includeDynamicResources = true;
            //1. Find prefabs and other resources;
            Dictionary <long, UnityObject> resources = IdentifiersMap.FindResources(includeDynamicResources);

            PersistentDescriptor.GetOrCreateGameObjects(scene.Descriptors, resources /*, scene.ActiveSelf*/);
            PersistentData.RestoreDataAndResolveDependencies(scene.Data, resources);
        }
예제 #4
0
        private static void CreateResourceMapInternal(bool verbose)
        {
            DateTime start = DateTime.Now;

            if (verbose)
            {
                Debug.Log("[ResourceMapGen] Creating Resource Map... ");
            }

            Assembly unityEditor = typeof(Editor).Assembly;

            string[] assetPaths = AssetDatabase.GetAllAssetPaths();

            Dictionary <string, BundleResourceMapData> objectsPerBundle = new Dictionary <string, BundleResourceMapData>();
            BundleResourceMapData allResourceMapData = new BundleResourceMapData();
            BundleResourceMapData notBundledObjects  = new BundleResourceMapData();

            objectsPerBundle.Add(bundleNameDelimiter, notBundledObjects);

            bool hasBundledAssets = false;

            //searching for objects
            foreach (string path in assetPaths)
            {
                if (PathHelper.IsPathRooted(path))
                {
                    Debug.Log("Path is rooted " + path + ". skip...");
                    continue;
                }
                UnityObject obj = AssetDatabase.LoadAssetAtPath(path, typeof(UnityObject));
                if (obj == null)
                {
                    continue;
                }

                AssetImporter         importer       = AssetImporter.GetAtPath(path);
                string                bundleName     = importer.assetBundleName;
                bool                  isBundledAsset = !string.IsNullOrEmpty(bundleName);
                BundleResourceMapData resourceMapData;
                if (isBundledAsset)
                {
                    hasBundledAssets = true;

                    string bundleNameAndVariant = importer.assetBundleName + bundleNameDelimiter + importer.assetBundleVariant;
                    if (!objectsPerBundle.TryGetValue(bundleNameAndVariant, out resourceMapData))
                    {
                        resourceMapData = new BundleResourceMapData();
                        objectsPerBundle.Add(bundleNameAndVariant, resourceMapData);
                    }
                }
                else
                {
                    resourceMapData = notBundledObjects;
                }

                if (obj is GameObject)
                {
                    GameObject go = (GameObject)obj;
                    if (go.GetComponent <BundleResourceMap>() != null)
                    {
                        continue;
                    }
                }

                if (obj.GetType().Assembly != unityEditor || obj.GetType() == typeof(UnityEditor.Animations.AnimatorController))
                {
                    if (!allResourceMapData.Objects.Contains(obj))
                    {
                        resourceMapData.Objects.Add(obj);
                        allResourceMapData.Objects.Add(obj);
                    }
                }

                foreach (UnityObject sub in AssetDatabase.LoadAllAssetRepresentationsAtPath(path))
                {
                    if (sub == null)
                    {
                        continue;
                    }
                    if (sub.GetType().Assembly == unityEditor)
                    {
                        continue;
                    }

                    if (!allResourceMapData.Objects.Contains(sub))
                    {
                        resourceMapData.Objects.Add(sub);
                        allResourceMapData.Objects.Add(sub);
                        TryAddMaterialShader(sub, resourceMapData);
                    }
                }

                TryAddMaterialShader(obj, resourceMapData);
            }

            foreach (BundleResourceMapData resourceMapData in objectsPerBundle.Values)
            {
                if (resourceMapData == notBundledObjects)
                {
                    continue;
                }

                for (int i = 0; i < m_builtInResources.Length; ++i)
                {
                    GameObject obj = AssetDatabase.LoadAssetAtPath <GameObject>(m_builtInResources[i]);
                    if (obj == null)
                    {
                        continue;
                    }
                    Material[] materials = obj.GetComponent <Renderer>().sharedMaterials;
                    foreach (Material material in materials)
                    {
                        if (!resourceMapData.Objects.Contains(material))
                        {
                            resourceMapData.Objects.Add(material);

                            //do not add to allResourceMapData. Built-in material could be added to serveral resource maps.
                        }

                        if (material.shader != null)
                        {
                            if (!resourceMapData.Objects.Contains(material.shader))
                            {
                                resourceMapData.Objects.Add(material.shader);

                                //do not add to allResourceMapData. Built-in shader could be added to serveral resource maps.
                            }
                        }
                    }

                    //Mesh mesh = obj.GetComponent<MeshFilter>().sharedMesh;
                    //if (!resourceMapData.Objects.Contains(mesh))
                    //{
                    //    resourceMapData.Objects.Add(mesh);
                    //}
                }
            }

            HashSet <UnityObject> builtInResources = new HashSet <UnityObject>();

            for (int i = 0; i < m_builtInResources.Length; ++i)
            {
                GameObject obj = AssetDatabase.LoadAssetAtPath <GameObject>(m_builtInResources[i]);
                if (obj == null)
                {
                    continue;
                }
                Material[] materials = obj.GetComponent <Renderer>().sharedMaterials;
                foreach (Material material in materials)
                {
                    if (!allResourceMapData.Objects.Contains(material))
                    {
                        notBundledObjects.Objects.Add(material);
                        allResourceMapData.Objects.Add(material);
                    }

                    if (material.shader != null)
                    {
                        if (!allResourceMapData.Objects.Contains(material.shader))
                        {
                            notBundledObjects.Objects.Add(material.shader);
                            allResourceMapData.Objects.Add(material.shader);
                        }
                    }
                }
                Mesh mesh = obj.GetComponent <MeshFilter>().sharedMesh;
                if (!allResourceMapData.Objects.Contains(mesh))
                {
                    notBundledObjects.Objects.Add(mesh);
                    builtInResources.Add(mesh);
                    allResourceMapData.Objects.Add(mesh);
                }
            }

            GameObject[] rootSceneObjects = Resources.FindObjectsOfTypeAll <GameObject>()
                                            .Where(go => !go.IsPrefab() &&
                                                   go.transform.parent == null &&
                                                   go.hideFlags == HideFlags.None).ToArray();

            List <UnityObject> persistentIgnoreObjects = new List <UnityObject>();

            for (int i = 0; i < rootSceneObjects.Length; ++i)
            {
                FindPersistentIgnoreObjects(rootSceneObjects[i].transform, persistentIgnoreObjects);
            }

            //processing objects
            foreach (BundleResourceMapData data in objectsPerBundle.Values)
            {
                foreach (UnityObject obj in data.Objects)
                {
                    if (obj == null)
                    {
                        continue;
                    }

                    if ((obj.hideFlags & HideFlags.DontSaveInBuild) != 0)
                    {
                        if (!builtInResources.Contains(obj))
                        {
                            continue;
                        }
                    }

                    GroupDescriptor descriptor = data.GroupsDict[typeof(UnityObject)];
                    Type            type       = obj.GetType();
                    while (type != typeof(object))
                    {
                        if (data.GroupsDict.TryGetValue(type, out descriptor))
                        {
                            descriptor = data.GroupsDict[type];
                            break;
                        }
                        type = type.BaseType;
                    }

                    if (obj is GameObject)
                    {
                        GameObject prefab = (GameObject)obj;
                        if (PrefabUtility.FindPrefabRoot(prefab) == obj)
                        {
                            descriptor.Objects.Add(prefab);
                        }
                    }
                    else if (obj is Component)
                    {
                        continue;
                    }
                    else
                    {
                        descriptor.Objects.Add(obj);
                    }
                }
            }

            BundleResourceMap[] bundleResourceMaps     = Resources.FindObjectsOfTypeAll <BundleResourceMap>();
            HashSet <Guid>      bundleResourceMapGuids = new HashSet <Guid>(bundleResourceMaps.Select(m => new Guid(m.Guid)));

            ResourceMap[] resourceMaps = bundleResourceMaps.OfType <ResourceMap>().ToArray();
            if (resourceMaps.Length > 1)
            {
                if (verbose)
                {
                    Debug.LogError("You have more than one ResourceMap");
                }
            }

            ResourceMap mainResourceMap;
            Dictionary <string, BundleResourceMap> bundleResourceMapDict = new Dictionary <string, BundleResourceMap>();

            {
                mainResourceMap = resourceMaps.OrderByDescending(m => m.GetCounter()).FirstOrDefault();
                if (mainResourceMap == null)
                {
                    GameObject mapGO = new GameObject();
                    mapGO.name      = "Resource Map";
                    mainResourceMap = mapGO.AddComponent <ResourceMap>();
                }
                else
                {
                    GameObject resourceMapGO = UnityObject.Instantiate(mainResourceMap.gameObject);
                    resourceMapGO.transform.SetParent(mainResourceMap.transform.parent, false);

                    if (!mainResourceMap.gameObject.IsPrefab())
                    {
                        Undo.DestroyObjectImmediate(mainResourceMap.gameObject);
                    }

                    resourceMapGO.name = "Resource Map";
                    mainResourceMap    = resourceMapGO.GetComponent <ResourceMap>();
                }

                bundleResourceMapDict.Add(bundleNameDelimiter, mainResourceMap);
            }


            for (int i = 0; i < bundleResourceMaps.Length; ++i)
            {
                BundleResourceMap bundleResourceMap = bundleResourceMaps[i];
                string            key = bundleResourceMap.BundleName + bundleNameDelimiter + bundleResourceMap.VariantName;
                if (!bundleResourceMapDict.ContainsKey(key))
                {
                    GameObject bundleResourceMapGO = UnityObject.Instantiate(bundleResourceMap.gameObject);
                    bundleResourceMapGO.transform.SetParent(bundleResourceMap.transform.parent, false);

                    if (!bundleResourceMap.gameObject.IsPrefab())
                    {
                        Undo.DestroyObjectImmediate(bundleResourceMap.gameObject);
                    }

                    bundleResourceMapGO.name = "Resource Map " + key.Replace(bundleNameDelimiter, "_");
                    bundleResourceMap        = bundleResourceMapGO.GetComponent <BundleResourceMap>();
                    bundleResourceMapDict.Add(key, bundleResourceMap);
                }
            }

            ResourceGroup[] allResourceGroups = Resources.FindObjectsOfTypeAll <ResourceGroup>().Where(r => !r.gameObject.IsPrefab()).ToArray();
            ResourceGroup[] destroyGroups     = allResourceGroups.Where(r => string.IsNullOrEmpty(r.Guid) || !bundleResourceMapGuids.Contains(new Guid(r.Guid))).ToArray();
            for (int i = 0; i < destroyGroups.Length; ++i)
            {
                UnityObject.DestroyImmediate(destroyGroups[i]);
            }

            if (!AssetDatabase.IsValidFolder("Assets/" + ResourceMapsPath))
            {
                AssetDatabase.CreateFolder("Assets/" + RootFolder, ResourceMapsFolder);
            }
            if (!AssetDatabase.IsValidFolder("Assets/" + ResourceMapsPath + "/Resources"))
            {
                AssetDatabase.CreateFolder("Assets/" + ResourceMapsPath, "Resources");
            }

            foreach (KeyValuePair <string, BundleResourceMapData> keyBundleResourceMapData in objectsPerBundle)
            {
                BundleResourceMap bundleResourceMap;
                if (!bundleResourceMapDict.TryGetValue(keyBundleResourceMapData.Key, out bundleResourceMap))
                {
                    GameObject bundleResourceMapGO = new GameObject();
                    bundleResourceMapGO.name = "Resource Map" + keyBundleResourceMapData.Key.Replace(bundleNameDelimiter, "_");
                    bundleResourceMap        = bundleResourceMapGO.AddComponent <BundleResourceMap>();
                    string[] bundleNameAndVariant = keyBundleResourceMapData.Key.Split(new[] { bundleNameDelimiter }, StringSplitOptions.None);
                    bundleResourceMap.BundleName  = bundleNameAndVariant[0];
                    bundleResourceMap.VariantName = bundleNameAndVariant[1];
                    bundleResourceMapDict.Add(keyBundleResourceMapData.Key, bundleResourceMap);
                }

                Guid            bundleResourceMapGuid          = new Guid(bundleResourceMap.Guid);
                ResourceGroup[] resourceGroups                 = allResourceGroups.Where(r => !string.IsNullOrEmpty(r.Guid) && new Guid(r.Guid) == bundleResourceMapGuid).ToArray();
                Dictionary <UnityObject, int> extistingMapping = ToDictionary(resourceGroups);
                if (verbose)
                {
                    Debug.Log("[ResourceMapGen] " + keyBundleResourceMapData.Key + " Existing Mappings = " + extistingMapping.Count);
                }

                DestroyChildren(bundleResourceMap.gameObject.transform);
                Undo.RegisterCreatedObjectUndo(bundleResourceMap.gameObject, "Battlehub.RTSaveLoad.ResourceMapGen");

                BundleResourceMapData resourceMapData = keyBundleResourceMapData.Value;
                PopulateRootGroups(mainResourceMap, bundleResourceMap, resourceMapData.GroupsDict.Where(kvp => kvp.Key != typeof(GameObject)).Select(kvp => kvp.Value), extistingMapping);

                GroupDescriptor prefabs = resourceMapData.GroupsDict[typeof(GameObject)];
                PopulatePrefabsGroup(mainResourceMap, bundleResourceMap, prefabs, extistingMapping);

                if (bundleResourceMap == mainResourceMap)
                {
                    CreatePersistentIngoreResourceGroups(mainResourceMap, persistentIgnoreObjects, extistingMapping);
                    OrderTransformsByName(bundleResourceMap.transform);
                }
                else
                {
                    OrderTransformsByName(bundleResourceMap.transform);
                    CreateResourceMapPrefab(verbose, "_" + keyBundleResourceMapData.Key.Replace(bundleNameDelimiter, "_") + "_" + bundleResourceMap.Guid, bundleResourceMap);
                }
            }

            CreateResourceMapPrefab(verbose, string.Empty, mainResourceMap);

            if (verbose)
            {
                Debug.Log("[ResourceMapGen] Max ID: " + mainResourceMap.GetCounter());
            }
            if (verbose)
            {
                Debug.Log("[ResourceMapGen] Resource Map Created... Elapsed Time " + (DateTime.Now - start).TotalMilliseconds + " ms ");
            }

            foreach (KeyValuePair <string, BundleResourceMap> kvp in bundleResourceMapDict)
            {
                BundleResourceMap bundleResourceMap = kvp.Value;
                GameObject        mapGO             = bundleResourceMap.gameObject;

                UnityObject.DestroyImmediate(bundleResourceMap);
                UnityObject.DestroyImmediate(mapGO);
            }

            BundleResourceMap[] maps = Resources.FindObjectsOfTypeAll <BundleResourceMap>();
#if UNITY_EDITOR
            foreach (BundleResourceMap bundleResourceMap in maps)
            {
                IdentifiersMap.Internal_Initialize(bundleResourceMap);
                RuntimeShaderInfoGen.RemoveUnused(bundleResourceMap.BundleName, bundleResourceMap.VariantName);
            }

            Dictionary <BundleResourceMap, Shader[]> m_shaders = new Dictionary <BundleResourceMap, Shader[]>();
            foreach (BundleResourceMap bundleResourceMap in maps)
            {
                IdentifiersMap.Internal_Initialize(bundleResourceMap);
                Shader[] shaders = RuntimeShaderInfoGen.Create(bundleResourceMap.BundleName, bundleResourceMap.VariantName);
                m_shaders.Add(bundleResourceMap, shaders);
            }

            AssetDatabase.Refresh();

            foreach (BundleResourceMap bundleResourceMap in maps)
            {
                IdentifiersMap.Internal_Initialize(bundleResourceMap);
                RuntimeShaderInfoGen.SetAssetBundleNameAndVariant(m_shaders[bundleResourceMap], bundleResourceMap.BundleName, bundleResourceMap.VariantName);
            }

            if (hasBundledAssets)
            {
                Debug.Log("Project has bundled assets. Build All Asset Bundles. Done.");
                CreateAssetBundles.BuildAllAssetBundles();
            }
#endif
        }