static bool IsEditable(Asset asset, AssetGroupViewData failures) { if (asset.readOnly || asset.locked) { failures.AddEntry(asset.path, $"readOnly = {asset.readOnly}, locked = {asset.locked}"); return(false); } // do not append to failures if it is a readonly package var packageInfo = UnityEditor.PackageManager.PackageInfo.FindForAssetPath(asset.assetPath); return(packageInfo == null || packageInfo.source == PackageSource.Embedded || packageInfo.source == PackageSource.Local); }
static bool IsEditable(AssetList assetList, AssetGroupViewData failures) { if (!Provider.enabled || !Provider.isActive || !Provider.CheckoutIsValid(assetList, CheckoutMode.Both)) { return(true); } var task = Provider.Checkout(assetList, CheckoutMode.Both); task.Wait(); if (!task.success) { foreach (var asset in assetList) { failures.AddEntry(asset.assetPath, "Checkout from version control failed."); } return(false); } return(true); }
static void UpgradePrefabAsset(Asset asset, AssetList prefabsWithShapes, ICollection <Asset> upgradedAssets, AssetGroupViewData successes, AssetGroupViewData failures ) { // exit if we have already upgraded the asset (e.g. it is a parent and we already upgraded it via a variant) if (upgradedAssets.Contains(asset)) { return; } upgradedAssets.Add(asset); // exit if it is a prefab parent that doesn't actually have any shapes if (!prefabsWithShapes.Contains(asset)) { return; } GameObject prefab = null; try { prefab = PrefabUtility.LoadPrefabContents(asset.path); } catch (Exception e) { failures.AddEntry(asset.path, $"{e.Message}\n\n{e.StackTrace}"); return; } // if the prefab is a variant, ensure the prefab it inherits is upgraded first if (PrefabUtility.GetPrefabAssetType(prefab) == PrefabAssetType.Variant) { var sourcePrefab = PrefabUtility.GetCorrespondingObjectFromSource(prefab); var sourceAsset = new Asset(AssetDatabase.GetAssetPath(sourcePrefab)); UpgradePrefabAsset(sourceAsset, prefabsWithShapes, upgradedAssets, successes, failures); } // next upgrade any nested prefabs foreach ( var rootAsset in prefab.GetComponentsInChildren <Transform>(true) .Select(PrefabUtility.GetNearestPrefabInstanceRoot) .Where(r => r != null && r != prefab) // skip if the child is not a nested prefab .Select(r => new Asset(AssetDatabase.GetAssetPath(r))) .Where(r => prefabsWithShapes.Any(a => a.assetPath == r.assetPath)) // skip if the nested prefab isn't one with a shape ) { UpgradePrefabAsset(rootAsset, prefabsWithShapes, upgradedAssets, successes, failures); } bool success = true; try { UpgradePrefabInstance(prefab); PrefabUtility.SaveAsPrefabAsset(prefab, asset.path); } catch (Exception e) { failures.AddEntry(asset.path, $"{e.Message}\n\n{e.StackTrace}"); } finally { PrefabUtility.UnloadPrefabContents(prefab); } if (success) { successes.AddEntry(asset.path, string.Empty); } }
void UpgradeMaterials() { // upgrade material template assets var assetList = new AssetList(); assetList.AddRange( AssetDatabase.FindAssets($"t:{nameof(PhysicsMaterialTemplate)}") .Select(guid => AssetDatabase.GUIDToAssetPath(guid)) .Select(path => new Asset(path)) ); if (assetList.Count > 0) { if (IsEditable(assetList, m_Failures)) { foreach (var asset in assetList) { if (!IsEditable(asset, m_Failures)) { continue; } // material templates are upgraded in OnEnable(), so it should be sufficient to merely load them var materialTemplate = AssetDatabase.LoadAssetAtPath <PhysicsMaterialTemplate>(asset.path); EditorUtility.SetDirty(materialTemplate); m_Successes.AddEntry(asset.path, string.Empty); } } } // upgrade prefabs assetList.Clear(); foreach (var guid in AssetDatabase.FindAssets("t:Prefab")) { var prefabAssetPath = AssetDatabase.GUIDToAssetPath(guid); var prefab = AssetDatabase.LoadAssetAtPath <GameObject>(prefabAssetPath); var shapeComponents = prefab.GetComponentsInChildren <PhysicsShapeAuthoring>(true); if (shapeComponents.Length == 0) { continue; } var asset = new Asset(prefabAssetPath); if (!IsEditable(asset, m_Failures)) { continue; } assetList.Add(asset); } if (assetList.Count > 0) { if (IsEditable(assetList, m_Failures)) { var upgradedAssets = new HashSet <Asset>(); foreach (var asset in assetList) { UpgradePrefabAsset(asset, assetList, upgradedAssets, m_Successes, m_Failures); } } } // update scene objects EditorSceneManager.SetActiveScene(EditorSceneManager.NewScene(NewSceneSetup.EmptyScene)); foreach (var guid in AssetDatabase.FindAssets("t:Scene")) { var scenePath = AssetDatabase.GUIDToAssetPath(guid); var asset = new Asset(scenePath); if (!IsEditable(asset, m_Failures)) { continue; } Scene scene; try { scene = EditorSceneManager.OpenScene(scenePath); } catch (Exception e) { m_Failures.AddEntry(asset.path, $"{e.Message}\n\n{e.StackTrace}"); continue; } EditorSceneManager.SetActiveScene(scene); var succcess = true; if (IsEditable(new AssetList { new Asset(scenePath) }, m_Failures)) { var upgradedAny = false; foreach ( var sceneObject in scene.GetRootGameObjects() .Where(go => go.GetComponentsInChildren <PhysicsShapeAuthoring>(true).Any()) ) { try { UpgradePrefabInstance(sceneObject); upgradedAny = true; } catch (Exception e) { succcess = false; m_Failures.AddEntry( $"{scenePath}::{AnimationUtility.CalculateTransformPath(sceneObject.transform, sceneObject.transform.root)}", $"{e.Message}\n\n{e.StackTrace}" ); } } if (upgradedAny) { EditorSceneManager.SaveScene(scene); } } if (succcess) { m_Successes.AddEntry(scenePath, string.Empty); } EditorSceneManager.SetActiveScene(EditorSceneManager.NewScene(NewSceneSetup.EmptyScene)); EditorSceneManager.CloseScene(scene, true); } }