Questions about Platform Dependent Compilation

Source : Unity - Manual: Conditional Compilation

The scenario is : the above script is attached to many waypoint objects. They are a gameObject with a box collider set to trigger (no renderer).

When I build this project :

  • does the build still include a script attached to each waypoint object?
  • Is it just a blank script?
  • Does Unity still have to spend time on start-up reading all these scripts even though they are blank (to find and execute awake and start functions)?

How do I write this question more clearly? If I have a whole script wrapped in if UNITY_EDITOR , when I build, does a blank script still get compiled and attached to the gameObject? How does this affect optimization when I have 200 objects that Unity has to find and check the script on initialization?

Edit :

  • what kind of drop in performance or lag at startup is incurred by having many gameObjects with an empty script attached?
  • Does this performance issue only happen at startup, as there is no Update function on the empty scripts?
  • Is this whole issue negligible because they are all the same class?

Using this script as my example :

#pragma strict

#if UNITY_EDITOR

function OnDrawGizmos()
{
	var col : BoxCollider = GetComponent.< BoxCollider >();
	
	if ( col )
	{
		Gizmos.color = Color.red;
		Gizmos.matrix = transform.localToWorldMatrix;
		Gizmos.DrawCube( col.center, col.size );
	}
}
	
#endif

Suitable question checklist :

  • is it about Unity? : yes
  • of interest to more than one person? : should be, it’s about optimization and gizmos
  • has a specific answer? : they are yes/no questions, even though I asked more than one question
  • looking for code or theories? : no, I want to understand the process, insufficient information in the API
  • duplicate question? : not that I can find (Unity Questions about Platform Dependent Compilation - Google Search)
  • other considerations? : even though more than one question was asked, they all relate to the same main question ‘does a blank script get compiled and attached when using Platform Dependent Compilation in a build?’

Well, like others said already you can’t really create a MonoBehaviour that isn’t included in a build. Here are the possible problems:

UnityScript

If you use UnityScript and wrap everything in your script in pre-processor tags Unity will still create the class. The class will be an empty class. This is because Unity will create a MonoBehaviour for every *.js file, no matter what you put in the file. So in a build the class will still exist, but it’s empty.

C#

If you use C# and wrap the whole MonoBehaviour in pre-processor tags the class itself will not be included in the build. If you had an instance of that script attached to a GameObject in a scene or a prefab you will get this warning at the startup of your build:

“The class defined in script file named ‘YourClassName’ does not match the file name!”

This is because:

Asset Serialization

When Unity saves a prefab or scene to a file it has to store all the information required to restore an instance of a class in the asset file.

So a scene asset for example has a list of GameObjects that are inside the scene. For each component on the GameObjects Unity will store the type of the component and any additional information that the object needs / specified.

All MonoBehaviour scripts are simply of type “MonoBehaviour”. That is because from the engines point of view (so i talk about the native code part) all scripts are “just” MonoBehaviours. The .NET / Mono classes you create in Unity doesn’t exist in the actual engine, only in the scripting environment: Mono.

When Unity loads a scene or instantiates a prefab it does two things: It creates the actual GameObject in native code with all it’s components, where all your scripts are just MonoBehaviours. It also creates the “managed” representation of each GameObject and component in the scripting environment and wlll link them together. Since Unity analyses each of your class at compile time Unity will only call those methods on your script that have been implemented. Since the class is empty(UnityScript) or missing(C#) it won’t call any method at all.

To sum up:

Scripts which are empty but attached to gameobjects in a scene or prefab will go into the build. It will require some space in the serialization data of the scene / prefab and the part that is available will be loaded into memory. Since the script does nothing it has no real impact on Unitys update-business. It might cause a little performance hit when using GetComponent on a GameObject where the script is attached since it has to check an additional component. When you cache your components this isn’t a problem at all.

If you really need MonoBehaviours only in the editor, when using C# you could wrap them completely in preprocessor tags but don’t attach them to GameObjects in the scene. You could use an editor script (EditorWindow or custom inspector) to temporarily attach your script to a gameobject in the editor. Make sure to set the hideFlags to DontSave.
That will prevent Unity from saving the component into the scene. Note: Such a MonoBehaviour will be lost at each playmode change or scene reload since it only exists in memory.

Keep in mind if you wrap a C# MonoBehaviour in UNITY_EDITOR tags the class won’t exist in the build, so don’t use the script name in any runtime scripts or you can’t build your game.