static internal void BuildLinks(this PEPrefabScript _this, bool force = false) { if (force || _this.Prefab == _this.gameObject) { _this.Links.BuildLinks(_this.gameObject); EditorUtility.SetDirty(_this); } else { if (_this == null) { Debug.LogError("PEPrefabScriptExt.BuildLinks() - _this == null"); return; } if (_this.Prefab == null) { Debug.LogError(string.Format("PEPrefabScriptExt.BuildLinks(_this.name='{0}') - _this.Prefab == null. PrefabPath:{1}", _this.name, AssetDatabase.GetAssetOrScenePath(_this))); return; } PEPrefabScript pePrefabScript = _this.Prefab.GetComponent <PEPrefabScript>(); if (pePrefabScript == null) { Debug.LogError(string.Format("PEPrefabScriptExt.BuildLinks(_this.name='{0}') - expecting prefab with _this.Prefab.name='{1}' to have attached PEPrefabScript Component. PrefabPath:{2} (Click on this message to show this prefab in Project window)", _this.name, _this.Prefab.name, AssetDatabase.GetAssetPath(_this.Prefab)), _this.Prefab); return; } pePrefabScript.BuildLinks(); EditorUtility.SetDirty(pePrefabScript); } }
static void OnValidate(this PEPrefabScript _this) { if (PrefabUtility.GetPrefabType(_this.gameObject) == PrefabType.Prefab) { EditorApplication.delayCall += () => { if (_this == null) { return; } if (_this.Prefab != _this.gameObject && _this.transform == _this.transform.root) { _this.Prefab = _this.gameObject; _this.BuildLinks(); } }; } }
static internal void ApplyChanges(this PEPrefabScript _this, bool buildModifications = false) { if (!_this) { return; } if (PEPrefs.DebugLevel > 0) { Debug.Log(string.Format("[Begin Apply] {0}", _this.name)); } EditorUtility.DisplayProgressBar("Apply changes", _this.name, 0f); if (buildModifications) { foreach (var pi in _this.GetComponentsInChildren <PEPrefabScript>(true)) { pi.BuildModifications(); } } if (recursionCounter++ > 100) { Debug.LogError("Recursion"); recursionCounter = 0; EditorUtility.ClearProgressBar(); return; } _this.BuildLinks(true); _this.BuildModifications(); var newPrefab = !AssetDatabase.Contains(_this.gameObject) ? PrefabUtility.ReplacePrefab(_this.gameObject, _this.Prefab, ReplacePrefabOptions.ConnectToPrefab) : _this.gameObject; var prefabs = _this.GetPrefabsWithInstances(); foreach (var prefab in prefabs) { if (PEPrefs.DebugLevel > 0) { Debug.Log("[Apply] Found Nested instance:" + prefab.name); } var instantiatedPrefabsList = new List <GameObject>(); var instances = new List <PEPrefabScript>(); if (prefab == null) { continue; } var pi = (GameObject)PrefabUtility.InstantiatePrefab(prefab); PrefabUtility.DisconnectPrefabInstance(pi); var nestedInstances = PEUtils.GetNestedInstances(pi).Where(p => p.PrefabGUID == _this.PrefabGUID && p.enabled).ToArray(); instances.AddRange(nestedInstances); var rootInstance = pi.GetComponent <PEPrefabScript>(); if (rootInstance && rootInstance.ParentPrefabGUID == _this.PrefabGUID) { instances.Insert(0, rootInstance); } instantiatedPrefabsList.Add(pi); var counter = 0; foreach (var instance in instances) { if (instance == null || instance.gameObject == null) { Debug.LogWarning("[Apply] Huston we have a problem. Prefab is destroyed before replace"); continue; } instantiatedPrefabsList.Remove(instance.gameObject); var newObject = instance.ReplaceInPlace(newPrefab); if (newObject == null || newObject.gameObject == null) { Debug.LogWarning("[Apply] Huston we have a problem. Prefab is destroyed after replace"); continue; } if (newObject.ParentPrefab == newPrefab) { instantiatedPrefabsList.Add(newObject.gameObject); } PrefabUtility.RecordPrefabInstancePropertyModifications(newObject); EditorUtility.DisplayProgressBar("Apply changes", _this.name + " replaced in " + newObject.gameObject, ((float)counter++) / (float)instances.Count); } foreach (var instantiatedPrefab in instantiatedPrefabsList) { if (instantiatedPrefab == null) { continue; } var instance = instantiatedPrefab.GetComponent <PEPrefabScript>(); if (instance) { instance.ApplyChanges(); } else { PrefabUtility.ReplacePrefab(instantiatedPrefab, PrefabUtility.GetPrefabParent(instantiatedPrefab), ReplacePrefabOptions.ConnectToPrefab); } Object.DestroyImmediate(instantiatedPrefab); } } recursionCounter--; if (PEPrefs.DebugLevel > 0) { Debug.Log(string.Format("[End Apply] {0}", _this.name)); } }