private bool DetargetLateAttributeField(object obj, FieldInfo field) { FieldInfo targetField; if (IsLateAttributeField(obj, field, out targetField, true)) { if (ScanningUtils.IsSerializableArray(field.FieldType)) { IList referencesArray = (IList)field.GetValue(obj); var idsArray = new string[referencesArray.Count]; for (int i = 0; i < referencesArray.Count; i++) { UnityEngine.Object val = (UnityEngine.Object)referencesArray[i]; idsArray[i] = AssetId.FromObject(val); referencesArray[i] = null; } targetField.SetValue(obj, (object)idsArray); } else { UnityEngine.Object val = (UnityEngine.Object)field.GetValue(obj); targetField.SetValue(obj, (object)AssetId.FromObject(val)); field.SetValue(obj, null); } return(true); } return(false); }
private void CreateLateResources(IList <UnityEngine.Object> objects) { const string lateResourcesDirectory = "Assets/Resources/Late"; BuildUtils.PrepareCleanDirectory(lateResourcesDirectory); foreach (var obj in ScanningUtils.ItemsProcessor(objects, "Creating late resources", p => AssetDatabase.GetAssetPath(p))) { var lateResource = ScriptableObject.CreateInstance <LateResource>(); lateResource.Target = obj; AssetDatabase.CreateAsset(lateResource, lateResourcesDirectory + "/" + AssetId.FromObject(obj) + ".asset"); } }
public void Dispose() { var idMap = new Dictionary <string, UnityEngine.Object>(); foreach (var obj in _referencedObjects) { idMap.Add(AssetId.FromObject(obj), obj); } AssetId.CurrentResolver = (id, type) => { var asset = idMap[id]; if (type.IsAssignableFrom(asset.GetType())) { return(asset); } throw new UnityException(); }; try { foreach (var obj in _processedObjects) { RetargetObject(obj); } } catch (Exception e) { Debug.LogError("Unrecoverable error during late reference restore, close Unity without saving anything"); throw e; } finally { AssetId.CurrentResolver = null; AssetId.CurrentGenerator = AssetId.DefaultGenerator; } GC.SuppressFinalize(this); }
private void PackBundles() { var referencedObjects = new HashSet <UnityEngine.Object>(_lateProcessor.ReferencedObjects); var packedObjects = new HashSet <UnityEngine.Object>(); var tempPath = Path.Combine(Path.GetTempPath(), "bundles_" + DateTime.UtcNow.Ticks.ToString()); BuildUtils.PrepareCleanDirectory(tempPath); PushAssetDependencies(); { foreach (var bundleInfo in ScanningUtils.ItemsProcessor(_bundles, "Packing asset bundles", p => Path.GetFileName(p.Name), true)) { Console.WriteLine("Building bundle " + bundleInfo.Name + "..."); string bundlePath = Path.Combine(tempPath, bundleInfo.Name); //BuildUtils.GetPathHashString(bundleInfo.Name)); if (bundleInfo.IsScene) { var scenePaths = bundleInfo.AssetsPaths.ToArray(); PushAssetDependencies(); { string buildResult = BuildPipeline.BuildStreamedSceneAssetBundle(scenePaths, bundlePath, _params.Target); if (!String.IsNullOrEmpty(buildResult)) { throw new UnityException(buildResult); } } PopAssetDependencies(); // Find which assets were packed var packedDependencies = new HashSet <UnityEngine.Object>(); foreach (var scenePath in scenePaths) { Debug.Log(scenePath); EditorApplication.OpenScene(scenePath); packedDependencies.UnionWith(ScanningUtils.ScanCurrentSceneAssets()); packedDependencies.ExceptWith(packedObjects); } bundleInfo.Dependencies = packedDependencies.ToList(); var hash = GetHashForBuildAssets(scenePaths.Concat(BuildUtils.GetAssetPathsForObjects(packedDependencies))); int bundleLevel = _bundleLevelDataBase.GetBundleLevel(bundleInfo.Name); bundleInfo.Data = _bundlesDatabaseBuilder.AddSceneBundle(bundleInfo.Name, hash, bundleLevel, scenePaths.Select(p => Path.GetFileNameWithoutExtension(p)).ToArray(), bundlePath); } else { // Add only the main asset + any late referenced asset var mainObjects = bundleInfo.AssetsPaths.Select(p => AssetDatabase.LoadMainAssetAtPath(p)); var representations = bundleInfo.AssetsPaths.SelectMany(p => AssetDatabase.LoadAllAssetRepresentationsAtPath(p)); var objects = mainObjects.Concat(representations.Where(o => referencedObjects.Contains(o))).ToArray(); var assetIds = objects.Select(o => AssetId.FromObject(o)).ToArray(); foreach (var obj in objects) { string assetPath = AssetDatabase.GetAssetPath(obj); string guid = AssetDatabase.AssetPathToGUID(assetPath); Console.WriteLine("path: " + assetPath + " guid:" + guid); } if (bundleInfo.Isolate) { PushAssetDependencies(); } { if (!BuildPipeline.BuildAssetBundleExplicitAssetNames(objects, assetIds, bundlePath, BuildAssetBundleOptions.CompleteAssets | BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.DeterministicAssetBundle, _params.Target)) { throw new UnityException("Error building bundle " + bundleInfo.Name); } } if (bundleInfo.Isolate) { PopAssetDependencies(); } // Find which assets were packed var packedDependencies = new HashSet <UnityEngine.Object>(EditorUtility.CollectDependencies(objects.ToArray())); packedDependencies.ExceptWith(packedObjects); bundleInfo.Dependencies = packedDependencies.ToList(); if (!bundleInfo.Isolate) { packedObjects.UnionWith(packedDependencies); } var hash = GetHashForBuildAssets(BuildUtils.GetAssetPathsForObjects(packedDependencies)); int bundleLevel = _bundleLevelDataBase.GetBundleLevel(bundleInfo.Name); bundleInfo.Data = _bundlesDatabaseBuilder.AddBundle(bundleInfo.Name, hash, bundleLevel, bundlePath, assetIds.ToList()); foreach (var obj in objects) { referencedObjects.Remove(obj); } } } } PopAssetDependencies(); // Move to right destination Directory.CreateDirectory(_params.BundlesLocation); _bundlesPath = Path.Combine(_params.BundlesLocation, _bundlesDatabaseBuilder.Database.Id); FileUtil.DeleteFileOrDirectory(_bundlesPath); FileUtil.MoveFileOrDirectory(tempPath, _bundlesPath); // To create late reference for any late object not added to bundles _objectsToLateReference = referencedObjects.ToList(); }