- Home /
Create custom warning dialog on build, if a script or gameobject exists in the scene
Hi, I am trying to create a warning dialog to show when building / or have built, if I have my developer debugging scripts still enabled.
I tried looking at https://docs.unity3d.com/460/Documentation/ScriptReference/Callbacks.PostProcessBuildAttribute.html but for the life of me I cant seem to work out how to get that to work if there is a script or gameobject still enabled in the scene.
Anyone have a good way of doing this?
You could always do a
#if (UNITY_EDITOR)
#endif
encapsulation on your class. Which will prevent it from getting compiled
Answer by jdean300 · Feb 13, 2017 at 04:10 AM
I have done something similar to this. What I did was create my own MenuItem that runs the build using BuildPipeline.BuildPlayer. Either before or after running the build (depending on what you want to do), I load whatever scenes I want to check for editing using this bit of code:
using (var sceneEdit = new SceneEditHelper("Assets/Scenes/Menu.unity"))
{
// use SceneEditHelpers methods to analyze the scene, check for components, etc.
}
Which makes use of this class:
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
public class SceneEditHelper : IDisposable
{
private Scene m_Scene;
public SceneEditHelper(string sceneName)
{
m_Scene = EditorSceneManager.OpenScene(sceneName, OpenSceneMode.Single);
}
public void Dispose()
{
// These two lines make sure that any edits to the scene we have made are saved when
// we dispose of the SceneEditHelper (which the using statement does automatically)
EditorSceneManager.MarkSceneDirty(m_Scene);
EditorSceneManager.SaveScene(m_Scene);
}
/// <summary>
/// Gets the first component of the given type in the scene,
/// or null if no component of the given type exists.
/// </summary>
public T GetFirstComponentOfType<T>()
where T : MonoBehaviour
{
var roots = m_Scene.GetRootGameObjects();
var firstOrDefault = roots.FirstOrDefault(root => root.GetComponentInChildren<T>() != null);
return firstOrDefault != null
? firstOrDefault.GetComponentInChildren<T>()
: null;
}
/// <summary>
/// Gets all component of the given type from the scene
/// </summary>
public IEnumerable<T> GetComponentsOfType<T>()
where T : MonoBehaviour
{
var roots = m_Scene.GetRootGameObjects();
var components = new HashSet<T>();
foreach (var comp in roots.SelectMany(root => root.GetComponentsInChildren<T>()))
{
components.Add(comp);
}
return components;
}
/// <summary>
/// Gets all GameObjects in the scene that fulfill the given predicate
/// </summary>
public IEnumerable<GameObject> GetGameObjectsWhere(Func<GameObject, bool> pred)
{
var roots = m_Scene.GetRootGameObjects();
var objects = new List<GameObject>();
foreach (var go in roots)
{
if (pred(go))
objects.Add(go);
objects.AddRange(go.GetChildrenWhere(pred));
}
return objects;
}
}
You can then show a custom EditorWindow to show whatever warning you want.
EDIT: Sorry, missed the code for a GameObject extension method that the above code uses. Here it is:
public static IEnumerable<GameObject> GetChildrenWhere(this GameObject obj, Func<GameObject, bool> pred)
{
var children = new List<GameObject>();
for (var i = 0; i < obj.transform.childCount; i++)
{
var child = obj.transform.GetChild(i).gameObject;
if (pred(child))
children.Add(child);
children.AddRange(GetChildrenWhere(child, pred));
}
return children;
}
Thats really helpful thank you, and certainly something useful there for me to build a more extensive method of running post build checks, thanks very much :)
Answer by Yeasty · Feb 13, 2017 at 08:11 AM
Hey buddy have a look at this http://wiki.unity3d.com/index.php/DebugConsole