Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using UnityEngine;
- using UnityEditor;
- using System.Collections.Generic;
- using UnityEditor.SceneManagement;
- using System.Text.RegularExpressions;
- public class ReplaceObjectsWithPrefab : EditorWindow
- {
- public GameObject prefabToReplaceWith;
- public string targetName = "";
- public bool keepChildren = true;
- public Material overrideMaterial;
- [MenuItem("Tools/Replace Objects With Prefab")]
- public static void ShowWindow()
- {
- var window = EditorWindow.GetWindow<ReplaceObjectsWithPrefab>(
- utility: true, // Questo la rende una Utility Window
- title: "Replace Objects"
- );
- window.minSize = new Vector2(400, 200);
- window.maxSize = new Vector2(400, 200);
- }
- void OnGUI()
- {
- GUILayout.Label("1. Specify the objects to replace", EditorStyles.boldLabel);
- GUILayout.Label("You can use '*' as a wildcard anywhere in the name.", EditorStyles.miniLabel);
- // Layout orizzontale per il campo Target Name e il pulsante Select
- EditorGUILayout.BeginHorizontal();
- targetName = EditorGUILayout.TextField("Target Name", targetName);
- if (GUILayout.Button("Select", GUILayout.Width(60)))
- {
- SelectMatchingObjects();
- }
- EditorGUILayout.EndHorizontal();
- EditorGUILayout.Space();
- GUILayout.Label("2. Specify the prefab to replace with", EditorStyles.boldLabel);
- prefabToReplaceWith = (GameObject)EditorGUILayout.ObjectField("Prefab", prefabToReplaceWith, typeof(GameObject), false);
- EditorGUILayout.Space();
- GUILayout.Label("3. Material Override (Optional)", EditorStyles.boldLabel);
- overrideMaterial = (Material)EditorGUILayout.ObjectField("New Material", overrideMaterial, typeof(Material), false);
- EditorGUILayout.Space(10);
- keepChildren = GUILayout.Toggle(keepChildren, "Keep Children of replaced objects");
- if (GUILayout.Button("Replace All"))
- {
- ReplaceObjects();
- }
- }
- // Funzione per verificare se un nome corrisponde a un pattern con wildcard
- private bool MatchesWildcardPattern(string name, string pattern)
- {
- // Convertiamo il pattern con wildcard in un'espressione regolare
- string regexPattern = "^" + Regex.Escape(pattern).Replace("\\*", ".*") + "$";
- Regex regex = new Regex(regexPattern);
- return regex.IsMatch(name);
- }
- // Nuova funzione per selezionare gli oggetti corrispondenti al pattern
- private void SelectMatchingObjects()
- {
- if (string.IsNullOrEmpty(targetName))
- {
- EditorUtility.DisplayDialog("⚠️ Warning ⚠️", "The 'Target Name' field cannot be empty.", "Ok");
- return;
- }
- string trimmedTargetName = targetName.Trim();
- List<GameObject> matchingObjects = new List<GameObject>();
- var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
- if (prefabStage != null)
- {
- Debug.Log("Prefab mode: 🔍 Searching for objects...");
- GameObject root = prefabStage.prefabContentsRoot;
- var allTransforms = root.GetComponentsInChildren<Transform>(true);
- foreach (var t in allTransforms)
- {
- if (MatchesWildcardPattern(t.name, trimmedTargetName))
- {
- matchingObjects.Add(t.gameObject);
- }
- }
- }
- else
- {
- Debug.Log("Scene Mode: 🔍 Finding objects...");
- var allObjects = FindObjectsByType<GameObject>(FindObjectsSortMode.None);
- foreach (var obj in allObjects)
- {
- if (!obj.scene.IsValid()) continue;
- if (MatchesWildcardPattern(obj.name, trimmedTargetName))
- {
- matchingObjects.Add(obj);
- }
- }
- }
- if (matchingObjects.Count == 0)
- {
- EditorUtility.DisplayDialog("Info", "No objects found matching the specified criteria.", "Ok");
- return;
- }
- // Imposta la selezione sugli oggetti trovati
- Selection.objects = matchingObjects.ToArray();
- string contextMessage = (prefabStage != null) ? "in the prefab." : "in the scene.";
- EditorUtility.DisplayDialog("Selection Complete", $"Selected {matchingObjects.Count} {contextMessage} objects", "Ok");
- Debug.Log($"Selected {matchingObjects.Count} objects matching '{trimmedTargetName}'.");
- }
- void ReplaceObjects()
- {
- if (prefabToReplaceWith == null)
- {
- EditorUtility.DisplayDialog("⚠️ Warning ⚠️", "No Prefab assigned!", "Ok");
- return;
- }
- if (string.IsNullOrEmpty(targetName))
- {
- EditorUtility.DisplayDialog("⚠️ Warning ⚠️", "The 'Target Name' field cannot be empty.", "Ok");
- return;
- }
- string prefabName = prefabToReplaceWith.name;
- List<GameObject> objectsToReplace = new List<GameObject>();
- var prefabStage = PrefabStageUtility.GetCurrentPrefabStage();
- string trimmedTargetName = targetName.Trim();
- if (prefabStage != null)
- {
- Debug.Log("Prefab mode: 🔍 Searching for objects...");
- GameObject root = prefabStage.prefabContentsRoot;
- var allTransforms = root.GetComponentsInChildren<Transform>(true);
- foreach (var t in allTransforms)
- {
- if (t.gameObject == prefabToReplaceWith) continue;
- // Usa la nuova funzione per verificare la corrispondenza con le wildcard
- if (MatchesWildcardPattern(t.name, trimmedTargetName))
- {
- objectsToReplace.Add(t.gameObject);
- }
- }
- }
- else
- {
- Debug.Log("Scene Mode: 🔍 Finding objects...");
- var allObjects = FindObjectsByType<GameObject>(FindObjectsSortMode.None);
- foreach (var obj in allObjects)
- {
- if (!obj.scene.IsValid() || obj == prefabToReplaceWith) continue;
- // Usa la nuova funzione per verificare la corrispondenza con le wildcard
- if (MatchesWildcardPattern(obj.name, trimmedTargetName))
- {
- objectsToReplace.Add(obj);
- }
- }
- }
- if (objectsToReplace.Count == 0)
- {
- EditorUtility.DisplayDialog("Info", "No objects found to replace with the specified criteria.", "Ok");
- return;
- }
- Undo.SetCurrentGroupName("Replace Objects With Prefab");
- int group = Undo.GetCurrentGroup();
- foreach (var obj in objectsToReplace)
- {
- if (obj == null) continue;
- Transform originalTransform = obj.transform;
- List<Transform> children = null;
- if (keepChildren)
- {
- children = new List<Transform>();
- foreach (Transform child in originalTransform)
- {
- children.Add(child);
- }
- foreach (Transform child in children)
- {
- Undo.SetTransformParent(child, null, "Unparent Children");
- }
- }
- var targetScene = (prefabStage != null) ? prefabStage.scene : obj.scene;
- GameObject newObj = (GameObject)PrefabUtility.InstantiatePrefab(prefabToReplaceWith, targetScene);
- Undo.RegisterCreatedObjectUndo(newObj, "Create New Prefab");
- newObj.transform.SetParent(originalTransform.parent);
- newObj.transform.position = originalTransform.position;
- newObj.transform.rotation = originalTransform.rotation;
- newObj.transform.localScale = originalTransform.localScale;
- // --- NUOVA LOGICA PER APPLICARE IL MATERIALE ---
- if (overrideMaterial != null)
- {
- // Cerca tutti i Renderer nel nuovo prefab e nei suoi figli
- var renderers = newObj.GetComponentsInChildren<Renderer>(true);
- foreach (var renderer in renderers)
- {
- // Registra l'oggetto per l'Undo PRIMA di modificarlo
- Undo.RecordObject(renderer, "Apply Override Material");
- renderer.material = overrideMaterial;
- }
- }
- if (keepChildren && children != null)
- {
- foreach (Transform child in children)
- {
- Undo.SetTransformParent(child, newObj.transform, "Reparent Children");
- }
- }
- Undo.DestroyObjectImmediate(obj);
- }
- Undo.CollapseUndoOperations(group);
- string contextMessage = (prefabStage != null) ? "in the prefab." : "in the scene.";
- EditorUtility.DisplayDialog("Operation Complete", $"Replaced {objectsToReplace.Count} {contextMessage} objects", "Ok");
- Debug.Log($"Replaced {objectsToReplace.Count} objects matching '{targetName}' with the prefab '{prefabName}'.");
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment