EditorOnly Components & Actions when building


Sometimes you want to have some component present in your gameObject, but you want to remove them once you are in play mode. the script I present to you here delete every components you don't want in the build.

It also provide a list of UnityEvent Action you can use when you enter play mode, or when you are building your game

EditorOnly gameObjects

Currently if you want a gameObject to be

editorOnly
, unity provide a tag specificly for that purpose. gameObject tagged with EditorOnly are removed when building the game.

Unfortunatly, there isn't a way to scpecify it per components. So I made 2 script to overcome this porblem.




How to Use:

First, put the

ExtBuildSettings.cs
inside any Editor/ folder in your project.

The two others script providen must be outside of the Editor folder, put them in your current scripts folder.

Secondly, put as many

EditorOnlyCleaning.cs
script as you want in your hierarchy. See the exemple bellow:

Steps of uses:

  • First, Add a EditorOnlyCleaning.cs script in a gameObject
  • Second, Add as many built-in UnityEvent in the AllAction list, these actions will be fired in order
  • Third, Add all components you want to destroy in play or in build


When you will entering in play mode, or when you will build your application, every
EditorOnlyCleaning.cs
script will:
  • Execute all UnityEvent actions in the given order
  • Remove every components present in their list
  • Remove itself
Don't use them too much: theses scripts can add confusion between editor, play mode and build. My recommandation is to have only one
EditorOnlyCleaning.cs
script per scenes. If not, use it with caution, rename well your gameObjects and order your hierarchy.
If you have entire gameObjects marked as EditorOnly, you may want to hide them in the game camera, or in the scene view. See my article about it at the end of this page.



Scripts:

EditorOnlyCleaning.cs
Download
Copy
/// <summary>
/// MIT License - Copyright(c) 2019 Ugo Belfiore
/// </summary>

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

/// <summary>
/// Remove Components marked as EditorOnly, and execute actions when you building your game
/// ExecuteBuildCleaning is called thanks to BuildCallBack().
/// This function will also get called when entering Playmode, when SceneManager.LoadScene is called.
/// if you want to desactivate this behavior, set PlayModeCleaning to false
/// </summary>
public class EditorOnlyCleaning : MonoBehaviour
{
    public bool PlayModeCleaning = true;    //active the cleaning when entering in play mode
    public bool BuildCleaning = true;       //active the cleaning when building

    //all action you want to do
    public List<UnityEvent> AllActions = new List<UnityEvent>();
    //all Component you want to delete
    public List<Component> AllBehaviorToDeleteFromBuild = new List<Component>();

    /// <summary>
    /// - Call all action
    /// - Delete all behavior
    /// - Delete itself
    /// </summary>
    public void ExecuteBuildCleaning()
    {
        if (!BuildCleaning || (Application.isPlaying && !PlayModeCleaning))
        {
            return;
        }
        ExecuteUnityEventAction();
        RemoveAllComponents();
        RemoveItself();
    }

    /// <summary>
    /// execute all UnityEvent action
    /// We theoricly could have only one UnityEvent with multiple action,
    /// but then we can't prediect the order of actions.
    /// Here with a list of UnityEvent, we manage the order ourself.
    /// </summary>
    private void ExecuteUnityEventAction()
    {
        for (int i = 0; i < AllActions.Count; i++)
        {
            AllActions[i].Invoke();
        }
    }

    /// <summary>
    /// Delete every components in the list
    /// </summary>
    private void RemoveAllComponents()
    {
        for (int i = 0; i < AllBehaviorToDeleteFromBuild.Count; i++)
        {
            if (AllBehaviorToDeleteFromBuild[i] == null)
            {
                continue;
            }

            if (Application.isPlaying)
            {
                Destroy(AllBehaviorToDeleteFromBuild[i]);
            }
            else
            {
                DestroyImmediate(AllBehaviorToDeleteFromBuild[i]);
            }
        }
    }

    /// <summary>
    /// Remove the script component this
    /// </summary>
    private void RemoveItself()
    {
        if (Application.isPlaying)
        {
            Destroy(this);
        }
        else
        {
            DestroyImmediate(this);
        }
    }
}
ExtBuildSettings.cs
Download
Copy
/// <summary>
/// MIT License - Copyright(c) 2019 Ugo Belfiore
/// </summary>

using UnityEditor.Callbacks;

/// <summary>
/// useful functions linked to the building process
/// <summary>
public static class ExtBuildSettings
{
    [PostProcessScene(0)]
    private static void BuildCallBack()
    {
        EditorOnlyCleaning[] editorOnlyCleanings = ExtUtilityFunction.GetScripts<EditorOnlyCleaning>();
        for (int i = 0; i < editorOnlyCleanings.Length; i++)
        {
            editorOnlyCleanings[i].ExecuteBuildCleaning();
        }
    }
}
ExtUtilityFunction.cs
Download
Copy
/// <summary>
/// MIT License - Copyright(c) 2019 Ugo Belfiore
/// </summary>

/// <summary>
/// Useful runtime functions
/// <summary>
public static class ExtUtilityFunction
{
    /// <summary>
    /// Get a script. Use it only in editor, it's extremly expensive in performance
    /// use: MyScript myScript = ExtUtilityFunction.GetScript<MyScript>();
    /// </summary>
    /// <typeparam name="T">type of script</typeparam>
    /// <returns>return the script found, or null if nothing found</returns>
    public static T GetScript<T>()
    {
        object obj = UnityEngine.Object.FindObjectOfType(typeof(T));

        if (obj != null)
        {
            return ((T)obj);
        }
        return (default(T));
    }

    /// <summary>
    /// Get a list of scripts. Use it only in editor, it's extremly expensive in performance
    /// use: MyScript [] myScript = ExtUtilityFunction.GetScripts<MyScript>();
    /// </summary>
    /// <typeparam name="T">type of script</typeparam>
    /// <returns>return the array of script found</returns>
    public static T[] GetScripts<T>()
    {
        object[] obj = UnityEngine.Object.FindObjectsOfType(typeof(T));
        T[] objType = new T[obj.Length];


        if (obj != null)
        {
            for (int i = 0; i < obj.Length; i++)
            {
                objType[i] = (T)obj[i];
            }
        }

        return (objType);
    }
}



How it works:

When you will build your game, the function
BuildCallBack();
of the script
ExtBuildSettings.cs
will be fired, thanks to the
[PostProcessScene(0)]
attribute.

This function will find every
EditorOnlyCleaning.cs
script in every scenes, and execute their kamikaze actions.









See also:

Hide gameObjects from game camera or scene-view

This article show how to hide gameObjects from the game Camera, or from the scene view, without desactivating them.