|
|
|
|
|
|
using UnityEngine; |
|
|
|
using UnityEditor; |
|
|
|
|
|
|
|
// This code has been adapted from a tutorial by Patryk Galach
|
|
|
|
// https://www.patrykgalach.com/2019/08/26/replace-tool-for-level-designers
|
|
|
|
|
|
|
|
/// Replace tool window,available under Tools window.
|
|
|
|
/// Replace tool window,available under the Tools menu.
|
|
|
|
// Data store for replace tool.
|
|
|
|
// Data variable wrapped into SerializedObject.
|
|
|
|
// Prefab variable from data object. Using SerializedProperty for integrated Undo.
|
|
|
|
// Prefab variable from data object. Using SerializedProperty for integrated Undo
|
|
|
|
// Scroll position for list of selected objects
|
|
|
|
Vector2 selectObjectScrollPosition; |
|
|
|
// If data don't exist, create it.
|
|
|
|
// If data was not wrapped into SerializedObject, wrap it.
|
|
|
|
// If data was not wrapped into SerializedObject, wrap it
|
|
|
|
// If prefab field was not assigned as SerializedProperty, assign it.
|
|
|
|
// If prefab field was not assigned as SerializedProperty, assign it
|
|
|
|
replaceObjectField = serializedData.FindProperty("replaceObject"); |
|
|
|
replaceObjectField = serializedData.FindProperty("replacementPrefab"); |
|
|
|
// Scroll position for list of selected objects.
|
|
|
|
Vector2 selectObjectScrollPosition; |
|
|
|
|
|
|
|
// Register menu item to open Window.
|
|
|
|
// Register menu item to open Window
|
|
|
|
// Get existing open window or if none, make a new one.
|
|
|
|
|
|
|
|
// Open / Show window.
|
|
|
|
// Check to have data.
|
|
|
|
InitDataIfNeeded(); |
|
|
|
// Window title.
|
|
|
|
EditorGUILayout.LabelField("Replace Tool", EditorStyles.boldLabel); |
|
|
|
// ReplaceObject field. This object will be used to replace selected game objects.
|
|
|
|
InitDataIfNeeded(); |
|
|
|
EditorGUILayout.Separator(); |
|
|
|
// Space.
|
|
|
|
// Title for section with objects to replace.
|
|
|
|
|
|
|
|
// Space.
|
|
|
|
|
|
|
|
// Adding a little indentation.
|
|
|
|
// Printing information when no object is selected on scene.
|
|
|
|
|
|
|
|
// Printing information when no object is selected on scene.
|
|
|
|
EditorGUILayout.LabelField("Select object o objects in hierarchy to replace them", EditorStyles.wordWrappedLabel); |
|
|
|
EditorGUILayout.LabelField("Select objects in the hierarchy to replace them", EditorStyles.wordWrappedLabel); |
|
|
|
// Scroll view with selected game objects.
|
|
|
|
|
|
|
|
// Read-only scroll view with selected game objects.
|
|
|
|
// Read only list of objects to replace
|
|
|
|
|
|
|
|
GUI.enabled = false; |
|
|
|
if (data && data.objectsToReplace != null) |
|
|
|
{ |
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
GUI.enabled = true; |
|
|
|
// Closing scroll view.
|
|
|
|
|
|
|
|
// Removing indentation for rest of the window.
|
|
|
|
// Space.
|
|
|
|
// Replace button.
|
|
|
|
|
|
|
|
Debug.LogErrorFormat("[Replace Tool] {0}", "Missing prefab to replace with!"); |
|
|
|
Debug.LogErrorFormat("{0}", "No prefab to replace with!"); |
|
|
|
Debug.LogErrorFormat("[Replace Tool] {0}", "Missing objects to replace!"); |
|
|
|
Debug.LogErrorFormat("{0}", "No objects to replace!"); |
|
|
|
ReplaceSelectedObjects(data.objectsToReplace, data.replaceObject); |
|
|
|
ReplaceSelectedObjects(data.objectsToReplace, data.replacementPrefab); |
|
|
|
// Space.
|
|
|
|
|
|
|
|
// Applying any changes on data.
|
|
|
|
// If data was changed, force repaint.
|
|
|
|
if (serializedData != null && serializedData.UpdateIfRequiredOrScript()) |
|
|
|
{ |
|
|
|
this.Repaint(); |
|
|
|
|
|
|
{ |
|
|
|
// Check to have data.
|
|
|
|
// Creating filter to gather object only on scene.
|
|
|
|
// Converting Transform array into GameObject array.
|
|
|
|
// Force repaint as update is needed.
|
|
|
|
if (serializedData.UpdateIfRequiredOrScript()) |
|
|
|
{ |
|
|
|
this.Repaint(); |
|
|
|
|
|
|
/// Replaces game objects with provided replace object.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="objectToReplace">Game Objects to replace.</param>
|
|
|
|
/// <param name="replaceObject">Replace object.</param>
|
|
|
|
/// <param name="replaceObject">Prefab that will be instantiated in place of the objects to replace.</param>
|
|
|
|
// Loop through object to replace.
|
|
|
|
// Register current game object to Undo action in editor.
|
|
|
|
// Creating replace object as the same position and same parent.
|
|
|
|
// Register object creation for Undo action in editor.
|
|
|
|
// Changing parent for all children of current game object.
|
|
|
|
// Saving action for Undo action in editor.
|
|
|
|
// Destroying current game object with save for Undo action in editor.
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Data class for replace tool.
|
|
|
|
/// </summary>
|
|
|
|
public class ReplaceData : ScriptableObject |
|
|
|
{ |
|
|
|
public GameObject replacementPrefab; |
|
|
|
public GameObject[] objectsToReplace; |
|
|
|
} |