See and post notes on Unity Documentation pages

Adds shared user contributed notes per page to Unity's docs. Such as examples, gotchas and general notes on usage.

Chrome: Download for Chrome
Firefox: Download Foxified first then use the Chrome link

Disclaimer: This is an unofficial extension and is in no way affiliated with or endorsed by Unity Technologies.


Extension Preview

Total Note Count: 323

Unity - Scripting API: Object.DestroyImmediate

Thomas Ingram - 2019-04-21T12:25:49

When destroying prefab assets you must use AssetDatabase.DeleteAsset(path); as Object.DestroyImmediate(prefabAsset, true); will not successfully delete the asset.

Unity - Scripting API: SceneManagement.SceneManager.LoadScene

Robert Yang - 2019-04-20T16:23:57

when loading a scene additively, the light settings (skybox, fog, etc) might conflict... to tell Unity which scene settings to use, use SceneManager.SetActiveScene (but wait at least one frame after loading the scene before setting it to be the active scene)... for more info, see this Catlike Coding tutorial

IEnumerator LoadLevel () {
SceneManager.LoadScene("Level 1", LoadSceneMode.Additive);
yield return null;
SceneManager.SetActiveScene(SceneManager.GetSceneByName("Level 1"));

Unity - Manual: Cache Server

Romain Théry - 2019-04-17T10:04:26

Please note that you should not use different unity versions at the same time on the same cache server. You will end up corrupting your assets (very problematic if you use asset bundles in production)
If all your unity version are 2018.1+, you can create a different cache server instance per unity version, each accessible with a specific port. (cf.

Unity - Scripting API: EventSystems.PhysicsRaycaster.maxRayIntersections

Hugo Scott-Slade - 2019-04-09T13:16:15

The built in script in 2017.4 versions (and newer) has an issue with this variable. If this number exceeds the actual number of ray intersections/collisions found it will throw a NullReferenceException.

Source code:

Fixed replacement drop-in:


Barnaby Smith - 2019-04-08T23:32:11

Note you can find a list of all menu items by using the undocumented EditorGUIUtility.SerializeMainMenuToString() method.

To generate complete paths, use something like the following (tested on Unity 2018.3)

static int CalculateIndent(string source)
int spaceCount = 0;
for (int i = 0; i < source.Length; i++)
if (source[i] == ' ')

return spaceCount / 4;

public static List<string> ParseMenuItems()
List<string> menuItemMappings = new List<string>();
string mainMenuString = EditorGUIUtility.SerializeMainMenuToString();
string[] split = mainMenuString.Split('\n');
int lastIndent = -1;

List<string> stack = new List<string>();

foreach (string line in split)
if (line.Trim().Length == 0) continue;

int newIndent = CalculateIndent(line);
for (int i = lastIndent; i < newIndent; i++)
for (int i = lastIndent; i > newIndent; i--)
stack.RemoveAt(stack.Count - 1);

stack[stack.Count - 1] = line.Trim();

string path = string.Join("/", stack.ToArray());

lastIndent = newIndent;

return menuItemMappings;

Unity - Scripting API: TerrainData.GetInterpolatedHeight

bgrz - 2019-04-05T14:38:40

Input parameters are in normalized [0, 1] range, returned value is in unnormalized range [0, terrain height].

Unity - Scripting API: Bounds.size

Thomas Ingram - 2019-03-30T09:29:02

Calls to Bounds.extents will be cheaper than Bounds.size as size is treated as a multiple of extents.
Setting it will call extents = value * 0.5f, and getting it will return extents * 2f.
It's generally good practice to cache calls to properties if you're constructing a component vector because of situations like these.

Unity - Scripting API: Random.Range

Ben Haderle - 2019-03-20T03:20:46

not affected by resetting Random.State

Script compilation and assembly definition files

Thomas Ingram - 2019-03-15T07:15:16

It's important to notice that when you tick or untick the "Any Platform" tickbox the state of the platforms below swaps between Include and Exclude. It can be easy to accidentally create exclusive instead of inclusive scenarios even knowing this behaviour.

Unity - Manual: Rich Text

Barnaby Smith - 2019-03-12T15:05:41

Note you can use the ColorUtility to convert a Unity color to the hex sequence needed for the color tag.

For example:

Color myColor = new Color(1, 0.77f, 1);
string foo = "<color=#" + ColorUtility.ToHtmlStringRGBA(myColor) + ">something</color>";

Unity - Scripting API: MonoBehaviour.OnValidate()

litefeel - 2019-03-08T11:24:00

This message can be sent from assets and instances.

Unity - Manual: Playmode test framework

Bart Heijltjes - 2019-03-07T09:39:26

PrebuildSetupAttribute is only for setting up a scene or assets. Use NUnit's SetupAttribute for setting up variables inside your test class.

Unity - Manual: Android SDK/NDK setup

ippocardio - 2019-03-05T18:01:04

Following the above steps (I checked the Android Studio install option) will give errors when you try to build.
After downloading and installing everything,
- go to Android SDK folder
- rename the "tools" folder to tools.backup
- download and place the zipped "tools" folder into the Android SDK folder
Now it should work.

Unity - Scripting API: JsonUtility.FromJsonOverwrite

HilariousCow - 2019-03-03T19:43:49

I've found that if the ScriptableObject class you have created has references to other ScriptableObjects, then the time at which you use JsonUtility.FromJsonOverwrite is important.
If the objects references have not been loaded into the scene yet, then during deserialisation, the ID of that object will not be in the unity lookup table, and thus that field will come back as "default(T)" (i.e. "null")

If you are loading save game data, my advice is to use the JsonUtility.FromJsonOverwrite AFTER the content for your game is loaded.

Or use something else (I've heard Odin is good).

Unity - Scripting API: UI.Scrollbar.OnPointerDown

kkukshtel - 2019-03-03T18:20:55

It's not obvious here, but to actually receive this callback on a script you need to have a script that is attached to a GameObject that has a Selectable (like the Scrollbar), and then in that script implement the IPointerDownHandler interface. Unity then magically calls your implementation of the interface for the selectable that the script is "attached" to. Example (attached to a GameObject with a Scrollbar):

public class DoSomethingOnSelectableMouseDown: MonoBehaviour, IPointerDownHandler
public void OnPointerDown(PointerEventData eventData)
// Your code here

Unity - Manual: Using Animation Events

Danny Hawk - 2019-03-03T17:55:01

It is important to note that function called by an animation event is allowed to have a float, string, int, object reference, or an AnimationEvent object as its parameter. However, it cannot have a bool as a parameter. Any function with a bool as a parameter will simply not show up in the dropdown of the available functions on the animation event.

Unity - Scripting API: DrivenRectTransformTracker

SkywardRay - 2019-02-26T22:14:52

See also:

Unity - Scripting API: AnimationStream

HilariousCow - 2019-02-25T16:43:02

Nope. Just confirmed that it's not. Had a root motion animation which went through ~181 degrees. I counted up the displacement each time the root motion function got called. It added up to ~3.19. I figured, wow, that looks awful close to Pi!

So yeah, make sure, if you're dealing with eulers, to convert angularVelocity into degrees/second by multiplying by Mathf.Rad2Deg. Then before setting the downstream, remember to put it back into radians per second by multiplying it by Mathf.Deg2Rad.

Unity - Manual: JSON Serialization

Robert Yang - 2019-02-24T22:11:57

To serialize arrays in JSON, a "wrapper class" might look like this:

// from
public static class JsonHelper
public static T[] FromJson<t>(string json)
Wrapper<t> wrapper = JsonUtility.FromJson<wrapper<t>>(json);
return wrapper.Items;

public static string ToJson<t>(T[] array)
Wrapper<t> wrapper = new Wrapper<t>();
wrapper.Items = array;
return JsonUtility.ToJson(wrapper);

public static string ToJson<t>(T[] array, bool prettyPrint)
Wrapper<t> wrapper = new Wrapper<t>();
wrapper.Items = array;
return JsonUtility.ToJson(wrapper, prettyPrint);

private class Wrapper<t>
public T[] Items;

and then call something like

string mySaveData = JsonHelper.ToJson<array_type>(ARRAY);

Unity - Scripting API: ForceMode

bgrz - 2019-02-22T14:14:31

Examples of using all modes to achieve the same result:

Unity - Scripting API: AnimationStream

HilariousCow - 2019-02-22T13:58:58

My best guess is that angularVelocity is in degrees/second.

Unity - Scripting API: AnimationStream

HilariousCow - 2019-02-21T22:17:26

Clarification: "velocity" is in local space, i.e. velocity relative to the animation's current root bone rotation. Multiply this by deltaTime to see the local (relative) displacement.

Unity - Scripting API: Il2CppCompilerConfiguration

Romain Théry - 2019-02-21T10:54:21

You can get/set this value via PlayerSettings.GetIl2CppCompilerConfiguration and PlayerSettings.SetIl2CppCompilerConfiguration

Unity - Scripting API: Audio.AudioMixer.SetFloat

Bart Heijltjes - 2019-02-18T15:02:15

At least in the editor this appears only to works from Start(), not from Awake(), OnEnable() or [RuntimeInitializeOnLoad].


Barnaby Smith - 2019-02-10T23:26:02

Note that from Unity 2018.2 almost all built in Window paths change, for example Window/Inspector becomes Window/General/Inspector. As such you may need to use #if UNITY_2018_2_OR_NEWER to branch the paths in your code if you need to support older versions of Unity.

A handy use of ExecuteMenuItem is to combine it with a selection change. For example if you have a config scriptable object that you want to link to from a custom editor window you could write something like:

Selection.activeObject = KeyMappings.Instance;

This sets the scriptable object (or any object) as the selection then will either focus an inactive Inspector tab or create a new one if there isn't one already.

Unity - Scripting API: ParticleSystem.Play

Thomas Ingram - 2019-02-10T21:31:16

When using many ParticleSystem methods it's important to use the overload "withChildren" to disable Unity recursing over child gameObjects and getting child ParticleSystems where appropriate. If you are calling this many times without, it's advised to cache the children yourself and to pass withChildren = false;

Unity - Scripting API: Editor

Thomas Ingram - 2019-02-10T04:19:41

There is a method: DrawPropertiesExcluding(SerializedObject obj, params string[] propertyToExclude) that will act like DrawDefaultInspector, but you can specify serialized properties to not draw.
For example you can provide "m_Script" to not draw the script field at the top of the component UI.

Unity - Scripting API: Vector3.Distance

Thomas Ingram - 2019-02-10T00:35:41

Use Vector3.sqrMagnitude wherever possible to avoid the square root operation present in the distance calculation.

Unity - Scripting API: PrefabAssetType -

Sergio Bonfiglio - 2019-02-08T11:23:50

This enum and PrefabInstanceStatus on their own don't really give a straightforward way to check whether the object you're testing is a prefab or an instance of a prefab.
What I found works well is testing against both PrefabAssetType.NotAPrefab and PrefabInstanceStatus.NotAPrefab:

if ( _prefabAssetType != PrefabAssetType.NotAPrefab )
if ( _prefabInstanceStatus != PrefabInstanceStatus.NotAPrefab )
// It's an instance
// It's a prefab
// It's neither of those

Rendering with Replaced Shaders

Vadim Kaburgan - 2019-02-08T09:09:00

Seems like using custom RenderTypes don't break anything in default unity rendering.(But beware that some plugins can use Rendering with Replaced Shaders and don't have support for your custom RenderTypes).
For example you can change terrain's RenderType from "Opaque " to "Terrain" if you want to render your terrain differently than other Opaque objects. Or use any new custom RenderType on other objects.

Unity - Scripting API: EditorGUI.indentLevel

Thomas Ingram - 2019-02-08T04:56:17

It is generally preferably to use an IndentLevelScope to control this behaviour in a disposable fashion.

There is also a method Rect EditorGUI.IndentedRect(Rect source) that will return an indented rect.

Unity - Scripting API: PrefabInstanceStatus

Sergio Bonfiglio - 2019-02-07T16:52:02

Took me a while to figure this out, this enum and PrefabAssetType don't really give a straightforward way to check whether the object you're testing is a prefab or an instance of a prefab.
What I found works well is testing against PrefabInstanceStatus.NotAPrefab:

if ( _prefabAssetType != PrefabAssetType.NotAPrefab )
if ( _prefabInstanceStatus != PrefabInstanceStatus.NotAPrefab )
// It's an instance
// It's a prefab
// It's neither of those

Unity - Scripting API: Resources.FindObjectsOfTypeAll

RageKit - 2019-02-06T21:11:33

In Editor, will only return object that have been LOADED in memory before, by clicking on them. So be Carefull

Unity - Scripting API: Editor.CreateEditor

Thomas Ingram - 2019-02-05T07:42:04

Although it is present in the example: it's important to DestroyImmediate the created Editor. If this is not done there will be an increasing amount of errors that can only be reset via restarting Unity.
If you are using this method and getting errors from an associated Editor's OnEnable, it is likely that you have missed doing this in an OnDisable method, or if relevant, before recreating the Editor.

Unity - Scripting API: Vector3.SignedAngle

HilariousCow - 2019-02-05T03:13:49

Do not expect the "from" and "to" vectors to be flattened against the Axis when calculating the angle. If the inputs are pointing at all up or down in the plane defined by the axis, you're going to get the "Angle between two 3D vectors" returned. NOT the "Angle between two 3D vectors flattened on a plane".

Workaround: Make sure that you flatten the "from" and "to" vectors against the axis: i.e.

Vector3.SignedAngle( Vector3.ProjectOnNormal(from, Vector3.up), ( Vector3.ProjectOnNormal(to, Vector3.up), Vector3.up);

Unity - Scripting API: LayoutGroup

Jonathan Page - 2019-02-01T14:46:45

From Unity UI Optimization tips :
"Every UI element that marks its layout as dirty will perform, at minimum, one GetComponents call
This call looks for a valid Layout Group on the Layout Element’s parent. If it finds one, it continues walking up the Transform hierarchy until it stops finding Layout Groups or reaches the hierarchy root–whichever comes first.
Therefore, each Layout Group adds one GetComponents call to each child Layout Element’s dirtying process, making nested Layout Groups extremely bad for performance."

Use them wisely and sparingly.

Unity - Scripting API: SerializedObject.Update

Thomas Ingram - 2019-02-01T09:34:45

If you end up modifying the Editor.targets array in combination with SerializedObjects I have found a nightmare situation where Undo does not seem to properly work in combination with SerializedObject.Update.
In such a case you may find calling SerializedObject.SetIsDifferentCacheDirty will successfully dirty the Object and enable SerializedObject.Update to function properly.

Unity - Scripting API: SceneManagement.EditorSceneManager.SaveScene

Mathew Varkki - 2019-01-31T14:58:32

If you want to save a newly created scene, you have to use ".unity" at the end of the path.
Like in this example:

Scene newScene = EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Single);
EditorSceneManager.SaveScene(newScene, scenePath+"/"+sceneName+".unity", false);

Unity - Scripting API: Bounds.SqrDistance

Thomas Ingram - 2019-01-29T22:41:00

Similar to Bounds.ClosestPoint:
"If the point is inside the bounding box, unmodified point position will be returned."

Unity - Scripting API: AssetBundle.Unload

Nevermind - 2019-01-29T12:52:27

Calling Unload(true) apparently uses DestroyImmediate internally. This can lead to crashes when loaded object is actually used in a different thread (e.g. when it's animated).

Unity - Scripting API: AssetDatabase.GetSubFolders

RageKit - 2019-01-28T17:34:43

warning : can be broken, see https://issuetracker.unity3...
Should be fixed


Robert Yang - 2019-01-27T01:27:16

In Unity 2017.4 or before, ``Animations.Axis`` was ``RectTransform.Axis``

Unity - Scripting API: Editor.OnSceneGUI()

Thomas Ingram - 2019-01-18T06:38:46

Editors for ScriptableObjects do not seem to call this method. Use SceneView.onSceneGUIDelegate or the 2019.1+ SceneView.duringSceneGui instead.

Unity - Manual: Audio Clip

Maize Wallin - 2019-01-18T02:48:10

Further much more detailed explanation of different import settings for audio and their effects:


Robert Yang - 2019-01-16T17:48:58

Really important: Note the "cam = null" usage note in the docs!

Also: this function won't actually give you the coordinates in anchored / UI pivot space... to convert:

localPoint += rect.rect.max;

(see for info)

Unity - Scripting API: StaticBatchingUtility.Combine

Mark Hogan - 2019-01-16T11:42:03

The overload that takes a GameObject array also sorts the array by material and lightmap index

Unity - Manual: USS supported properties

Thomas Ingram - 2019-01-15T09:19:33

-unity-background-image-tint-color is the property associated with unityBackgroundImageTintColor.

Platform dependent compilation

crowbarska - 2019-01-14T19:02:32

For Nintendo Switch you can also use the define symbol "UNITY_SWITCH" (not listed here).

Unity - Scripting API: Collider.ClosestPoint

Chris Wade - 2019-01-10T18:11:21

This function always returns the passed in vector3 if the collider is disabled or the gameObject not activeInHierarchy!

Unity - Scripting API: Vector3

Thomas Ingram - 2019-01-09T23:38:30

When debugging vectors it can be important to note that the displayed default fractional precision is extremely low due to the default implementation of ToString, and this rounding can make vectors be percieved as identical when in reality they are relatively far apart.
When debugging you can use .ToString("FX") where X is the amount of fractional precision you want.

Unity - Scripting API: Texture2D.LoadRawTextureData

Barnaby Smith - 2019-01-07T11:23:45

Note this works with raw pixel data, it does not work with image files. To load a PNG or JPG you should use LoadImage instead

Unity - Scripting API: SystemLanguage

Barnaby Smith - 2019-01-06T02:24:34

Hungarian is certainly present in 3.4 and above, so there's no reason to use Hugarian if targeting 4.x or 5.x.

See and

Unity - Scripting API: SystemInfo.unsupportedIdentifier

Barnaby Smith - 2019-01-06T01:33:39

This has a constant value of "n/a" see

Unity - Manual: Setting up the post-processing stack

Simon (darkside) J - 2019-01-02T17:09:11

This section is really out of date for 2018.3. The Post processing asset does not work and causes loads of script validation errors and the new V2 PPS uses a different workflow.

I recommend users look at the Quick Start guide on the V2 PPS GitHub wiki ( and use the Post Processing package located in the package manager (Window -> Package manager) on 2018.3

Unity - Scripting API: RuntimeInitializeLoadType

Michael Chugg - 2018-12-27T05:57:22

RuntimeInitializeLoadType does not get called on static generic classes. (2018.3)

Unity - Manual: Properties types

Thomas Ingram - 2018-12-24T11:36:39

The fonts present in Unity Editor Resources on Windows are:

Arial, Lucida Grande, consola

You do not seem to have to provide a file extension.

Unity - Scripting API: UnityEvent

Thomas Ingram - 2018-12-22T01:24:43

If you add a component at runtime you need to initialise a UnityEvent
FooEvent = new UnityEvent();
before you can subscribe to it successfully.

Unity - Manual: ShaderLab: Blending

Alexander Degtyarev - 2018-12-20T08:41:26

Remember, in most cases, you can't use Blend Operation Min / Max on mobiles (Some devices do not support it)

Unity - Manual: Vertical Layout Group

Robert Yang - 2018-12-17T05:32:54

For a (better) explanation of how Vertical Layout Groups work, see: https://www.hallgrimgames.c...

Unity - Manual: Horizontal Layout Group

Robert Yang - 2018-12-17T05:32:32

For a (better) explanation of how Layout Groups work, see: https://www.hallgrimgames.c...

Unity - Scripting API: IDropHandler

Robert Yang - 2018-12-17T05:21:22

If OnDrop doesn't seem to be working or firing, there are two ways to make it work:

OPTION 1: put a CanvasGroup on the dragged object, and disable "Blocks Raycast" when you begin dragging, and then re-enable it when you end dragging

OPTION 2: make sure the object accepting the drop is listed AFTER the dragged item in the hierarchy (order matters). That is, your hierarchy order should look like this:
- dragged item implementing IDragHandler
- drop area implementing IDropHandler

Unity - Scripting API: Renderer.SetPropertyBlock

Anomalous Underdog - 2018-12-16T09:23:47

In practice, I found out that SetPropertyBlock has to be called continually in the Update method, if you're also continually changing values in the MaterialPropertyBlock. In other words, SetPropertyBlock doesn't create a "link" between the Material and the MaterialPropertyBlock (I thought I only needed to call SetPropertyBlock once, in the Start method or something). Instead, it seems it just applies the current values of the MaterialPropertyBlock to the Material, right there and then.

Unity - Scripting API: TextGenerationSettings.scaleFactor

Alexander Degtyarev - 2018-12-10T10:39:32

This one is set 0 by default, so make sure it is set to proper value;

Unity - Scripting API: ScriptableObject.CreateInstance

Robert Yang - 2018-12-06T01:59:54

If you're creating the ScriptableObject manually (*not* with the CreateAssetMenuAttribute) then make sure you call AssetDatabase.CreateAsset() etc. as well... see for an example...

public static void CreateAsset<t> (string path) where T : ScriptableObject
T asset = ScriptableObject.CreateInstance<t> ();
string assetPathAndName = AssetDatabase.GenerateUniqueAssetPath (path + "/New " + typeof(T).ToString() + ".asset");

AssetDatabase.CreateAsset (asset, assetPathAndName);

Unity - Scripting API: TextureImporterType.NormalMap

Sergio Bonfiglio - 2018-12-04T14:35:51

Property seems to be deprecated in Unity 5.6.x, not sure whether it's been brought back on the latest versions.

Unity - Scripting API: PointerEventData

Robert Yang - 2018-12-02T21:03:01

To use PointerEventData, you need to add the appropriate interface and implement the event... for example, see Selectable.OnPointerEnter:

Unity - Scripting API: SystemInfo

Barnaby Smith - 2018-12-02T19:42:23

Also for iOS (2017.3.1):

batteryLevel: 0.88
batteryStatus: Charging
copyTextureSupport: Basic, Copy3D, DifferentTypes, TextureToRT, RTToTexture
deviceModel: iPhone9,3
deviceName: [REDACTED NAME]
deviceType: Handheld
deviceUniqueIdentifier: [REDACTED HASH]
graphicsDeviceID: 0
graphicsDeviceName: Apple A10 GPU
graphicsDeviceType: Metal
graphicsDeviceVendor: Apple
graphicsDeviceVendorID: 0
graphicsDeviceVersion: Metal
graphicsMemorySize: 512
graphicsMultiThreaded: True
graphicsShaderLevel: 45
graphicsUVStartsAtTop: True
maxCubemapSize: 4096
maxTextureSize: 4096
npotSupport: Full
operatingSystem: iOS 12.0
operatingSystemFamily: Other
processorCount: 2
processorFrequency: 0
processorType: arm64
supportedRenderTargetCount: 8
supports2DArrayTextures: True
supports3DRenderTextures: True
supports3DTextures: True
supportsAccelerometer: True
supportsAsyncCompute: False
supportsAudio: True
supportsComputeShaders: True
supportsCubemapArrayTextures: False
supportsGPUFence: False
supportsGyroscope: True
supportsImageEffects: True
supportsInstancing: True
supportsLocationService: True
supportsMotionVectors: True
supportsMultisampledTextures: 1
supportsRawShadowDepthSampling: True
supportsRenderToCubemap: True
supportsShadows: True
supportsSparseTextures: False
supportsTextureWrapMirrorOnce: 0
supportsVibration: True
systemMemorySize: 2002
unsupportedIdentifier: n/a
usesReversedZBuffer: True

Unity - Scripting API: MonoBehaviour.OnDisable()

Sergio Bonfiglio - 2018-11-19T17:15:53

Notice that OnDisable will be called AFTER the GameObject has been disabled, so this function is not suitable for any last-minute Animator configurations or any other process that requires the GameObject to be active.

Unity - Scripting API: SystemLanguage

Robert Yang - 2018-11-18T22:09:05

In older versions of Unity (e.g. 5.6.6f2 and before) one of these enums reads "Hugarian" (instead of "Hungarian")

Creating and Using Materials

Thomas Ingram - 2018-11-15T03:42:19

If you have a shader selected when you create a material, it will automatically use the selected shader!

Unity - Scripting API: MonoBehaviour.OnValidate()

Thomas Ingram - 2018-11-11T06:45:17

Do not cache variables with a null check in OnValidate unless they are global, as if you Copy-Paste Component variables the values will be set, and no longer contextual to your current MonoBehaviour.

Unity - Scripting API: PropertyName

Thomas Ingram - 2018-11-06T22:20:37

If you're using PropertyNames for ReferenceValues in PlayableDirector bindings (ie. for ExposedReferences in TimelineClips) the usage of these variables is to:
- Create a new PropertyName with your own generated GUID.
- Assign the PropertyName to your exposedName.
- SetReferenceValue with that PropertyName and your binding.

If you attempt to use the original exposedName it will be :0, an empty PropertyName. This value will then be used for all unexposed properties, and that's definitely not something you want to be doing!

Unity - Scripting API: MenuItem

Thomas Ingram - 2018-11-01T06:06:21

If you're using simple shortcuts with shift key alone (ie. SHIFT-X) that keyboard event will be consumed regardless of whether you have a validation method or not.
So when you're inevitably focused in a Text Field or Area, you can no longer type that capital letter.
My workaround involves:

if (EditorGUIUtility.editingTextField) {
EditorWindow focused = focusedWindow;
if (focused != null) {
Event keyboardEvent = Event.KeyboardEvent("X");
keyboardEvent.character = 'X'; //The variable that TextFields seem to actually use.
keyboardEvent.modifiers = EventModifiers.Shift;
keyboardEvent.shift = true;
return false;
return true;

in the validation function for your shortcut.

Unity - Manual: Streaming Assets

Jon Huffman - 2018-10-10T20:12:46

Pulled this from the general page on special folder:
You can only have one StreamingAssets folder and it must be placed in the root of the Project; directly within the Assets folder.

Unity - Scripting API: MinMaxCurve

plaw - 2018-10-09T15:31:44

I've been trying to create a Timeline playable to manipulate this, the particle system that's setup required 'Random between two Constants', once getting the StartLifeTime updating via the timeline working I found that the ConstantMax value was always double of what I wanted it to be. An hour or so later I found out constant and constantMax are not treated separately, so doing the following was setting the value twice.

curveA.constant += curveB.constant * weight;
curveA.constantMin += curveB.constantMin * weight;
curveA.constantMax += curveB.constantMax * weight;

Unity - Scripting API: TextAsset

PsyKaw - 2018-10-04T16:06:56

.bytes is a getter, keep it mind and set in cache the result by calling it once.

Unity - Manual: Sprite Packer

Eran Arbel - 2018-10-04T08:26:34

Sprite Packer will be deprecated in the future. Best switch to Sprite Atlas.

Unity - Scripting API: MonoBehaviour

Sergio Bonfiglio - 2018-09-24T16:22:40

Despite it implying that the checkbox is only related to

It will also prevent OnDestroy() from being called upon object destruction if said object has never been enabled, therefore leaving us without a reliable destructor function.

Unity - Scripting API: EditorGUI.Foldout

Thomas Ingram - 2018-09-18T05:22:48

You can style a Toggle like a Foldout by providing EditorStyle.foldout to the Toggle and it will function the same but in some cases (like when not provided a label) the Toggle will function where the Foldout may not.

Unity - Scripting API: SpriteMetaData.rect

Josh Killinger - 2018-09-13T16:02:52

SpriteMetaData.rect is in pixel values, not normalized values.


haowan - 2018-09-13T13:13:02

This function is called DeleteArrayElementAtIndex, but if you call it on a nullable type and the element is not null, it sets the element to null and leaves it there instead of deleting it.

Unity - Scripting API: WWW.EscapeURL

Barnaby Smith - 2018-09-12T13:17:32


Unity - Scripting API: GUIUtility.GetStateObject

sugoidev - 2018-09-02T16:08:52

Some actual info and usage on this are in this post:

Unity - Scripting API: EditorGUILayout.GetControlRect

sugoidev - 2018-09-02T16:08:23

Gives weird results in EventType.Layout

Unity - Scripting API: WebCamTexture.WebCamTexture

Eran Arbel - 2018-09-02T10:48:32

If you precache the device names you want to use, you can save on some performance when you actually need it.
It switches from front to back quick and easy but make sure you null check important things like the texture.


Robert Yang - 2018-08-30T21:00:24

ok what this actually does is: it checks if the file already exists -- and if it does, it appends "1" or "2" etc to the end of the filename, e.g:

// outputs "Assets/Rules.xml" if "Assets/Rules.xml" file does not already exist.
// if "Assets/Rules.xml" already exists it outputs "Assets/Rules 1.xml"

Unity - Scripting API: AnimationEvent

Eran Arbel - 2018-08-28T09:22:14

Do note that animation events are attached to animations, not animators or objects. It is invoked whenever the animation reaches it. But, if it can't, nothing happens.

Unity - Scripting API: EditorGUILayout.TextArea

Robert Yang - 2018-08-27T18:59:53

At least in 2018.2, you cannot normally access the TextEditor (to control keyboard cursor / caret position or selection) on EditorGUILayout.TextArea... unless you use reflection!
// see
TextEditor tEditor = typeof(EditorGUI).GetField("activeEditor", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null) as TextEditor;

Unity - Scripting API: GUILayout.TextArea

Robert Yang - 2018-08-27T18:57:09

If you want cut / copy / paste support in editor, make sure you use EditorGUILayout.TextArea (warning: on these Editor classes, you can't access TextEditor without reflection!)

Unity - Scripting API: GUI.TextArea

Robert Yang - 2018-08-27T18:56:28

If you want cut / copy / paste support in editor, make sure you use EditorGUI.TextArea or EditorGUILayout.TextArea (warning: on these Editor classes, you can't access TextEditor without reflection)

Unity - Scripting API: AssetDatabase.Refresh

Robert Yang - 2018-08-27T18:53:58

if you just want to refresh one (or a few) assets, you can use AssetDatabase.ImportAsset() instead

Unity - Scripting API: Compilation.AssemblyBuilder.additionalReferences

Anthony Marmont - 2018-08-26T18:51:25

To get this to work with Assembly Definition Files you need to enter the path of where Unity builds the DLLs relative to the project folder. Below is an example.

assemblyBuilder.additionalReferences = new string[] { "Library/ScriptAssemblies/MyAssembly.dll" };

Unity - Scripting API: UnityEvent

Eran Arbel - 2018-08-22T11:14:04

Are there any known lists for things that can be called via the no-argument event?

Unity - Scripting API: SystemInfo.operatingSystem

tenpn - 2018-08-21T12:20:13

Also "iOS 11.2.6", "iPhone OS 11.0" on iOS

Unity - Scripting API: SystemInfo.operatingSystem

tenpn - 2018-08-21T11:34:53

I've also seen "Android OS 7.1.2 / API-25 (NJH47F/4146041)" as output on android

Unity - Scripting API: KeyCode.Plus

Ido Adler - 2018-08-21T08:21:34

If you do not have an actual plus key on your keyboard, use KeyCode.Equals. If you need check for the shift key as well.

Unity - Scripting API: AudioSource.PlayOneShot

tenpn - 2018-08-16T09:37:40

A one-shot clip cannot be stopped, and the clip property of the AudioSource won't be updated to refer to it.

Unity - Manual: Font

Barnaby Smith - 2018-08-14T16:03:48

As szymon112233 says putting them on new lines won't separate them, as commas are required to delimit the names. You can still put them on new lines however as long as you still delimit with commas, e.g.


Unity - Scripting API: AssetDatabase.CreateAsset

Robert Yang - 2018-08-10T23:45:25

If you want to create text or script files with a template, you can use undocumented internal UnityEditor.CreateScriptAsset("Assets/YourTemplatesScript.cs.txt", "DefaultNewScriptName.cs"); via reflection...

private static MethodInfo createScriptMethod = typeof(ProjectWindowUtil)
.GetMethod("CreateScriptAsset", BindingFlags.Static | BindingFlags.NonPublic);

static void CreateScriptAsset(string templatePath, string destName) {
createScriptMethod.Invoke(null, new object[] { templatePath, destName });

for more details, see

Unity - Manual: Searching

Thomas Ingram - 2018-08-09T02:01:48

You can search for references to Objects (eg. individual Components) via their instance ID with: ref:instanceID:

Creating and Using Materials

Thomas Ingram - 2018-08-07T02:59:51

You can control-click on a texture field to show a larger preview of that texture.

Unity - Scripting API: EditorGUILayout.MaskField

Barnaby Smith - 2018-08-06T13:11:11

Nothing and Everything are options that Unity adds to your supplied options with special integer values:

0 = Nothing
-1 = Everything - note using int.MaxValue will not display as Everything, instead it will show Mixed with all values set

Unity - Scripting API: AddComponentMenu

Thomas Ingram - 2018-08-01T04:41:48

You can use this attribute with an empty string to hide a component from the Add Component list.

Unity - Scripting API: ModelImporter.globalScale

Anomalous Underdog - 2018-07-21T19:24:32

This is the same as the "Scale Factor" in a model's import settings. https://uploads.disquscdn.c...

Unity - Manual: Ignore files

Jon Hallier - 2018-07-14T08:12:43

To exclude an entire folder or directory from Collaborate use: folder name/**
e.g. Assets/Standard Assets/**


houkanshan - 2018-07-08T09:13:12

Show / hide outline & wireframe of selected object:

[MenuItem("Utility/Show WireFrame %h")]
static void Show() {
foreach(GameObject h in Selection.gameObjects) {
var rend = h.GetComponent<renderer>();
if (rend)
EditorUtility.SetSelectedRenderState(rend, EditorSelectedRenderState.Highlight | EditorSelectedRenderState.Wireframe);

[MenuItem("Utility/Show WireFrame %h", true)]
static bool CheckShow() {
return Selection.activeGameObject != null;

[MenuItem("Utility/Hide WireFrame %h")]
static void Hide() {
foreach(GameObject h in Selection.gameObjects) {
var rend = h.GetComponent<renderer>();
if (rend)
EditorUtility.SetSelectedRenderState(rend, EditorSelectedRenderState.Hidden);

[MenuItem("Utility/Hide WireFrame %h", true)]
static bool CheckHide() {
return Selection.activeGameObject != null;

Unity - Scripting API: Networking.ClientScene.RegisterPrefab

Luís Fonseca - 2018-06-28T13:27:17

This example is wrong. The prefab registration should be done on Awake and not on OnStartClient.
See this:

Unity - Scripting API: AssetDatabase.DeleteAsset

Robert Yang - 2018-06-26T04:00:47

make sure you use DestroyImmediate() if deleting a sub-asset (and then re-save or re-import the asset afterwards)

Unity - Scripting API: AssetDatabase.AddObjectToAsset

Robert Yang - 2018-06-26T03:57:16

to access sub-assets later, see AssetDatabase.LoadAllAssetRepresentationsAtPath ... to get the main asset path, use AssetDatabase.GetAssetPath

Unity - Scripting API: Time.unscaledDeltaTime

Barnaby Smith - 2018-06-20T10:22:05

Note that unscaledDeltaTime does not always behave the same as deltaTime even when timeScale is 1. unscaledDeltaTime will increase when the game is in the background, if the game isn't updating for 10 seconds then when you come back unscaledDeltaTime will be about 10 seconds whereas deltaTime will likely be a very small value. More details at

Unity - Scripting API: UI.Dropdown.AddOptions

tenpn - 2018-06-19T12:54:00

since there's no link from here to OptionData:

Unity - Scripting API: Editor.OnInspectorGUI

Robert Yang - 2018-06-19T00:40:08

There's several ways to get the "width" of the Inspector window, see:

- EditorGUIUtility.currentViewWidth might help
- EditorGUIUtility.fieldWidth is supposed to take the Inspector scrollbar into account

There's also a *nasty* rumor that Screen.width will return the width of the inspector, when called from OnInspectorGUI() ?!?!...

Unity - Scripting API: Rendering.CommandBuffer.SetRenderTarget

XRA - 2018-06-12T05:06:18

Important note, when targeting Texture3D or Texture2DArrays, if you want to use uint slice : SV_RenderTargetArrayIndex; for writing into multiple slices within the geometry shader, you must use _cmd.SetRenderTarget( targetName, 0, CubemapFace.Unknown, -1 );

Unity - Scripting API: MaterialPropertyDrawer

Graham H Reeves - 2018-06-11T11:18:25

You can add custom parameters to your custom drawer by adding a matching constructor.
`[RangeMinMax(0,100)]SomeValue("SomeValue", VECTOR ) = (0,0,0,0)`

and in C#
`public class RangeMinMaxDrawer : MaterialPropertyDrawer
float Min,Max;
public RangeMinMaxDrawer(float Min,float Max)
this.Min = Min;
this.Max = Max;

Unity - Scripting API: AssetDatabase.FindAssets

Thomas Ingram - 2018-06-08T05:01:38

If you want to search within assets and packages you can use "Assets" and "Packages" in the searchInFolders parameter.


Barnaby Smith - 2018-06-04T01:31:40

Note that you should never wrap a [RuntimeInitializeOnLoadMethod] in an if def as it will not behave as expected. Instead you can put your if def inside the method body.

For full details on how this attribute behaves strangely with if defs see


Barnaby Smith - 2018-06-03T16:15:49

For personal licenses you can find your Team ID by:
- Open Xcode
- Setting your team to personal, then save
- Open Unity-iPhone.xcodeproj/project.pbxproj in a text editor
- Find the line that starts with 'DevelopmentTeam = ' and ends in a hash, this hash is your Team ID

Note that the Team ID setting is shared between all projects on a machine, it is not stored in each project's ProjectSettings.asset file like most of the PlayerSettings.iOS class.

Unity - Scripting API: XR.InputTracking.

Tenebrous - 2018-05-31T16:36:12

Does not work in 2018.2.0b5 or above, probably related to

Unity - Scripting API: XR.XRNodeState.uniqueID

Tenebrous - 2018-05-31T16:34:20

Prior to 2018.2.0b5, uniqueID is not actually unique - For example, the HTC Vive has the same uniqueID for three seperate nodes - Left Eye, Right Eye, and Head.

As of 2018.2.0b6, uniqueID is unique, BUT InputTracking.GetNodeName( uniqueID ) no longer works.

Script compilation and assembly definition files

Thomas Ingram - 2018-05-31T01:31:19

The "new" layout is split all your scripts into "Editor" and "Runtime" - seeing as all packages currently use this layout, it's advisable to transition your scripts to this layout.

Script compilation and assembly definition files

haowan - 2018-05-30T15:36:58

I recommend not using asmdef files if you use assets that have a lot of Editor folders strewn around the hierarchy, as you'll end up having to create an assembly definition for each editor folder if you want to make builds.

Managed bytecode stripping with IL2CPP

Barnaby Smith - 2018-05-29T00:22:23

By default specifying an assembly in link.xml will require it to be present at link stage otherwise you may get an error.

You can mark an assembly as optional by adding the following attribute: ignoreIfMissing="1"

for example

<assembly fullname="UnityEngine.Analytics" ignoreIfMissing="1">

Unity - Scripting API: MonoBehaviour.Start()

Thomas Ingram - 2018-05-25T01:13:03

If Start returns a IEnumerator, it will be treated as a Coroutine and will successfully be scheduled.

Unity - Manual: Unity Test Runner

Nikkolai Davenport - 2018-05-21T15:24:12

The version of NUnit packaged with Unity can be found by locating and viewing properties of the nunit.framework.dll.

The nunit.framework.dll is located within the Unity install directory, in folder path Data\Managed.

Unity 2018.1.0f2 includes NUnit

Unity - Scripting API: MonoBehaviour.OnDrawGizmos()

Thomas Ingram - 2018-05-19T06:05:29

If using a custom editor you can implement Gizmos using the DrawGizmoAttribute. This has a selection and deselection parameter that's more flexible than the messages sent to the object.

Unity - Manual: Publishing Builds

Thomas Ingram - 2018-05-14T06:35:56

Fun fact! Windows Unity .exe launcher files are all the same! They will open any _Data folder next to them that shares the same name.

Unity - Scripting API: QualitySettings.vSyncCount

timsoret - 2018-05-13T01:24:37

VSync caps the framerate to even divisions of the monitor's frequency.

For example, with a 60hz monitor
QualitySettings.vSyncCount = 0; // uncapped FPS
QualitySettings.vSyncCount = 1; // 60/2 = 30fps
QualitySettings.vSyncCount = 2; // 60/3 = 20fps
QualitySettings.vSyncCount = 3; // 60/4 = 15fps

With a 144hz monitor
QualitySettings.vSyncCount = 0; // uncapped FPS
QualitySettings.vSyncCount = 1; // 144/2 = 72fps
QualitySettings.vSyncCount = 2; // 144/3 = 48fps
QualitySettings.vSyncCount = 3; // 144/4 = 36fps

Keep in mind that more & more users are equipped with screens capable of adaptative-sync (Freesync from AMD, or G-SYNC from Nvidia). These screens adapt their refresh rate to the fluctuating framerate, and require uncapped framerate. So considering that VSync is not always desirable, provide users a way to set this value themselves, either through an option menu or a console, and it's even better if you help them understand what's happening under the hood with a tooltip or a description so they can enjoy the best possible conditions.

Example script:

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

public class FramerateSettings : MonoBehaviour {

[Range(0, 4)]
public int vSyncCount = 0;
public int maxFPS = 144;

void Awake () {
ApplySettings ();

void OnValidate () {
ApplySettings ();

void ApplySettings() {
Application.targetFrameRate = maxFPS;
QualitySettings.vSyncCount = vSyncCount;

Unity - Scripting API: Unity.Collections.Allocator.Persistent

Thomas Ingram - 2018-05-11T03:06:53

Allocator.Persistent is the slowest allocation, but lasts throughout the application lifetime. It is a wrapper for a direct call to malloc. Longer jobs may use this NativeContainer allocation type.

Unity - Scripting API: Unity.Collections.Allocator.TempJob

Thomas Ingram - 2018-05-11T03:06:46

Allocator.TempJob is a slower allocation than Temp, but is faster than Persistent. It is intended for allocations with a lifespan of 4 frames or fewer and is thread-safe. Most short jobs use this NativeContainer allocation type.

Unity - Scripting API: Unity.Collections.Allocator.Temp

Thomas Ingram - 2018-05-11T03:06:38

Allocator.Temp has the fastest allocation. It is intended for allocations with a lifespan of 1 frame or fewer and is not thread-safe. Temp NativeContainer allocations should call the Dispose method before you return from the function call.

Unity - Scripting API: AssetDatabase.DeleteAsset

Thomas Ingram - 2018-05-10T01:54:04

There can be issues with Unity not managing the solution correctly (Error CS2001: Source file could not be found) when creating/moving files, operating on them, and then deleting them. You must use AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport) to avoid these issues.

Unity - Manual: Command line arguments

Jon Huffman - 2018-05-09T13:47:13

Though it does not list it, it appears that cleanedLogFile is still a valid parameter. Syntax follows
-cleanedLogFile <path_to_output>

This appears to dump the editor's logs to a standalone file for the duration of execution.


tenpn - 2018-05-08T10:03:34

On iOS the identifierForVendor can change if all vendor apps are uninstalled. If you're not using the value for advertising, you can consider storing the value in the device's keychain on first install and retrieving from there on subsequent installs.


tenpn - 2018-05-03T10:05:02

On Android it attempts to use the device ID if the telephony permission is available, then the android ID, then the mac address, but there's some complexity outlined here:

Unity - Scripting API: GameObject.tag

Thomas Ingram - 2018-05-02T12:49:31

Use Component.CompareTag to compare tags instead of == or Equals as it's optimised for the purpose.

Unity - Scripting API: Camera.ScreenToWorldPoint

Simon (darkside) J - 2018-04-29T09:15:20

This information seems out of date, as testing shows the Y value is no longer inverted.

Unity - Scripting API: Editor.OnSceneGUI()

Thomas Ingram - 2018-04-28T02:59:33

If you want to draw IMGUI content in OnSceneGUI you can do this within Handles.BeginGUI() and Handles.EndGUI()

Unity - Scripting API: Graphics.DrawTexture

Thomas Ingram - 2018-04-19T04:17:56

If providing your own Material - it will not be clipped under other GUI elements.
To fix this provide a Shader with the following layout additions:

sampler2D _GUIClipTexture;
uniform float4x4 unity_GUIClipTextureMatrix;

struct v2f {
float2 clipUV : TEXCOORD1;

v2f vert (appdata_t v) {
float3 eyePos = UnityObjectToViewPos(v.vertex);
o.clipUV = mul(unity_GUIClipTextureMatrix, float4(eyePos.xy, 0, 1.0));

fixed4 frag (v2f i) : SV_Target {
col.a *= tex2D(_GUIClipTexture, i.clipUV).a;

Unity - Scripting API: AssetDatabase.ImportAsset

Thomas Ingram - 2018-04-17T03:08:19

If importing a large number of assets it's quicker to call AssetDatabase.SaveAssets after modifying assets, as currently you cannot use AssetDatabase.StopAssetEditing without crashing Unity if you're calling ImportAsset or AddObjectToAsset.

Unity - Manual: ShaderLab: Properties

Graham H Reeves - 2018-04-11T15:35:30

There are a lot of options to effect the Inspector for your material documented on this page, but not above;

Unity - Scripting API: GameObject.CreatePrimitive

Thomas Ingram - 2018-04-08T00:58:55

If you just want the primitive meshes you can call:
with TYPE being : "New-Sphere.fbx", "New-Capsule.fbx", "New-Cylinder.fbx", "Cube.fbx", "New-Plane.fbx", or "Quad.fbx".

Unity - Manual: Preferences

Thomas Ingram - 2018-04-08T00:17:36

Editor Attaching makes it possible to attach a C# debugger at any time, but it causes Mono JIT to insert a whole lot of “should I handle debugger right now?” checks in compiled code all over the place.
“Heavy” C# code can run 2-3x slower in the editor, so watch out!
Changing this will require a restart of the editor.

Unity - Scripting API: HumanPoseHandler.SetHumanPose

Thomas Ingram - 2018-04-06T11:16:14

SetHumanPose on Optimised GameObject Hierarchies seems to do nothing. (If you find differently I'd love to hear about it!)

Unity - Scripting API: EditorGUILayout.MaskField

Thomas Ingram - 2018-04-06T08:30:26

If you want your MaskField to look like a button you might think to pass GUIContent.none to label and use a relevant GUISkin. The MaskField will draw text of its own, the way to fix this is to make your own GUIStyle with imagePosition set to ImagePostion.ImageOnly.

Unity - Manual: Unity Test Runner

Thomas Ingram - 2018-04-05T01:36:22

When using the Test Runner with Assembly Definition files you need to have a asmdef file with Test Assemblies ticked to use the UnityEngine.TestTools and NUnit namespaces. The Test Runner window has a button that will automate this process.

Unity - Scripting API: MonoBehaviour.Reset()

Thomas Ingram - 2018-04-05T00:51:09

This function is called before deserialization, this means that when it gets called after a Paste Component As New operation you both cannot operate on data you expect to be on the object, nor can you expect your default values to persist in this case.

Unity - Scripting API: RenderTexture.GetTemporary

Thomas Ingram - 2018-04-04T01:24:10

Temporary RenderTextures may not be Created. You may need to call Create before use.

Unity - Scripting API: Graphics.Blit

Thomas Ingram - 2018-04-03T11:24:48 is set by this function. When using it in many contexts you may need to cache the active RenderTexture and restore it to maintain normal behaviour.


Thomas Ingram - 2018-03-25T11:21:30

This is not called in Edit mode without the [ExecuteInEditMode] tag.


Thomas Ingram - 2018-03-24T12:24:19

This is not called in Edit Mode without the [ExecuteInEditMode] tag - along with OnRenderObject.

Unity - Scripting API: MonoBehaviour.OnRenderObject()

Thomas Ingram - 2018-03-24T12:22:41

This is not called in Edit Mode without the [ExecuteInEditMode] tag - along with OnWillRenderObject.

Rendering with Replaced Shaders

Thomas Ingram - 2018-03-22T04:36:20

For the replacementTag variable, the string you provide is the tag Key, like "RenderType" and each of the original shaders need to have matching associated Value (eg. "Opaque") in the replacement sub shaders or else they are not drawn.

Unity - Scripting API: MonoBehaviour.FixedUpdate()

Thomas Ingram - 2018-03-18T10:15:36

Ensure that if you are using Input functions that you use Update, and hold that state for FixedUpdate. FixedUpdate doesn't run in sync with Update or LateUpdate.

Unity - Scripting API: GameObject.AddComponent

DeadJay - 2018-03-16T15:52:26

The generic version also returns to the specified generic type. You can write it without the 'as ...' portion.

var sc = gameObject.AddComponent< SphereCollider >();


Thomas Ingram - 2018-03-15T04:54:20

You can use EditorUserBuildSettings.selectedBuildTargetGroup to get the current selected build target.

Unity - Scripting API: Selection.activeGameObject

Barnaby Smith - 2018-03-14T13:10:55

When setting Selection.activeGameObject you often want to highlight the newly selected object in the hierarchy, to do this call EditorGUIUtility.PingObject()

Selection.activeGameObject = newObject;

Unity - Scripting API: Mathf.Clamp

tenpn - 2018-03-12T17:27:39

the Max is inclusive

Unity - Scripting API: AssetDatabase.LoadAssetAtPath

Thomas Ingram - 2018-03-07T07:45:26

If you're trying to load an asset from a Package the relative path is "Packages/com.example.example/...", regardless of the 'real' location of the package files.

Script compilation and assembly definition files

Thomas Ingram - 2018-03-07T01:52:33

You can have assembly definition references to packages' asmdef files, eg. com.unity.postprocessing.runtime.
To set these up your need to navigate the Project View to the package directory in question. This can be done by adding a script from the package as a component, switching to debug mode, and clicking on the script field.
Navigate to the relevant assembly definition used by that package and drag it into the references field.

These references will survive the process of creating a package out of your own files. This means that you can make your package.json manifest file contain a dependency for the referenced package, and use the assembly references to define linking and compilation order. Your package will download the referenced package using the package manifest dependencies, and compile correctly.

Unity - Scripting API: AssetDatabase.CopyAsset

Thomas Ingram - 2018-03-06T23:57:47

If you are using CopyAsset, and then DeleteAsset for script files you need to call ImportAsset before deleting.
If you do not call ImportAsset the DeleteAsset call will remove the asset, but the .csproj + cache will still think the script exists, and will complain: error CS2001: Source file `TScript.cs' could not be found, forcing you to restart Unity to resolve the issue.

Unity - Scripting API: InitializeOnLoadAttribute

Thomas Ingram - 2018-03-05T23:09:25

This will not be called if there are compilation errors, regardless of whether the Assembly your script is in has compiled.

Unity - Scripting API: PackageManager.Client.Add

Thomas Ingram - 2018-03-03T10:14:26

This can be called after a Package has been already added without an issue.
If you wish to use this to rely on packages, you need to wrap code that has dependencies into preprocessor directives so your code will still compile, allowing this to be run.

Unity - Scripting API: Compilation.AssemblyBuilder.additionalReferences

Thomas Ingram - 2018-02-22T00:59:33

When using Assembly Definition Files adding additional references to the list will result in the hierarchical nature of the file to be lost and become a manual process. (Tested 2018.1.0b4)

Unity - Scripting API: DidReloadScripts

Thomas Ingram - 2018-02-21T00:00:00

Helpful related callbacks about assembly reloading can be found here:

Unity - Scripting API: IPreprocessBuild

tenpn - 2018-02-19T16:56:48

Don't forget callbackOrder from IOrderedCallback, although it's not clear what the default value is.

Unity - Scripting API: Canvas.ForceUpdateCanvases

Robert Yang - 2018-02-19T05:49:29

If you're looking at this page, then you actually want is probably LayoutRebuilder.ForceLayoutRebuildImmediate(), to force UI elements to update itself, e.g. force a deeply nested LayoutGroup to re-space its children based on new rect sizes, etc

Unity - Scripting API: SystemInfo.graphicsMemorySize

Robert Yang - 2018-02-19T05:39:29

Be warned that this is a pretty useless stat in practice; I think Windows will automatically allocate more memory for onboard GPUs.

Unity - Scripting API: SystemInfo

Robert Yang - 2018-02-19T05:38:13

If you're looking for an easy way to auto-detect some decent first run settings, be warned that almost all the SystemInfo stuff (number of threads, graphics memory available, etc) is very unreliable. Basically the only two metrics you might be able to use are SystemInfo.graphicsShaderLevel (< 45 means it's a DX10, pre-OpenGL3, or older GPU, like a pretty old Intel integrated card)... supportsSparseTextures also seems like an OK indicator for whether it's a fairly recent higher-end GPU that supports DX11.2+

Unity - Scripting API: EditorWindow

Henry de Jongh - 2018-02-14T21:02:36

Here is a little code snippet in case you wish to know whether your editor window is docked:

private MethodInfo isDockedMethod = null;

/// <summary>Gets a value indicating whether this window is docked.</summary>
/// <value><c>true</c> if this window is docked; otherwise, <c>false</c>.</value>
private bool isDocked
if (isDockedMethod == null)
isDockedMethod = typeof(EditorWindow).GetProperty("docked", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static).GetGetMethod(true);
return (bool)isDockedMethod.Invoke(this, null);

Unity - Scripting API: StaticBatchingUtility.Combine

Simon Fawcett - 2018-02-14T17:09:52

You need to have Read/Write Enabled ticked in the import settings

Unity - Scripting API: UI.Button.onClick

Eran Arbel - 2018-02-13T09:19:00

You are correct. This should be reported.

Unity - Scripting API: GUILayout.ExpandHeight

Thomas Ingram - 2018-02-12T02:18:53

GUI content may expand to fill a space provided by MaxHeight if the provided GUIStyle has stretchHeight set.

Unity - Scripting API: Application.targetFrameRate

Robert Yang - 2018-02-11T22:04:26

For desktop, it's highly recommended to *always* set this to something like 60 or 120, just to clamp the framerate -- otherwise systems running at very high framerates without vsync can shoot up to like 1000 FPS and cause weird bugs or errors.

Unity - Scripting API: MatchTargetWeightMask.MatchTargetWeightMask

justcherie - 2018-02-06T23:48:32

Weighting note: 1 is full weight, 0 is no weight. E.g. MatchTargetWeightMask(, 0) is a mask representing full positional weight with no rotation weight


Michael Chugg - 2018-02-06T18:37:06

In Editor, what is seen via the scene view's camera will trigger the skinnedMeshRenderer to update when updateWhenOffscreen is true. To avoid this issue, hide the scene view with a different tab.

Unity - Scripting API: GameObject.GameObject

Barnaby Smith - 2018-02-04T19:48:50

To create a new GameObject that has a RectTransform (such as for use in UI), you should supply the RectTransform type in the third parameter, i.e.

new GameObject("GameObject", typeof(RectTransform));

This is particularly useful if extending Unity editor, such as through this menu item for creating a new GameObject as a sibling of the selection:

[MenuItem("GameObject/Create Sibling", false, 0)]
static void CreateSibling()
List<unityengine.object> newSelection = new List<unityengine.object>();
foreach (Transform selectedTransform in Selection.transforms)
GameObject newSibling;

if(selectedTransform.GetComponent<recttransform>() != null)
newSibling = new GameObject("GameObject", typeof(RectTransform));
newSibling = new GameObject("GameObject");

Undo.RegisterCreatedObjectUndo(newSibling, "Create Sibling");

newSibling.transform.SetParent(selectedTransform.parent, false);
newSibling.transform.SetSiblingIndex(selectedTransform.GetSiblingIndex() + 1);

Selection.objects = newSelection.ToArray();

Unity - Scripting API: VideoPlayer

Mario Gutierrez - 2018-02-01T05:10:33

For WebGL builds, the video source must be set to URL. The video can be placed in a StreamingAssets folder and this path can be used for the URL.

Unity - Scripting API: Video.VideoPlayer.isPlaying

Mario Gutierrez - 2018-02-01T05:05:00

Doesn't seem to work even when calling Prepare() beforehand. More accurate to check if the frame is past 0 or other small number.

Unity - Scripting API: Physics.IgnoreCollision

Henry de Jongh - 2018-01-28T11:27:49

Another limitation: There appears to be no way to query whether a collision between two colliders is currently ignored.

Unity - Scripting API: Application.persistentDataPath

tenpn - 2018-01-25T10:25:13

When running in the editor in windows 10, this path is ~/AppData/LocalLow/{Company Name}/{Product Name}/

Unity - Scripting API: SceneManagement.SceneManager.sceneCount

tenpn - 2018-01-24T15:31:13

Using this in a for() lets you iterate loaded scenes through GetSceneAt(i)

Unity - Scripting API: Event.Use

Roy Zwart - 2018-01-22T15:08:21

Event.Use() will stop the event from being used after your code, but the Scene view will keep registering mouse clicks unless you use the following code. The important part is GUIUtility.hotControl = 0; which will indicate that no control is currently active and prevent the unwanted selection of gameobject for example.

void OnSceneGUI () {
Event e = Event.current;

var controlID = GUIUtility.GetControlID(FocusType.Passive);
var eventType = e.GetTypeForControl(controlID);
if (eventType == EventType.MouseUp) {
Debug.Log("Mouse Up!");
GUIUtility.hotControl = controlID;
else if (eventType == EventType.MouseDrag) {
Debug.Log("Mouse Drag!");
else if (eventType == EventType.MouseDown) {
Debug.Log("Mouse Down!");
GUIUtility.hotControl = 0;

(from: EventType.MouseUp not working on Left Clicks.)

Unity - Manual: Log Files

Tony Coculuzzi - 2018-01-18T00:14:44

For Android:
Using "adb logcat -s Unity" will filter the log to only show you Unity-specific log data.

Unity - Scripting API: EditorGUI.DrawRect

S. Darkwell - 2018-01-15T10:35:01

Although it is stated on this page "You can also use them to simulate statistics in the Editor, for example, an in-Editor health bar", there is a notable overhead to using EditorGUI.DrawRect which makes it unsuitable for more complex representations (eg: point graphs). In situations such as the aforementioned point graph, it is significantly more performant to create and cache a Texture2D any time the underlying values are changed and to display that Texture2D as the GUIContent of a LabelField.

Unity - Scripting API: SystemInfo

Barnaby Smith - 2018-01-14T13:00:48

As of Unity 2017.3.0, this prints all SystemInfo properties

string systemInfoMessage = "";
systemInfoMessage += "batteryLevel: " + SystemInfo.batteryLevel + "\n";
systemInfoMessage += "batteryStatus: " + SystemInfo.batteryStatus + "\n";
systemInfoMessage += "copyTextureSupport: " + SystemInfo.copyTextureSupport + "\n";
systemInfoMessage += "deviceModel: " + SystemInfo.deviceModel + "\n";
systemInfoMessage += "deviceName: " + SystemInfo.deviceName + "\n";
systemInfoMessage += "deviceType: " + SystemInfo.deviceType + "\n";
systemInfoMessage += "deviceUniqueIdentifier: " + SystemInfo.deviceUniqueIdentifier + "\n";
systemInfoMessage += "graphicsDeviceID: " + SystemInfo.graphicsDeviceID + "\n";
systemInfoMessage += "graphicsDeviceName: " + SystemInfo.graphicsDeviceName + "\n";
systemInfoMessage += "graphicsDeviceType: " + SystemInfo.graphicsDeviceType + "\n";
systemInfoMessage += "graphicsDeviceVendor: " + SystemInfo.graphicsDeviceVendor + "\n";
systemInfoMessage += "graphicsDeviceVendorID: " + SystemInfo.graphicsDeviceVendorID + "\n";
systemInfoMessage += "graphicsDeviceVersion: " + SystemInfo.graphicsDeviceVersion + "\n";
systemInfoMessage += "graphicsMemorySize: " + SystemInfo.graphicsMemorySize + "\n";
systemInfoMessage += "graphicsMultiThreaded: " + SystemInfo.graphicsMultiThreaded + "\n";
systemInfoMessage += "graphicsShaderLevel: " + SystemInfo.graphicsShaderLevel + "\n";
systemInfoMessage += "graphicsUVStartsAtTop: " + SystemInfo.graphicsUVStartsAtTop + "\n";
systemInfoMessage += "maxCubemapSize: " + SystemInfo.maxCubemapSize + "\n";
systemInfoMessage += "maxTextureSize: " + SystemInfo.maxTextureSize + "\n";
systemInfoMessage += "npotSupport: " + SystemInfo.npotSupport + "\n";
systemInfoMessage += "operatingSystem: " + SystemInfo.operatingSystem + "\n";
systemInfoMessage += "operatingSystemFamily: " + SystemInfo.operatingSystemFamily + "\n";
systemInfoMessage += "processorCount: " + SystemInfo.processorCount + "\n";
systemInfoMessage += "processorFrequency: " + SystemInfo.processorFrequency + "\n";
systemInfoMessage += "processorType: " + SystemInfo.processorType + "\n";
systemInfoMessage += "supportedRenderTargetCount: " + SystemInfo.supportedRenderTargetCount + "\n";
systemInfoMessage += "supports2DArrayTextures: " + SystemInfo.supports2DArrayTextures + "\n";
systemInfoMessage += "supports3DRenderTextures: " + SystemInfo.supports3DRenderTextures + "\n";
systemInfoMessage += "supports3DTextures: " + SystemInfo.supports3DTextures + "\n";
systemInfoMessage += "supportsAccelerometer: " + SystemInfo.supportsAccelerometer + "\n";
systemInfoMessage += "supportsAsyncCompute: " + SystemInfo.supportsAsyncCompute + "\n";
systemInfoMessage += "supportsAudio: " + SystemInfo.supportsAudio + "\n";
systemInfoMessage += "supportsComputeShaders: " + SystemInfo.supportsComputeShaders + "\n";
systemInfoMessage += "supportsCubemapArrayTextures: " + SystemInfo.supportsCubemapArrayTextures + "\n";
systemInfoMessage += "supportsGPUFence: " + SystemInfo.supportsGPUFence + "\n";
systemInfoMessage += "supportsGyroscope: " + SystemInfo.supportsGyroscope + "\n";
systemInfoMessage += "supportsImageEffects: " + SystemInfo.supportsImageEffects + "\n";
systemInfoMessage += "supportsInstancing: " + SystemInfo.supportsInstancing + "\n";
systemInfoMessage += "supportsLocationService: " + SystemInfo.supportsLocationService + "\n";
systemInfoMessage += "supportsMotionVectors: " + SystemInfo.supportsMotionVectors + "\n";
systemInfoMessage += "supportsMultisampledTextures: " + SystemInfo.supportsMultisampledTextures + "\n";
systemInfoMessage += "supportsRawShadowDepthSampling: " + SystemInfo.supportsRawShadowDepthSampling + "\n";
systemInfoMessage += "supportsRenderToCubemap: " + SystemInfo.supportsRenderToCubemap + "\n";
systemInfoMessage += "supportsShadows: " + SystemInfo.supportsShadows + "\n";
systemInfoMessage += "supportsSparseTextures: " + SystemInfo.supportsSparseTextures + "\n";
systemInfoMessage += "supportsTextureWrapMirrorOnce: " + SystemInfo.supportsTextureWrapMirrorOnce + "\n";
systemInfoMessage += "supportsVibration: " + SystemInfo.supportsVibration + "\n";
systemInfoMessage += "systemMemorySize: " + SystemInfo.systemMemorySize + "\n";
systemInfoMessage += "unsupportedIdentifier: " + SystemInfo.unsupportedIdentifier + "\n";
systemInfoMessage += "usesReversedZBuffer: " + SystemInfo.usesReversedZBuffer + "\n";

For example on a MacBook Pro (15 inch, late 2013):

batteryLevel: 0.88
batteryStatus: Discharging
copyTextureSupport: Basic, Copy3D, DifferentTypes, TextureToRT, RTToTexture
deviceModel: MacBookPro11,3
deviceName: [REDACTED NAME]
deviceType: Desktop
deviceUniqueIdentifier: [REDACTED GUID]
graphicsDeviceID: 0
graphicsDeviceName: NVIDIA GeForce GT 750M
graphicsDeviceType: Metal
graphicsDeviceVendor: Apple
graphicsDeviceVendorID: 0
graphicsDeviceVersion: Metal
graphicsMemorySize: 2048
graphicsMultiThreaded: True
graphicsShaderLevel: 45
graphicsUVStartsAtTop: True
maxCubemapSize: 16384
maxTextureSize: 16384
npotSupport: Full
operatingSystem: Mac OS X 10.12.6
operatingSystemFamily: MacOSX
processorCount: 8
processorFrequency: 2300
processorType: Intel(R) Core(TM) i7-4850HQ CPU @ 2.30GHz
supportedRenderTargetCount: 8
supports2DArrayTextures: True
supports3DRenderTextures: True
supports3DTextures: True
supportsAccelerometer: False
supportsAsyncCompute: False
supportsAudio: True
supportsComputeShaders: True
supportsCubemapArrayTextures: True
supportsGPUFence: False
supportsGyroscope: False
supportsImageEffects: True
supportsInstancing: True
supportsLocationService: False
supportsMotionVectors: True
supportsMultisampledTextures: 1
supportsRawShadowDepthSampling: True
supportsRenderToCubemap: True
supportsShadows: True
supportsSparseTextures: False
supportsTextureWrapMirrorOnce: 1
supportsVibration: False
systemMemorySize: 16384
unsupportedIdentifier: n/a
usesReversedZBuffer: True

Another example on a Windows 10 Desktop:

batteryLevel: -1
batteryStatus: Charging
copyTextureSupport: Basic, Copy3D, DifferentTypes, TextureToRT, RTToTexture
deviceModel: System Product Name (System manufacturer)
deviceName: [REDACTED NAME]
deviceType: Desktop
deviceUniqueIdentifier: [REDACTED HASH]
graphicsDeviceID: 7041
graphicsDeviceName: NVIDIA GeForce GTX 1070
graphicsDeviceType: Direct3D11
graphicsDeviceVendor: NVIDIA
graphicsDeviceVendorID: 4318
graphicsDeviceVersion: Direct3D 11.0 [level 11.1]
graphicsMemorySize: 8096
graphicsMultiThreaded: True
graphicsShaderLevel: 50
graphicsUVStartsAtTop: True
maxCubemapSize: 16384
maxTextureSize: 16384
npotSupport: Full
operatingSystem: Windows 10 (10.0.0) 64bit
operatingSystemFamily: Windows
processorCount: 8
processorFrequency: 4008
processorType: Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz
supportedRenderTargetCount: 8
supports2DArrayTextures: True
supports3DRenderTextures: True
supports3DTextures: True
supportsAccelerometer: False
supportsAsyncCompute: False
supportsAudio: True
supportsComputeShaders: True
supportsCubemapArrayTextures: True
supportsGPUFence: False
supportsGyroscope: False
supportsImageEffects: True
supportsInstancing: True
supportsLocationService: False
supportsMotionVectors: True
supportsMultisampledTextures: 1
supportsRawShadowDepthSampling: True
supportsRenderToCubemap: True
supportsShadows: True
supportsSparseTextures: True
supportsTextureWrapMirrorOnce: 1
supportsVibration: False
systemMemorySize: 16311
unsupportedIdentifier: n/a
usesReversedZBuffer: True

Unity - Scripting API: Physics.GetIgnoreLayerCollision

Barnaby Smith - 2018-01-12T13:52:49

If you would like to drive raycasts with the same layer mask as defined in the collision matrix you can calculate the layer mask by using GetIgnoreLayerCollision(), for example:

public static int GetLayerMask(int sourceLayer)
int layerMask = 0;
for (int otherLayer = 0; otherLayer < 32; otherLayer++)
if(Physics.GetIgnoreLayerCollision(sourceLayer, otherLayer) == false)
layerMask |= 1 << otherLayer;

return layerMask;

int layerMask = GetLayerMask(gameObject.layer); // Usage example

Unity - Scripting API: Input.GetTouch

JacobK - 2018-01-12T12:09:37

Be aware that using a mouse in the editor does not count as input touches.

Unity - Scripting API: EventType.MouseUp

Thomas Ingram - 2017-12-30T12:35:03

When detecting MouseUp events in the SceneView without a hotControl you may find MouseUp on Button 0 is Used before you can possibly capture it. You can approximate this by querying e.rawType == EventType.Used, as it's one of the only events Used before the SceneView. There will be others but hopefully this is enough to hack a solution!
By using rawType and not querying isMouse you can capture mouse events that occur outside the SceneView window without having a hotcontrol active.


Baste Nesse Buanes - 2017-12-19T14:27:50

There is an undocumented version of this method (and every other physics method) with no parameters. It will still get called:

void OnTriggerEnter() {
//gets called whenever OnTriggerEnter(Collider other) would get called.

Unity - Manual: Command line arguments

Anomalous Underdog - 2017-12-18T04:54:40

Note: if you have an editor script and want to get what command line arguments were used when Unity was launched, you can use System.Environment.GetCommandLineArgs()

Unity - Scripting API: EditorWindow

Ardiawan Bagus Harisa - 2017-12-16T05:58:59

Just want to share, if you guys have problem which is editor window is not shown up, don't close the unity yet. Open the new launcher of unity, close the first unity that still running, and then open project from the unity launcher that you have opened.

Unity - Scripting API: WebCamTexture.WebCamTexture

JacobK - 2017-12-08T11:53:22

Make sure to call webcamtexture.Stop(); in OnDestroy or similar once you're done using it

Unity - :

Ardiawan Bagus Harisa - 2017-12-07T15:24:25

Unity - :

Ardiawan Bagus Harisa - 2017-12-07T15:03:45

welp. where is the page doc?

Unity - Scripting API: Application.persistentDataPath

Shay Pierce - 2017-12-05T21:48:04

In a UWP build running on an XboxOne, this resolves to a path like the following:

Unity - Scripting API: Object.FindObjectsOfType

Ardiawan Bagus Harisa - 2017-12-03T13:59:15

Please keep in mind that FindObjectsOfType() doesn't guarantee the ordered result. See this thread:


Sam Narain - 2017-11-26T14:25:34

By default unity computes a physx mesh representation at load time. Unity does this on the loading thread, so it should not affect framerate when using LoadLevelAsync. However computing physX meshes can take time, thus Unity has an option to bake them at build time. This increases distribution size and decreases load time.

At build time Unity tags meshes based on usage (the meshes which are referenced by MeshColliders). Those either get the physx mesh "baked" flag when the option is enabled, or a flag that they will need to be computed on the loading thread.

Unity - Scripting API: Handles.DrawBezier

Jaime Borondo - 2017-11-24T17:55:25

The tangent parameters here are not actually what is described, but the tangent endpoints. So for the example above example (start facing up, end from below) it would be something like (startpoint, endpoint, startpoint + tangentLength*Vector3.up, endpoint - tangentLength*Vector3.up,.....)

Unity - Scripting API: Material.EnableKeyword

Thomas Ingram - 2017-11-24T04:05:59

Enabling emission with the standard shader is done by the "_EMISSION" keyword.

Unity - Scripting API: Handles

Thomas Ingram - 2017-11-23T01:13:33

If you wish to always draw handles (regardless of whether your Editor is selected or not) you can subscribe to the SceneView.onSceneGUIDelegate provided by the Editor class.

Unity - Scripting API: Transform.SetSiblingIndex

tenpn - 2017-11-22T17:17:26

Range is 0 <= index < transform.parent.childCount

Unity - Scripting API: EditorUtility.SetDirty

Tom G - 2017-11-21T18:25:53

If you aren't using a SerializedProperty yet you want to set a scene as dirty then you can use: UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty( gameobject.scene) or
UnityEditor.SceneManagement.EditorSceneManager.MarkAllScenesDirty() instead.

Unity - Scripting API: EditorApplication.MarkSceneDirty

Tom G - 2017-11-21T18:22:58

Use UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty( gameobject.scene) or UnityEditor.SceneManagement.EditorSceneManager.MarkAllScenesDirty() instead.

Unity - Scripting API: GameObject.activeInHierarchy

Barnaby Smith - 2017-11-19T21:25:13

Note that this will return false if used on an uninstantiated prefab (for example if you're writing an editor tool that requires selecting a prefab in the project window).

For example, this will always be false when a prefab is selected in the Project window:


Unity - Scripting API: Screen.currentResolution

Barnaby Smith - 2017-11-19T21:22:48

Note that Screen.currentResolution.width is not guaranteed to be the same as Screen.width. In particular currentResolution has different behaviour on different platforms - there is more information on this in this article.

In many cases you'll want to use Screen.width and Screen.height instead of Screen.currentResolution

Unity - Scripting API: Material

haowan - 2017-11-19T12:13:28

Note that materials that are being animated will still return properties as they were before the animation played. To get the values as affected by the animation, use a material property block.

MaterialPropertyBlock properties = new MaterialPropertyBlock();
Vector4 color = properties.GetVector("_Color");
Debug.Log("color: " + color);

(Retrieved from:

Unity - Scripting API: Behaviour.isActiveAndEnabled

Barnaby Smith - 2017-11-19T00:40:49

This is the equivalent of:

behaviour.enabled && behaviour.gameObject.activeInHierarchy

It checks that both the behaviour component is enabled as well as the gameObject it lives on being active (and all parent gameObjects recursing upwards).

Note that like activeInHierarchy, this will return false if used on an uninstantiated prefab (for example if you're writing an editor tool that requires selecting a prefab in the project window)

Standalone Player Settings

Sam Narain - 2017-11-18T21:29:16

Screen Resolution Dialog: you need to change the texture import settings in the "Advanced" options and then select "none" instead of "nearest power of two" setting. Else you will get a distorted image in your dialog.

Unity - Scripting API: EditorGUI.EndChangeCheck

Barnaby Smith - 2017-11-16T12:09:26

Note that Begin/EndChangeCheck can be nested. For example:

string foo = "";
int bar = 0;


foo = EditorGUILayout.TextField(foo);


bar = EditorGUILayout.IntField(bar);

Debug.Log("Bar changed");

Debug.Log("Foo or Bar changed");

Also, as mentioned in the docs this is based on GUI.changed going from False at the time of BeginChangeCheck to True at the time of EndChangeCheck. Built in Unity controls will mark this flag already, but if you need it with your own controls or with a button you can set GUI.changed = true; yourself.

Unity - Scripting API: GUILayout.Toggle

Nikkolai Davenport - 2017-11-15T17:17:28

The following will display a toggle as a button

isEnabled = GUILayout.Toggle(isEnabled, isEnabled ? "Enabled" : "Disabled",;

Unity - Manual: Tags

Barnaby Smith - 2017-11-15T11:50:06

The built in EditorOnly tag has special behaviour. At build time any objects tagged EditorOnly will be stripped out (including child objects regardless of whether the child is also tagged EditorOnly). This behaviour only occurs at build time, EditorOnly tagged objects will remain when pressing Play in the Editor.

Marking objects as EditorOnly is useful for development helpers (such as debug text) that you may want in Editor but not in builds.

If you do want to strip EditorOnly objects in editor at Play time as well as at build time there are a couple of simple approaches:

* Write a script which destroys its gameObject on Awake
* Write a PostProcessSceneAttribute that strips all EditorOnly objects. Note that PostProcessSceneAttributes are called on Play as well as at build time.

Unity - Scripting API: ControlTrack

Thomas Ingram - 2017-11-13T03:11:49

Implement ITimeControl to allow components on GameObjects targetted by ControlTracks to recieve a time callback.

Unity - Scripting API: Animator

"This site is a mess" Juskelis - 2017-11-12T19:38:08

Remember that the animation system is updated after Update and before LateUpdate

Unity - Scripting API: MonoBehaviour.Invoke

"This site is a mess" Juskelis - 2017-11-12T19:32:23

Note that Invoke follows scaled time. If you need to Invoke regardless of timescale, you'll need to write your own invoker.

Unity - Scripting API: RenderTexture

"This site is a mess" Juskelis - 2017-11-12T19:25:42

Keep in mind that when you "new" a RenderTexture, it does not clear out the memory that the texture uses, which can lead to weird artifacts. In order to clear it out, you need to use GL.Clear

Execution Order of Event Functions

Ardiawan Bagus Harisa - 2017-11-11T10:47:13

Yeah, but they said it will be better to not to use that function. Since it is unstable cz unity might change many things on the updated version.

Unity - Scripting API: Material.FindPass

JacobK - 2017-11-09T13:24:28

passName seems to need to be capitialized. FindPass("ShadowCaster") will return -1, whereas FindPass("SHADOWCASTER") will work. (as of 5.6.4p1)

Unity - Scripting API: CanEditMultipleObjects

Alex Lovett - 2017-11-07T18:15:35

This is an example of a custom inspector with a button that fires a method on all selected objects with the component Thing.

Note that this example has both the class and editor in the same file. This is optional, but useful if you want to have an editor's code in the same file as what it edits instead of a separate file put inside an Editor folder: See "#if UNITY_EDITOR namespace UnityEditor {"

( note Disqus seems to be changed the case of 'Thing' to 'thing' for some reason )

Mod: Edited for clarity

using System.Linq;

public class Thing : MonoBehaviour {
public void MethodOnThing() {}

namespace UnityEditor {

[CustomEditor( typeof(Thing) ), CanEditMultipleObjects]
public class ThingEditor : Editor {
public override void OnInspectorGUI() {

var myScripts = targets.Cast<thing>().ToList();

if( GUILayout.Button( "Button Text" ) ) {
// With LINQ
myScripts.ForEach( o => o.MethodOnThing() );

// Without LINQ ( dont need .ToList() above with this
foreach( var o in myScripts ) { o.MethodOnThing(); }




ShaderLab built-in values

Graham H Reeves - 2017-11-06T16:09:22

_Time.y is not the same as Time.time, it is the equivalent of Time.timeSinceLevelLoad


Graham H Reeves - 2017-11-06T16:05:26

I did something similar, but with an IDisposable abstraction, I clear the progress bar in the Dispose().
then my code simplifies down to

using ( var ProgressBar = new ScropedProgressBar("MyOp") ){}

Unity - Scripting API: Mathf.DeltaAngle

Barnaby Smith - 2017-11-04T18:13:14

Note this value is signed and can produce negative values, for example

Debug.Log(Mathf.DeltaAngle(1080, 90));

will print 90

Debug.Log(Mathf.DeltaAngle(90, 1080));

will print -90

Unity - Manual: Unity Manual

haowan - 2017-11-03T15:23:02

integer queue values:
Background is 1000
Geometry is 2000
Transparent is 3000
Overlay is 4000

WebGL: Interacting with browser scripting

Brahim Hadriche - 2017-10-27T16:39:19

If you want to build your c++ code into a binary .bc file, you're supposed to install the SDK. But you can do that without installing it since emscripten is bundled with Unity.
The best approach is to create a config file similar to PlaybackEngines\WebGLSupport\BuildTools\emscripten.config, and set where everything is (Node.js, LLVM, etc) which should all be in the WebGLSupport folder anyway.
Finally, when calling emcc to compile code, add the option --em-config and point to the file where you have your config. This allows you to compile with emscripten, without messing up with env vars.
Pro tip: cmake can make this more stright forward. check out PlaybackEngines\WebGLSupport\BuildTools\Emscripten\cmake\Modules\Platform\Emscripten.cmake. make a copy of the toolchain file, and change the call to "emcc -v" to "emcc -v --em-config <file>" so it doesn't fail to find the config when the SDK is not installed.
And also add the --em-config option to the CMAKE_C_FLAGS, so "cmake install" calls emcc correctly, with your settings.
Here's more here:
And here:

Unity - Scripting API: MenuCommand

Graham H Reeves - 2017-10-26T18:08:51

To handle multiple-selections (as MenuCommand.context is a single object), your MenuCommand function is called for every object selected.

E.g. Selecting 10 game objects with RigidBody components, calls DoSomething() 10 times with different contexts.

Unity - Scripting API: Mesh.vertices

Nick Klingensmith - 2017-10-25T20:54:11

If using a List<vector3> for your mesh generation, you can use Mesh.SetVertices instead to bypass a .ToArray() call and save yourself some time and memory!

Unity - Scripting API: EditorGUILayout.Foldout

Byron - 2017-10-25T17:49:31

The issue with storing a local bool with a foldout is that it will be reset every time you click on and off the editor. You can solve this by making the value static however this still has issues if you have multiple and it also resets when you recompile. What you should use is the SerializedProperty.isExpanded

Custom Lighting models in Surface Shaders

haowan - 2017-10-25T13:56:42

Note that the lighting function parameter list is apparently variable. According to this page you can also add light direction and attenuation. The syntax for the lighting function signature is not clear.

Unity - Manual: Masking Imported Clips

YoonJeong Sa - 2017-10-25T08:02:22

"The Humanoid mask selection option" under Transform section: "The Transform mask selection option"

Unity - Scripting API: MonoBehaviour.OnDrawGizmos()

haowan - 2017-10-24T13:25:16

Here is a solution for those wanting to draw their own pickable gizmos:

Unity - Scripting API: CustomPropertyDrawer

haowan - 2017-10-23T15:57:20

Link to the manual page for property drawers:


Byron - 2017-10-20T15:32:39

A good way to use this is using Exceptions to your advantage.

public class Abort() : System.Exception {}

public void Process()
EditorUtility.ShowProgressBar("Title", "Doing Stuff", 0f);
// The user hit cancel. Nothing to do here.
catch(Exception e)
// We got an an exception so lets handle it.
// If we get an exception or the user cancels we always clear our progress bar

private void ProcessAssets()
// Complex code
if(EditorUtility.DisplayCancelableProgressBar("Title", "Doing Stuff", 0f))
throw new Abort();
// Other complex code

Having the finally block makes sure that we always clear the progress bar when we are done. If we were to get an exception while doing our process the loading bar would stick around forever and the user would have to restart Unity. Throwing our own Abort exception allows us to break at any point and not log errors to the console.

Unity - Manual: Google VR

Mario Gutierrez - 2017-10-19T22:18:49

VRSettings is now XRSettings.

Unity - Scripting API: VR.VRSettings.enabled

Mario Gutierrez - 2017-10-19T20:46:17

This is now XRSettings.enabled.

Unity - Scripting API: Handheld.PlayFullScreenMovie

Marc-Olivier Beaupré - 2017-10-19T20:27:35

In case you need a remote solution and not a streaming assets solution here is an example :
string videoFile = Application.persistentDataPath + "/" + videoName;
WWW www = new WWW (url + videoName);
yield return www;
isDownloading = false;

if (www != null && www.isDone && www.error == null)
FileStream stream = new FileStream (videoFile, FileMode.Create);
stream.Write (www.bytes, 0, www.bytes.Length);
stream.Close ();
Debug.LogError (www.error);

videoFile = "file://" + videoFile;

Handheld.PlayFullScreenMovie(videoFile,, FullScreenMovieControlMode.Full, FullScreenMovieScalingMode.AspectFit);

Unity - Manual: Timeline Preview and Timeline Selector

Thomas Ingram - 2017-10-19T11:15:04

Whilst Timeline Preview is active you may find component Resets are greyed out. Disabling the preview will re-enable the reset option.

Unity - Scripting API: UnityEvent

Thomas Ingram - 2017-10-14T11:34:34

UnityEvents do not function in edit mode by default. There is a toggle in the inspector, but each event needs to managed. Doing this via code can be done via SetPersistentListenerState.


Dave Smeathers - 2017-10-10T16:02:37

"Return argument of this function tells if user had pressed the cancel button"

It returns true when cancel is pressed.

Unity - Scripting API: Physics.Raycast

Jon Hallier - 2017-10-10T13:06:31

For examples of ignoring multiple layers, see:

Execution Order of Event Functions

S. Darkwell - 2017-10-09T22:39:07

Unity also has an undocumented event function, Main, which is executed after OnEnable and before Start.

Unity - Manual: Property Drawers

Matt Bengston - 2017-10-09T18:56:25

It's worth noting that with `CustomPropertyDrawer` you need to override the `OnGUI` method in your custom drawer class otherwise "No GUI implemented" will show up instead of your custom gui.

Unity - Scripting API: MonoBehaviour.OnDestroy()

Jon Hallier - 2017-10-09T13:13:53

It's not mentioned here, but instantiating a GameObject OnDestroy (e.g. spawning debris, gibs, other effects) will result in the error: "Some objects were not cleaned up when closing the scene. (Did you spawn new GameObjects from OnDestroy?)" when you stop the game or change scene. So I don't think it can be recommended for this purpose. Instead it's probably a better idea to create a custom OnDeath() or similar public method which instantiates the desired objects and then destroys itself.

Built-in shader include files

haowan - 2017-10-04T14:37:41

Naming for members of appdata* structs is as follows, to save you looking it up:
float4 vertex : POSITION;
float4 tangent : TANGENT;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
float4 texcoord1 : TEXCOORD1;
float4 texcoord2 : TEXCOORD2;
float4 texcoord3 : TEXCOORD3;
fixed4 color : COLOR;


Oswald Hurlem - 2017-10-04T09:40:03

This does in fact perform frustum culling, based on the bounds parameter.

Unity - Scripting API: Graphics.DrawMeshInstanced

Oswald Hurlem - 2017-10-04T09:38:46

This does in fact perform frustum culling, based on the bounds parameter of the mesh that's passed in.

Unity - Scripting API: Camera.CalculateFrustumCorners

haowan - 2017-10-02T16:00:22

The order of points returned is as follows:
bottomLeft = 0
bottomRight = 3
topLeft = 1
topRight = 2

Unity - Scripting API: Timeline.TimelineClip.clipIn

Thomas Ingram - 2017-10-02T02:12:35

This is the time the asset within the Timeline Clip will play at : the start time of the asset local to the TimelineClip. Start is when the TimelineClip will play local to the timeline.

Unity - Scripting API: UI.ScrollRect.OnDrag

zarawesome - 2017-09-29T14:05:14

If the ScrollRect has inertia, this will not be called after the mouse is released, even if the ScrollRect is still changing value.

Add listeners to onValueChanged instead.

Unity - Scripting API: Mesh

Mark Wonnacott - 2017-09-29T09:23:04

if you are updating vertices without updating the topology, absolutely remember to call RecalculateBounds or you may find your mesh vanishing (i.e culled) when you look at it the wrong way!

Unity - Scripting API: ComputeBuffer.stride

haowan - 2017-09-26T09:54:40

The unit of this field is bytes.

Unity - Scripting API: Dropdown

Timothy Grant - 2017-09-25T16:17:13

If you use TextMesh Pro, there is a pre-configured TMP_Dropdown that should be used in place of Dropdown.

Unity - Scripting API: AssemblyReloadEvents

Byron - 2017-09-25T02:30:31

This is a super useful function to have for the case of IL Weaving. This gets called after Unity generates the final assemblies and writes them to disk but before they are loaded. This means you can use tools like Mono.Cecil to edit the assemblies.


Barnaby Smith - 2017-09-23T22:59:22

On macOS this will return


or similar if the Unity install is renamed


Barnaby Smith - 2017-09-23T22:58:43

On macOS this will return


or similar if renamed


Byron - 2017-09-23T17:48:35

On Windows this will return the path <Unity Install directory>/Editor/Data/Unity.exe


Byron - 2017-09-23T17:48:00

On Windows this will return the path <Unity Install directory>/Editor/Data/

Unity - Scripting API: UI.Button.onClick

Adriano Gil - 2017-09-22T19:25:10

You don't need to get a Button reference if you already have one. This line doesn't make sense: "Button btn = yourButton.GetComponent<button>();"

Unity - Manual: Command line arguments

FiveOhThreeBHP - 2017-09-21T13:36:52

tvOS does not seem to be supported

Unity - Scripting API: EditorUtility.ClearProgressBar

Byron - 2017-09-21T02:49:05

You should always wrap your progress bars in a try finally. This is because if you have an exception the clear will never be called. If you don't call clear the user will have to force close Unity to dismiss it. This makes sure that never happens.

public void PrintGameObjectNames()
GameObject[] gameObjects = GameObject.FindObjectsOfType<gameobject>();

for(int i = 0; i < gameObjects.Length; i++)
EditorUtility.DisplayProgressBar("Printing Game Objects", gameObjects[i].name, (float)i / gameObjects.Length);
// Even if we have an exception the finally happens

Unity - Scripting API: AssetDatabase

Byron - 2017-09-21T01:49:21

Working with folders in Unity is a super huge pain. If you are creating folders with System.IO this will be imported into Unity later on. So if you create a folder and also try to add stuff to it in code you are going to have issues. This is why Unity has their own functions, to create and import them in one step. I have written an free open source library that you can do that makes these task much easier.

Unity IO

Unity - Scripting API: PrefabUtility

Byron - 2017-09-21T01:35:08

Detecting if a Prefab has changes. Unfortunately checking if a prefab has pending changes can be quite difficult for a few reasons. There is no one method to check if a prefab has a change. There is a few things you have to check.

1) Have any of the properties changed? You use GetPropertyModifications and filter out root changes (read doc for how)
2) Have any components been removed? (You have to do this with serialized property hacks)
3) Have any new components been added? You use Example
4) Do we have any objects from the parent all the way down to the bottom of the hierarchy that are not already belonging do us? Using GetPrefabType to check if the child is part of a prefab and FindPrefabRoot to check if the prefab it's part of is the root one we started with.

With all that information you can find out if there is a change.

Unity - Scripting API: Light.cullingMask

Thomas Ingram - 2017-09-20T23:57:32

When trying to isolate a small amount of layers it's important to note that toggling the mask to Nothing via the inspector will set all the layers to none, including the hidden un-bound layers. This will cause warnings if running in deffered, where you can only exclude 4 layers from culling masks ( .)
To exclude layers you should start from Everything and work backwards.


Byron - 2017-09-20T18:12:15

To find out if your prefab has any changes you have to remember that the root will always have pending modifications that will always be dirty. This is true for the Transform or RectTransform. You will always want to filter out the following on the root object.

// Transform
// Rect Transform
// Misc changes

Unity - Scripting API: PrefabUtility

Byron - 2017-09-20T18:08:58

Missing Documentation for


This function is used to check if a component was added to a prefab. If you want to check if a prefab has any new components you have to loop over them all and call this function

/// <summary>
/// Takes in Prefab instance and checks if any of it's components
/// were added and have not been saved to the prefab.
/// </summary>
/// <returns>True if we have a new component and false if we don't.</returns>
public bool HasNewComponent(GameObject prefabInstance)
// Get all components in our prefab
Component[] components = prefabInstance.GetComponentsInChildren<component>(true);
// Loop over them all
for (int i = 0; i < components.Length; i++)
if (PrefabUtility.IsComponentAddedToPrefabInstance(components[i]))
return true;
return false;

WebGL: Interacting with browser scripting

Mark Wonnacott - 2017-09-20T10:56:01

It seems that SendMessage is no longer in global scope ( ) - look at the html template for your webgl game and you'll need something like gameInstance.SendMessage instead

Unity - Scripting API: FileUtil.CopyFileOrDirectory

FiveOhThreeBHP - 2017-09-18T08:30:02

If you're trying to copy a directory and the target directory already exists, this function throws an exception. Use FileUtil.ReplaceDirectory if there is a possibility that the target directory already exists, it will overwrite the existing target directory.

Advanced Unity mobile scripting

YoonJeong Sa - 2017-09-18T06:55:00

Incorrect cross-reference.

Refer to the "Handheld.StartActivityIndicator Unity Scripting API" documentation for examples.

should be corrected to ""

Unity - Scripting API: Sprite.Create

Mark Wonnacott - 2017-09-16T18:46:46

Although it says "specified in pixels", the pivot in this call are actually are a multiplier of the rect (e.g 0.5, 0.5 is the center)

Unity - Scripting API: Sprite.pixelsPerUnit

Mark Wonnacott - 2017-09-16T18:41:03

There's no way to change pixels per unit on a sprite other than to create a new one.


Mark Wonnacott - 2017-09-16T11:59:56

At least in 2017.1, MinMaxGradient has an implicit type conversion from both Color and Gradient types

Unity - Scripting API: KeyCode.Hash

Mark Wonnacott - 2017-09-16T11:56:10

Doesn't work on UK keyboards


Seb - 2017-09-15T10:48:27

There must be something I miss in this example, maybe it's outdated? main.startColor is obviously of type MinMaxGradient. However it's initialized as Color:

main.startColor = new Color(hSliderValueR, hSliderValueG, hSliderValueB, hSliderValueA);

this doesn't compile in 5.6. I currently had to revert to the obsolete ParticleSystem.startColor property to be able to change color.

ShaderLab: Culling & Depth Testing

Mark Wonnacott - 2017-09-15T10:32:38

Warning, the offset examples are badly formatted and shouldn't be copied and pasted! They've got en dashes instead of minuses so you will get a cryptic shader compile error.

Reporting crash bugs under Android

YoonJeong Sa - 2017-09-15T05:42:16

incorrect cross-reference for "Unity bug reporting guidelines"
Should change "" to ""

Unity - Scripting API: Application.CaptureScreenshot

Barnaby Smith - 2017-09-12T10:23:19

As of Unity 2017 this has been moved to a new ScreenCapture class. The API call is now


Unity - Manual: Font

szymon112233 - 2017-09-11T12:28:18

Be sure to list Fallback Fonts in 'Font Names' field in one line (Font 1, Font 2, Font 3) instead of using new lines to separate them.

Unity - Scripting API: EditorPrefs

Barnaby Smith - 2017-09-10T16:16:37

Note that on Windows the registry location is

HKCU\Software\Unity Technologies\Unity Editor N.x

rather than the documented

HKCU\Software\Unity Technologies\UnityEditor N.x

Unity - Scripting API: Application.unityVersion

Barnaby Smith - 2017-09-10T16:03:57

This reports the fully qualified Unity version such as:


Unity - Scripting API: AnimationClip

Thomas Ingram - 2017-09-08T08:46:07

If you're managing large animation clips (eg. motion capture data) and/or associated assets (eg. TimelineAssets,) and finding loading them is extremely slow, change your Asset Serialization mode to binary, this will improve load times significantly.

Unity - Scripting API: TrackAsset

Thomas Ingram - 2017-09-08T08:34:32

If you ever find yourself manually controlling TrackAssets using custom scripts, duplicating, swapping timelines, etc, it's important ensure the root tracks' parents are set to the Timelines that contain them. Without doing this the Timeline inspector will lag.

Unity - Scripting API: Playables.DirectorUpdateMode.Manual

Victor S C Lui - 2017-09-05T09:16:16

"You need to manually call PlayerController.Tick with your own deltaTime."
"You need to manually call PlayableGraph.Evaluate with your own deltaTime."

유니티 - 매뉴얼: VR 개요

Victor S C Lui - 2017-09-05T09:09:51

"Unity 5.1는 여러 VR 장치를 지원합니다"
"Unity 5.1은 여러 VR 장치를 지원합니다"

Unity - Scripting API: Object.FindObjectOfType

Byron - 2017-09-03T21:58:30

In the editor if you are looking to find an instance of an Editor type this will not find them. However Resources.FindObjectOfTypeAll<t> will.

Unity - Scripting API: Time.smoothDeltaTime

Alex Lovett - 2017-09-03T12:20:51

Using smoothDeltaTime limits the effect of sudden fluctuations in deltaTime by averaging over several frames to avoid spikes say if you drop frames.


Baste Nesse Buanes - 2017-09-01T15:09:51

Note that if this is false, yielding the AsyncOperation will never finish, as yielding checks the isDone variable:

var loadOp = SceneManager.LoadSceneAsync("scene");
loadOp.allowSceneActivation = false;

yield return loadOp; //never finishes!

Unity - Scripting API: AssetDatabase.RenameAsset

RobD6 - 2017-09-01T08:48:52

Note that the 2nd parameter needs to not include the path.

Correct usage is:
AssetDatabase.Rename("Assets/Textures/OldName.png", "NewName.png");

AssetDatabase.Rename("Assets/Textures/OldName.png", "Assets/Textures/NewName.png");

Unity - Scripting API: Purchasing.ConfigurationBuilder.useCloudCatalog

Barnaby Smith - 2017-08-31T16:37:39

At the time of writing cloud catalogs cannot be set up on Unity Services, see

Unity - Scripting API: Application.Quit

Barnaby Smith - 2017-08-31T13:08:28

Note that while the documentation and guidelines discourage usage of Application.Quit() for released games, it does work correctly on iOS. This is particularly useful for developer code that may need to force quit the game.

Unity - Scripting API: EventSystems.UIBehaviour.OnCanvasGroupChanged

Byron - 2017-08-30T20:39:50

Vote for the worst documents page. This function does not exist on MonoBehaviour.

Unity - Scripting API: ScreenOrientation

Mario Gutierrez - 2017-08-30T16:19:50

The value of the enums when converted to integer and string.
enum => (int value, string value)

ScreenOrientation.Unknown => (0, "Unknown")
ScreenOrientation.Portrait => (1, "Portrait")
ScreenOrientation.PortraitUpsideDown => (2, "PortraitUpsideDown")
ScreenOrientation.LandscapeLeft => (3, "Landscape")
ScreenOrientation.LandscapeRight => (4, "LandscapeRight")
ScreenOrientation.AutoRotation => (5, "AutoRotation")
ScreenOrientation.Landscape => (3, "Landscape")

Tested on Unity 5.6.1f1

Unity - Scripting API: SceneManager

Timothy Johnson - 2017-08-30T13:59:41

GetSceneByXXX() only return a valid result for the currently active scene, many forum posts suggest using these for checking if a scene can be loaded, use Application.CanStreamedLevelBeLoaded() for that instead.

Unity - Scripting API: QualitySettings.shadowCascades

Jon Huffman - 2017-08-28T15:53:44

Shadow cascades do not work on Mobile. An alternative option if your shadows look fine when zoomed out but shitty when zoomed in is to adjust shadow distance dynamically.


Barnaby Smith - 2017-08-28T15:39:07

C# version of the above example:

using UnityEditor;

// Disable import of materials if the file contains
// the @ sign marking it as an animation.

class DisableMaterialImport : AssetPostprocessor
void OnPreprocessModel ()
if (assetPath.Contains("@"))
ModelImporter modelImporter = (ModelImporter)assetImporter;
modelImporter.importMaterials = false;

Unity - Scripting API: EditorGUIUtility.IconContent

Anomalous Underdog - 2017-08-28T02:34:01 is a list of names of built-in icons in the Unity Editor. You can use those in the fist parameter of this method.

Unity - Scripting API: Camera

Tony Coculuzzi - 2017-08-28T01:44:22

NOTE: Camera.main is a wrapper property that calls GameObject.FindWithTag("MainCamera") behind the scenes. Consider caching this value once, instead of accessing it every frame.

Unity - Manual: Polygon Collider 2D

Michael Chugg - 2017-08-25T19:50:14

It should be noted that order to add a new vertex while holding shift, you must zoom in enough to see a green point on the line that follows your mouse cursor.

Unity - Scripting API: Debug

Jon Huffman - 2017-08-25T12:35:58

Keep in mind that the Debug Log methods do not get stripped in release builds and they can have a serious performance impact. Consider wrapping them in custom methods and making use of the Conditional attribute to disable them when desired.

Unity - Scripting API: Object.DontDestroyOnLoad

Baste Nesse Buanes - 2017-08-24T09:58:07

There's a lot of information missing here, especially with regards to changing the parenting relation between objects.

The rules for this method are these:
Calling DontDestroyOnLoad on an object that has a parent fails.
Calling DontDestroyOnLoad on a Component is equivalent to calling DontDestroyOnLoad on that Component's GameObject.
Calling DontDestroyOnLoad on an object marks that object and all it's children as DontDestroyOnLoad.

If you set object B as the parent of object A, object A will immediately and permanently get object B's DontDestroyOnLoad status.
Setting an object's parent to null (moving it to the root of the scene) doesn't change it's DontDestroyOnLoad status.

Unity - Manual: Platform-specific

Sam Narain - 2017-08-24T06:44:00

If you have to make a build for an other platform, changing your current platform from OSX to Windows can take up a lot of time. That is because the library folder is recreated when you change your current target. A nifty hack is to keep copies of the Library folder and switch them before changing the build target.


Liam Cary - 2017-08-24T02:28:52

The last overload that takes a List<t> as a parameter allows you to cache and re-use a list, whereas the overloads that return an array will allocate memory for a new array each time you call them.
The List<t> overload will only allocate memory if the capacity of the list is smaller than the amount of items that the method needs to return. In that case the list will have to expand, but at least you can keep re-using that expanded list in future calls.

Unity - Manual: Special folder names

BenBen Mushi - 2017-08-23T10:46:27

Note about Hidden Assets: There are useful with symlinks to avoid the .meta files duplications inside your Assets folder.

Unity - Scripting API: AssetDatabase.FindAssets

Thomas Ingram - 2017-08-23T06:21:47

This does not find assets with HideFlags HideInHierarchy set.

Unity - Manual: Editor settings

Thomas Ingram - 2017-08-22T02:05:38

Mixed mode serialisation will keep assets in the formats they have been serialised in. New assets are likely serialised in binary. It's a temporary setting intended for upgrading projects, so preferably choose either Text or Binary serialisation. You cannot set the mode on a per-asset basis.

Unity - Scripting API: BaseMeshEffect

mjholtzem - 2017-08-21T18:17:15

Example code in this is outdated and somewhat unhelpful.
A: ModifyMesh with a Mesh parameter is obsolete and has been replaced by ModifyMesh with a VertexHelper parameter. VertexHelper works totally different from the Mesh class and renders this example more or less useless.
B: The ListPool class used in this example is an internal class and cannot be used in normal projects.


Barnaby Smith - 2017-08-18T17:04:39

activeScriptCompilationDefines includes:

* Internal defines set by Unity such as UNITY_5_6_OR_NEWER
* User defines set through Player Settings' Scripting Define Symbols, common ones include CROSS_PLATFORM_INPUT (from Sample Assets) and TMP_PRESENT (if you have TextMeshPro)
* C# defines such as DEBUG and TRACE

Unfortunately it doesn't seem to include defines set in rsp files such as mcs.rsp and csc.rsp

Unity - Scripting API: Physics.SphereCast

Anomalous Underdog - 2017-08-17T23:31:11

Just to clarify, a SphereCast ends up looking like a capsule. If you wanted to check what objects are inside a sphere shape instead, use Physics.OverlapSphere() or Physics.OverlapSphereNonAlloc() (so it doesn't generate garbage).

Unity - Scripting API: GUILayout.TextField

Anomalous Underdog - 2017-08-17T23:21:10

Note that even though this method looks and works almost identical to EditorGUILayout.TextField(), you should always use EditorGUILayout.TextField() for your editor GUI. Using GUILayout.TextField() in an editor script (while it kind of works) won't work correctly in certain cases (if it's in OnSceneGUI and the user made a Ctrl+C, it won't copy the text, instead it'll copy whatever game object is selected)

Unity - Scripting API: AnimationState.speed

Jon Hallier - 2017-08-17T18:19:30

This post explains how to change the speed of any / all animation states using an animation parameter:

This is helpful if you want to quickly adjust the universal speed of all animations on a character, without having to look up and reference individual states or anims (as in the example above).

Built-in shader variables

Baste Nesse Buanes - 2017-08-17T13:36:03

_ZBufferParams is listed with "x is (1-far/near)"

For clarity, it's 1 - (far / near). That's what precedence gives, but it's nice if it's actually written out like that so you're sure.

Unity - Scripting API: Application.isPlaying

Barnaby Smith - 2017-08-16T22:46:25

In addition to Application.isPlaying there are two related properties in the UnityEditor namespace that are useful:

EditorApplication.isPlaying acts much the same as Application.isPlaying, except it also has a setter allowing you to change if the Editor is in play mode or not.
EditorApplication.isPlayingOrWillChangePlaymode in addition to reporting true when the game is actively playing it will also report true from the moment you hit play until the game is actively playing.

Unity - Scripting API: Playables.PlayableDirector.Play

Dave Smeathers - 2017-08-16T11:16:01

Doesn't work if you pass in a different playable asset to the first one played, or the one set in the editor. It seems that if you need to play multiple timelines then you will need multiple directors.

You can't do this:

myDirector.Play(mySecondPlayableAsset); // This one won't play


RobD6 - 2017-08-16T10:18:14

The return parameter is of type
The string passed in is the path to the asset.

Unity - Scripting API: GUILayoutUtility.GetRect

RobD6 - 2017-08-16T08:45:10

If used in an EditorGUI (and possible non-editor too), the "Fixed" sized version of this (where you specify min and max) seems to happily overshoot the max width, instead expanding to the width of the space it's in. Adding GUILayout.MaxWidth as an option fixes this.

E.g, if you want a rect of 100x100
GetRect(100, 100, 100, 100) will often give you back a width more than 100.
GetRect(100, 100, GUILayout.MaxWidth(100)) will actually work.

Unity - Scripting API: AssetDatabase.CreateFolder

Byron - 2017-08-16T03:46:45



if the directory already exists Unity will create a second directory with a unique name by appending a number to the end.

Unity - Scripting API: VerticalScope

Barnaby Smith - 2017-08-15T22:44:02

VerticalScopes are a great way to add structure and grouping to controls, especially editor inspectors and custom windows.

In particular for editor cases using EditorStyles.helpBox as the GUIStyle produces a well fitting scope.

GUILayout.Label("Something here", EditorStyles.boldLabel);

Additionally you can create more interesting reusable VerticalScopes by subclassing VerticalScope, and then in the subclass adding drawing to the overridden constructor and CloseScope method. For example you could create a NamedVerticalScope class that takes a string which it displays in a nicely styled title.

Unity - Scripting API: PlayerPrefs

Barnaby Smith - 2017-08-15T22:24:40

As of Unity 5.5 on Windows the player prefs registry location while playing in editor has moved to:

HKCU\Software\Unity\UnityEditor\[company name]\[product name] 

Before Unity 5.5 the player prefs would be shared between Windows editor and Windows standalone builds, since 5.5 they have now been split out into two separate locations. The Windows standalone location remains unchanged and the Mac editor and Mac standalone builds continue to share the same plist.

Unity - Scripting API: GUI.GetNameOfFocusedControl

Barnaby Smith - 2017-08-15T22:10:23

Note that handles can also return a valid name when being manipulated. For example, while interacting with Unity's built in translation handle GetNameOfFocusedControl() will report the axis being manipulated ("xAxis", "yAxis" or "zAxis")

Unity - Scripting API: GL.LoadPixelMatrix

Barnaby Smith - 2017-08-15T22:06:20

Note that the z value is inclusive of +1 on Windows, but exclusive on Mac. If you wish to draw at the very front you should use a value of 0.99 instead of 1 to maintain cross platform support. Otherwise your polygon will render correctly on Windows but be invisible on Mac.

Unity - Scripting API: Event.modifiers

Barnaby Smith - 2017-08-15T21:53:00

Note that this will not return EventModifiers.None when no keys are held if either Caps Lock or Num Lock is enabled. As these are easily left on by the user you should generally discount them from your comparisons.

For example if you wish to check if they are holding shift (but not control, command etc), rather than do:

if(e.modifiers == EventModifiers.Shift)

Which would fail if the player accidentally has Caps Lock on, instead do something like:

EventModifiers modfiers = e.modifiers;
modifiers &= (~EventModifiers.CapsLock);
modifiers &= (~EventModifiers.Numeric);
if(modifiers == EventModifiers.Shift)

Unity - Scripting API: Quaternion.Euler

Lewis Ellington - 2017-08-15T21:02:17

If you have values in radians, you can multiply them by Mathf.Rad2Deg to convert them to degrees.

Running Editor Script Code on Launch

RobD6 - 2017-08-15T09:04:29

Note that static constructors will be called again every time the code is compiled, and any static data will be lost. If you need to store data that persists across compilations, consider using EditorPrefs.

Unity - Scripting API: SceneManagement.EditorSceneManager.OpenScene

Thomas Ingram - 2017-08-14T04:46:43

An interesting and really specific missing reference exception can occur when opening scenes.
Say you've used LoadAssetAtPath and now have a reference to an asset. When OpenScene is called Unity will attempt to garbage collect and if your asset isn't assigned to a variable on another asset or window it will be destroyed. So (only tested in static scopes) if you've loaded an asset in a scope and then open a scene you will get a MissingReferenceException. The workaround is to store it in a window, or an asset.

Unity - Scripting API: Undo.RecordObject

Thomas Ingram - 2017-08-09T02:38:19

If using this to set objects as dirty (as you should be doing) the dirty state will only be set when the diff is run at the end of the frame. So if you're using this in combination with SaveAllScenes in one frame for example, the scene will not be marked as dirty, and it will not be saved.

Unity - Scripting API: SceneManagement.EditorSceneManager.SaveOpenScenes

Thomas Ingram - 2017-08-09T02:34:57

If the scenes have not been marked dirty (eg. with MarkAllScenesDirty or MarkSceneDirty) then this will not save.

Disclaimer: This is an unofficial extension and is in no way affiliated with or endorsed by Unity Technologies.