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); }
/// <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); }
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 }