300x250

0. 구현 이유
에셋스토어에서 가져온 캐릭터를 사용하려 했는데, 캐릭터에 포함된 불필요한 스크립트들을 제거해야 할 상황이었습니다. 그래서 자식 오브젝트들을 일일이 확인하며 스크립트를 제거하려 했으나, 이 작업이 상당한 시간을 요구하는 것을 알게 되었습니다. 결국 제 시간을 절약하기 위해 자체적으로 스크립트 제거 기능을 개발하게 되었습니다.

Unity 에디터 확장을 사용하여 게임 오브젝트에 붙은 여러 스크립트를 한 번에 제거하는 기능을 구현하는 방법에 대해 알아보겠습니다.


1. 에디터 확장 스크립트 작성
먼저, Unity 프로젝트에서 스크립트를 생성해야 합니다. 프로젝트 안에 Editor 폴더를 만들고, 그 안에 ScriptRemoverWindow.cs라는 이름으로 스크립트 파일을 생성합니다.

 

using UnityEditor;
using UnityEngine;
using System.Collections.Generic;

public class ScriptRemoverWindow : EditorWindow
{
    private int Count = 10;
    private List<string> scriptNames = new List<string>();

    // 에디터 메뉴에서 "SLG/Remove Scripts by Name" 옵션을 추가합니다.
    [MenuItem("slg/Remove Scripts by Name")]
    private static void ShowWindow()
    {
        // "Script Remover"라는 윈도우를 엽니다.
        GetWindow(typeof(ScriptRemoverWindow), false, "Script Remover");
    }

    private void OnGUI()
    {
        GUILayout.Label("Enter the script names to remove:");
        
        // 입력 필드를 생성하여 스크립트 이름을 입력받습니다.
        for (int i = 0; i < Count; i++)
        {
            scriptNames.Add("");
        }
        
        for (int i = 0; i < Count; i++)
        { 
            scriptNames[i] = EditorGUILayout.TextField("Script " + (i + 1), scriptNames[i]);
        }

        // "Remove Scripts" 버튼을 생성하고 클릭 시 스크립트 제거 함수를 호출합니다.
        if (GUILayout.Button("Remove Scripts"))
        {
            RemoveComponentsByNames(scriptNames);
        }
    }

    private static void RemoveComponentsByNames(List<string> targetComponentNames)
    {
        // 선택된 게임 오브젝트에 대해 스크립트 제거 함수를 호출합니다.
        if (Selection.gameObjects != null)
        {
            foreach (GameObject go in Selection.gameObjects)
            {
                RemoveComponentsRecursively(go.transform, targetComponentNames);
                
                Component[] components = go.GetComponents<Component>();

                foreach (Component component in components)
                {
                    if (component != null && targetComponentNames.Contains(component.GetType().Name))
                    {
                        // 즉시 객체를 제거하고, 실행 취소 기록에 남깁니다.
                        Undo.DestroyObjectImmediate(component);
                    }
                }
            }
        }
    }

    private static void RemoveComponentsRecursively(Transform parent, List<string> targetComponentNames)
    {
        // 하위 자식들에 대해 재귀적으로 컴포넌트 제거 함수를 호출합니다.
        for (int i = parent.childCount - 1; i >= 0; i--)
        {
            Transform child = parent.GetChild(i);
            RemoveComponentsRecursively(child, targetComponentNames);

            // 하위 자식 오브젝트의 컴포넌트를 순회하며 제거 대상인 경우 제거합니다.
            Component[] components = child.GetComponents<Component>();

            foreach (Component component in components)
            {
                if (component != null && targetComponentNames.Contains(component.GetType().Name))
                {
                    // 즉시 객체를 제거하고, 실행 취소 기록에 남깁니다.
                    Undo.DestroyObjectImmediate(component);
                }
            }
        }
    }
}

이 스크립트는 "slg" 메뉴에 "Remove Scripts by Name" 옵션을 추가하고, 해당 옵션을 선택하면 "Script Remover"라는 윈도우가 열립니다. 여기에서 제거할 스크립트 이름을 입력하고 "Remove Scripts" 버튼을 클릭하면 선택된 게임 오브젝트에서 해당 스크립트를 제거합니다.

 

 

 

2. 사용 방법

상단 메뉴 바에서 "slg" 메뉴를 찾아 "Remove Scripts by Name" 옵션을 선택합니다.

 

"Script Remover" 윈도우에서 제거하고 싶은 스크립트의 이름을 입력합니다. 필요한 만큼 필드를 추가하여 여러 개의 스크립트 이름을 입력할 수 있습니다.

 

 

Before

 


After




감사합니다.

300x250