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: 554

Unity - Scripting API: StaticBatchingUtility.Combine

Marcos Pereira - 2022-10-02T23:01:38

I just submitted a bug report because this should be logged to the console - it took me too long to figure out why static batching wasn't working as expected!

Unity - Scripting API: TimelineClip

Gabe Cuzzillo - 2022-05-24T20:57:45

clipin is start time in clip space, start is start in timeline space


Rowan W. - 2022-04-09T15:26:17
Note: The execution order of methods marked [RuntimeInitializeOnLoadMethod] is not guaranteed.

This comes off as a little misleading (though maybe there's a long-term reason why this was specified that isn't communicated); as of at least up to 2022.1, the execution order is somewhat deterministic because they are sneakily alphabetically ordered based off the names of the methods the attribute is attached to.

Take for example the following three methods:

private static void DoSomething() { Debug.Log("DoSomething"); }

private static void AnotherThing() { Debug.Log("AnotherThing"); }

private static void OnThirdThing() { Debug.Log("OnThirdThing"); }

This will always output:

1. "AnotherThing"
2. "DoSomething"
3. "OnThirdThing"

This applies discretely within all RuntimeInitializeLoadTypes - so, you do have some control over this!

Unity - Scripting API: RenderTexture.height

Alex Lovett - 2022-02-22T19:33:26

If renderTexture has already been created then setting this will error: "Resizing of render texture that is loaded not supported!" you need to Release() it first then you can set width/height again. This works for renderTextures that are unity asset files also.

Unity - Scripting API: RenderTexture.width

Alex Lovett - 2022-02-22T19:32:59

If renderTexture has already been created then setting this will error: "Resizing of render texture that is loaded not supported!" you need to Release() it first then you can set width/height again. This works for renderTextures that are unity asset files also.

Unity - Manual: Script Serialization

Marcos Pereira - 2022-02-03T09:39:18

This quote is in 2020.1:

"Generic field types can also be directly serialized, without the need to declare a non-generic subclass."

But not in 2020.3. Does anyone know why?

Unity - Scripting API: Camera.WorldToScreenPoint

homemech - 2021-12-21T20:25:51

Example of using WorldToScreenPoint for point-and-click interactable objects. Using this instead of raycasts has some nice benefits like being able to adjust the "interactable" distance. In this implementation it works really well with the timeline--in editor mode you can keep track of what objects are clickable in different stages or branches of a story.

Unity - Scripting API: ParticleSystem.Play

homemech - 2021-11-23T00:06:42

Here is an example of ParticleSystem.Play with visual scripting in context with other effects:

Unity - Scripting API: Rigidbody.AddForce

homemech - 2021-11-19T04:38:00

Visual scripting + C# Rigidbody.AddForce example here. ForceMode.Acceleration is perfect for conveyor belts and boost ramps! :D

Unity - Scripting API: Material.SetTextureOffset

homemech - 2021-11-19T04:31:18

Here is the SetTextureOffset example in visual scripting:

Unity - Scripting API: Collider.ClosestPoint

isobel shasha - 2021-11-16T02:33:49

appears to just always return the passed vector3 if it's a terrain collider :/

Unity - Scripting API: Highlighter

Ta Yu - 2021-11-14T20:39:50

Also note, only EditorGUI(Layout).PrefixLabel will be highlighted using EditorGUI.BeginLabelHighlight

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

Thomas Ingram - 2021-11-05T11:10:44


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

Marcos Pereira - 2021-11-04T22:52:55

Where did you find this information?

Unity - Scripting API: Event.clickCount

Anomalous Underdog - 2021-10-15T16:26:41

What ought to be emphasized here is that clickCount only ever gets a value of 2 during MouseDown events. It stays 1 on a MouseUp event, even if you did a double-click at that moment. My usual workaround is to use an int variable to store the value of clickCount every time there's a MouseDown event, and then use that in my MouseUp code.

Also, despite being an int, clickCount is either 1 or 2 only. It doesn't detect triple click or anything like that.

Unity - Scripting API: Animator.SetBool

Noah Ratcliff - 2021-10-13T15:45:33

SetBool does not seem to actually do anything if the Animator's GameObject is not active.

Unity - Scripting API: VerticalLayoutGroup

Wukongpvm - 2021-10-08T04:20:36

It also includes (bool) .reverseArrangement which is not currently included in any documentation at this point in time.

Unity - Scripting API: LowLevel.PlayerLoopSystem.updateDelegate

Anomalous Underdog - 2021-09-25T16:39:52

Unfortunately, this page doesn't have any example code but here's how to use updateDelegate to add your own code during a FixedUpdate:

static void Init()
var playerLoop = UnityEngine.LowLevel.PlayerLoop.GetDefaultPlayerLoop();
for (int i = 0; i < playerLoop.subSystemList.Length; i++)
if (playerLoop.subSystemList[i].type == typeof(UnityEngine.PlayerLoop.FixedUpdate))
playerLoop.subSystemList[i].updateDelegate += MyFixedUpdate;


Debug.Log("Game initialized");

static void MyFixedUpdate()

Unity - Scripting API: Handles.Label

Clavus - 2021-09-21T14:30:06

Note that Handles.color does not affect the text color, instead change GUIStyle.normal.textColor and pass that GUIStyle to the third parameter.

Unity - Scripting API: FrameTimingManager

superdupergc - 2021-09-18T02:33:00

I'm guessing it's the same platforms listed in

Scriptable Render Pipeline (SRP) Batcher

Clavus - 2021-08-30T15:18:58

The SRPBatcherProfiler.cs script they mention for profiling here doesn't appear to work in 2020.3 with the most recent URP version due to API changes.

Unity - Scripting API: EditorApplication.Exit

Thomas Ingram - 2021-08-30T01:13:59

If you want to exit the editor to simulate a crash, there's another API that is more suitable: Utils.ForceCrash

Unity - Scripting API: TooltipAttribute

Jonatan Lemos Zuluaga - 2021-08-29T19:03:33

'health' has to be public in order to appear in the Inspector.

Unity - Manual: AssetBundle Dependencies

Nevermind - 2021-08-18T14:10:40

Asset bundle dependencies do not work with dependent PREFABS. If you have a prefab that references a material, and put the material in another bundle, it would result in a dependency. However, if you have a prefab that references another prefab, and you put that second prefab into another bundle, the dependency won't be created: the bundle with the first prefab would have the second one inside, with all its dependencies too.

Unity - Scripting API: MaterialPropertyBlock

Thomas Ingram - 2021-08-13T08:24:10

Note that when using a Scriptable Render Pipeline, the SRP batcher does not support Material Property Blocks.

Script Execution Order Settings

Thomas Ingram - 2021-08-13T02:26:49

See the undocumented DefaultExecutionOrder attribute to do the same thing via a class-level attribute.

Unity - Manual: Preferences

Thomas Ingram - 2021-08-13T00:49:57

New versions of Unity have moved this behaviour to a bug (for debugging) icon in the bottom right of the editor.


Barnaby Smith - 2021-08-05T10:53:46

Note you may need to supply this pragma to ensure that PROCEDURAL_INSTANCING_ON is defined (which in turn defines UNITY_PROCEDURAL_INSTANCING_ENABLED and UNITY_ANY_INSTANCING_ENABLED)

#pragma instancing_options procedural:setup

where setup is at the very least an empty function:

void setup()

See the "#pragma instancing_options" section of for more details, specifically:

procedural:FunctionName Use this to instruct Unity to generate an additional variant for use with Graphics.DrawMeshInstancedIndirect.
At the beginning of the vertex Shader stage, Unity calls the function specified after the colon. To set up the instance data manually, add per-instance data to this function in the same way you would normally add per-instance data to a Shader. Unity also calls this function at the beginning of a fragment Shader if any of the fetched instance properties are included in the fragment Shader.

Unity - Scripting API: Camera.GetAllCameras

nindim - 2021-07-20T06:27:11

This gives access to all the active cameras across all scenes including cameras inside DontDestroyOnLoad.

The first line of the description would be more accurate as: "Fills an array of Camera with all the currently enabled cameras, without allocating a new array."

Unity - Scripting API: Highlighter

Barnaby Smith - 2021-07-18T16:50:00

Note that this is not the same as the highlighting in the project settings/preferences window when you type something in search. Instead this puts a box around a rect that is found by matching a name or identifier.

An easy example is the following:

Highlighter.Highlight("Console", "Error Pause");


If you are looking for the project settings style you can call EditorGUI.BeginLabelHighlight and EndLabelHighlight via reflection - see

Unity - Manual: Receipt validation

Mark Grossnickle - 2021-07-14T21:46:51

Application.bundleIdentifier should be Application.identifier I think

Unity - Scripting API: EditorGUIUtility.IconContent

Anomalous Underdog - 2021-07-13T03:01:10

Seems Disqus messed up their links. If you're getting a DNS_PROBE_FINISHED_NXDOMAIN error with that link, here's the direct url:

Unity - Scripting API: Renderer.SetPropertyBlock

Anomalous Underdog - 2021-07-13T02:57:37

Yeah I realize long after posting that reply that Cian Noonan may have been confused with my comment. I suppose there's two use cases here:
1. Changing a material property once and then leaving it like that.
2. Continually changing a material property over time.

Like I said in my comment 3 years ago, seems you need to do it if you're also continually changing values in the MaterialPropertyBlock. Because my wrong assumption back then, was that since MaterialPropertyBlock is a class, I thought that there was no need to call SetPropertyBlock again after editing the MaterialPropertyBlock.

Unity - Scripting API: Screen.resolutions

joonturbo - 2021-06-30T13:35:03

NB: I have seen Screen.resolutions return an empty array on iOS.

Unity - Scripting API: Mathf.Round

Thomas Ingram - 2021-06-28T08:00:34

If you want normal rounding behaviour, use the System Math class:
(float) Math.Round(value, MidpointRounding.AwayFromZero)

Unity - Scripting API: Mathf.RoundToInt

Thomas Ingram - 2021-06-28T07:59:30

If you want normal rounding behaviour, use the System Math class:
(int) Math.Round(value, MidpointRounding.AwayFromZero)

Unity - Scripting API: AvatarBuilder.BuildGenericAvatar

Jonatan Lemos Zuluaga - 2021-06-21T21:44:51

The last cast is redundant.

Unity - Scripting API: SkinnedMeshRenderer.localBounds

RobD6 - 2021-06-21T10:31:43

The manual page for the SkinnedMeshRenderer goes into a bit more detail:

Debugging C# code in Unity

Thomas Ingram - 2021-06-09T03:42:06

When connecting to a standalone player (especially il2cpp, or over the network) with Jetbrains Rider a blog like this may make it appear like you should select from the configurations dropdown to the right, but really you need to select the smaller Unity dropdown on the left.
Debugging IL2CPP builds this way seems to make breakpoints function correctly over using the configurations connection.

Unity - Scripting API: OffMeshLinkData

David - 2021-06-09T00:08:35

When using NavMeshComponents, this object seems to have limited use.

To get the GameObject that owns your NavMeshLink, use agent.navMeshOwner instead of OffMeshLinkData:

var agent = GetComponent<navmeshagent>();
if (agent.isOnOffMeshLink) {
var link = agent.navMeshOwner as NavMeshLink;
bool is_fall = link != null && !link.bidirectional;
// ...

Unity - Scripting API: Object.DontDestroyOnLoad

Jeremy S - 2021-06-06T16:48:02

Yep - more missing information:

DontDestroyOnLoad technically moves the object to a special scene called "DontDestroyOnLoad". This scene is special in that, when you call SceneManager.LoadScene in "Single" mode, it is the only scene which will not automatically be unloaded.

Unity - Scripting API: Renderer.SetPropertyBlock

Neat Freak - 2021-06-04T15:02:33

Still the same with version 2019.1. You need to remove & re-add the MPB every time a property changes.

Unity - Scripting API: AssetDatabase.CreateAsset

joonturbo - 2021-06-03T15:12:33

I forgot to add the filename to the end of CreateAsset and it just executes without throwing an error but also without creating a file.
Hard to debug this way.

Unity - Scripting API: MonoBehaviour.OnAnimatorMove()

Jonatan Lemos - 2021-06-01T21:34:07

We tested this with my team and found that this method is invoked at each frame after the state machines and the animations have NOT yet been evaluated.

Unity - Scripting API: Vector3.Reflect

joonturbo - 2021-05-27T12:30:03

The image on this page is very misleading.
If you reflect a position instead of a direciton, it would end up on the "other side" of the mirror plane (bottom of the picture), instead of to the side like the picture currently shows.

Unity - Scripting API: Screen.SetResolution

joonturbo - 2021-05-26T13:57:34

Unity caches this, not in playerprefs somehow.
I wrongly assumed that it would, reset to a default resolution, and was storing Screen.width as a base resolution before applying my own stored resolution.
This is bad because Screen.width will return the unity cached value, not the monitor's native width.
Use Screen.resolutions.Last() as a base instead.

Observed in 2020.3.9f1

Unity - Manual: Windows Runtime support

Thomas Ingram - 2021-05-26T07:30:24

When working on a project with the need for the ENABLE_WINMD_SUPPORT define you should enable

Edit/Preferences/External Tools/Generate .csproj files for: Player projects

This will generate an additional csproj, "YourAssembly.Player" for each assembly with the define directives for the target platform enabled. This lets you edit code inside the preprocessor #if properly as it will be active.

Unity - Scripting API: Grid.Swizzle

RaspberrySpaceJam - 2021-05-19T19:12:17

For anyone else like me who was unsure about what the word swizzle means, it is a term that is most common in graphics programming and shaders. The term simply means to map the values of one vector onto a different vector with re-arrangement of the values. Below is an example of using the Swizzle method to swap the X and Y values of a vector.

Vector3 preSwizzle = new Vector3(1.0f, 2.0f, 3.0f);
Vector3 postSwizzle = Grid.Swizzle(GridLayout.CellSwizzle.YXZ, preSwizzle);
//postSwizzle has the XYZ values: 2.0f, 1.0f, 3.0f

It is worth noting that this swizzle method is significantly less robust than swizzling typically is in shaders as it requires that each XYZ value be mapped to the new vector which is not typically a requirement when swizzling. Below is an example of what swizzling looks like in a shader to map the X value onto the XY value of a new vector (which is called a float3 in shader script) and keep the Z value the same.

float3 preSwizzle = float3(1.0, 2.0, 3.0);
float3 postSwizzle = preSwizzle.xxz;
//postSwizzle has the XYZ values: 1.0, 1.0, 3.0

Unity - Scripting API: Physics.ComputePenetration

Barnaby Smith - 2021-05-18T15:20:13

Note you can easily wrap this with a simpler method signature to create a simple collider-collider intersection test, e.g.

public static bool Intersects(this BoxCollider a, Collider b)
return Physics.ComputePenetration(a, a.transform.position, a.transform.rotation, b, b.transform.position, b.transform.rotation, out _, out _);


Niwala - 2021-05-13T08:26:11

So don't return all the assets at path as the name might suggest.
For that you can use System.IO as proposed by FlightOfOne here

Unity - Scripting API: LazyLoadReference

Jake Perry - 2021-05-13T00:43:33
In a standalone player, all assets are loaded when the player is loaded, or when asset bundles are loaded.

Please note, as the quoted part of the documentation suggests, this struct is only intended for editor use. Assets will be loaded immediately in built players as if the LazyLoadReference<t> type wasn't used at all.
Changing your code to use this type is not a performance optimization at all, it's just to speed up iteration in the editor by reducing load times, etc.


Thomas Ingram - 2021-05-12T04:11:06

If you are using the new Input System, mouse-related MonoBehaviour messages are not called. See Known Limitations to see if this has changed.

Unity - Scripting API: MonoBehaviour.OnMouseUp()

Thomas Ingram - 2021-05-12T04:10:26

If you are using the new Input System, mouse messages are not called. See Known Limitations to see if this has changed.

Unity - Scripting API: MonoBehaviour.OnMouseOver()

Thomas Ingram - 2021-05-12T04:09:28

If you are using the new Input System, mouse-related messages are not called. See Known Limitations to see if this has changed.

Unity - Scripting API: MonoBehaviour.OnMouseEnter()

Thomas Ingram - 2021-05-12T04:09:13

If you are using the new Input System, at present mouse-related messages are not called. See Known Limitations to see if this has changed.

Unity - Scripting API: MonoBehaviour.OnMouseExit()

Thomas Ingram - 2021-05-12T04:08:25

If you are using the new Input System, presently mouse-related messages are not called. See Known Limitations to see if this has changed.

Unity - Scripting API: MonoBehaviour.OnMouseDrag()

Thomas Ingram - 2021-05-12T04:07:14

If you are using the new Input System, presently this is not called. See Known Limitations to see if this has changed.

Unity - Scripting API: MonoBehaviour.OnMouseDown()

Thomas Ingram - 2021-05-12T04:06:38

If you are using the new Input System, presently this is not called. See Known Limitations to see if this has changed.

Unity - Scripting API: Collider.bounds

Karel Crombecq - 2021-05-07T08:04:15

Bounds are only updated when a physics tick happens. You can change this behaviour with Physics.autoSyncTransforms, but it has a performance overhead. (source:

Unity - Scripting API: MonoBehaviour

Oscar Abraham - 2021-05-04T23:13:41

This is not accurate: OnDestroy always runs for every MonoBehavior that would have its Awake method called, even if it doesn't define an Awake method. Awake won't run if the whole GameObject is deactivated, but it surely runs when only the MonoBehavior is disabled.

Unity - Scripting API: GameCenterPlatform

joonturbo - 2021-04-20T11:25:51

I found it hard to find a starting point based on this so here's some code

_platform = new GameCenterPlatform();
_initialized = true;

Unity - Scripting API: Application.isEditor

joonturbo - 2021-04-20T11:10:18

it seems I had the simulator window docked somewhere, removing it fixed the issue

Unity - Scripting API: Application.isEditor

joonturbo - 2021-04-20T11:08:41

If you are using the device similator package, it seems that Application.isEditor can return false, even when not running or showing the simulator.
Observed in Unity 2020.1.17f1 / Version 2.2.4-preview

Unity - Scripting API: Transform.SetParent

Eran Arbel - 2021-04-18T08:30:15

Apparently, setting worldPositionStays to false doesn't work for RectTransform..


Thomas Ingram - 2021-04-15T16:52:40

When drawing into the scene view it's important to do this at the rate the scene view renders using something like SceneView.beforeSceneGui. If you're enqueuing these draws from Update you may be outmatching the rendering of the scene view and can run out of the memory used to draw these objects.

Unity - Scripting API: PopupWindow

Barnaby Smith - 2021-04-13T10:29:34

A slightly cleaner approach than needing to cache the last rect in a member field is to use GUILayoutUtility.GetRect() to get the next rect before you draw the button and then GUI.Button(rect) to draw your button which can then also trigger the PopupWindow by supplying the same rect.

Rendering with Replaced Shaders

kirill zubenko - 2021-04-12T13:29:46

URP doesn't support the Replacement shader feature.

Unity - Scripting API: RaycastHit.triangleIndex

Thomas Ingram - 2021-03-29T00:43:53

This will return -1 if your Mesh Collider is marked as convex, as the convex mesh is not actually the same as the mesh assigned to the collider.

Unity - Scripting API: Vector3.SmoothDamp

Danny Hawk - 2021-03-22T16:52:05

There is also a Mathf.SmoothDamp if you want to damp specific values

Unity - Scripting API: QualitySettings.vSyncCount

Valentin Barat - 2021-03-22T10:42:42

as Thomas Ingram said, it goes from 0 to 4 (not 3 as OP) and it is:
0 => Uncapped
1 => x1
2 => x0.5
3 => x0.33
4 => x0.25

Unity - Scripting API: MeshCollider

Jason Lawless™ - 2021-03-11T01:03:16

If you find yourself needing to do this often. Use this:

public static void Recook(this MeshCollider meshCollider)
meshCollider.enabled = false;
meshCollider.enabled = true;

Use it like this: _meshCollider.Recook();


Barnaby Smith - 2021-03-10T14:04:32

Note that as of Unity 5.2 this is just a wrapper for GUIUtility.systemCopyBuffer

Unity - Manual: Physics Manager

Thomas Ingram - 2021-03-08T07:13:25

If you disable auto-simulation you can still query the physics world with raycasts. Be aware that colliders will not update with their transforms unless Physics.SyncTransforms is called, or the legacy Auto Sync Transforms is enabled.

Unity - Manual: Project Templates

Thomas Ingram - 2021-03-06T04:16:58

See 2D and 3D mode settings for more information.

Unity - Scripting API: Object.DestroyImmediate

disqus_FLxOSc4LyB - 2021-03-05T18:17:46

- In the Editor it can destroy assets permanently (as pointed out above, potentially as a consequence of a bug in your code)

Unity - Scripting API: Object.DestroyImmediate

disqus_FLxOSc4LyB - 2021-03-05T18:11:30

- DestroyImmediate moves the destruction out of the normal script execution order. Which means OnDestroy and OnDisable will be called at unusual times. This can lead to null reference errors, or other more subtle problems.

Unity - Scripting API: Renderer.SetPropertyBlock

Anomalous Underdog - 2021-03-05T13:39:08

Things may have changed since I last did this (Unity 5.5)

Unity - Scripting API: Renderer.SetPropertyBlock

Cian Noonan - 2021-03-05T11:55:26

Anomalous Underdog Is incorrect, you set an MPB and they persist with the Renderer

Unity - Scripting API: EditorWindow.ShowModalUtility

Liam Cary - 2021-02-22T07:50:04

This issue has since been fixed in 2020.1 and the issue linked above is updated.

Unity - Manual: Searching

NukeAndBeans - 2021-02-21T07:43:27

Besides t: and l:, other possible values are:

v: Can be used to find objects with different states. e.g. v:modified will show objects that are locally modified
s: Searches by soft lock state. e.g. s:inprogress will show objects modified by anyone, except you
a: Acts as a filter. Possible values are all (all folders), assets (only Assets/), and packages (only Packages/)
b: Searches for assets in asset bundles, by the asset bundle name. e.g. b:mybundle will only look in mybundle asset bundle
ref: Searches by instance ID
glob: Can be used to find assets with extensions of any type, e.g. glob:Assets/**/*.{png|PNG}, which will show any object ending with .png or .PNG in any subfolder.

Unity - Scripting API: AssetDatabase.FindAssets

NukeAndBeans - 2021-02-21T07:38:43

Besides t: and l:, other possible values are:

v: Can be used to find objects with different states. e.g. v:modified will show objects that are locally modified
s: Searches by soft lock state. e.g. s:inprogress will show objects modified by anyone, except you
a: Acts as a filter. Possible values are all (all folders), assets (only Assets/), and packages (only Packages/)
b: Searches for assets in asset bundles, by the asset bundle name. e.g. b:mybundle will only look in mybundle asset bundle
ref: Searches by instance ID
glob: Can be used to find assets with extensions of any type, e.g. glob:Assets/**/*.{png|PNG}, which will show any object ending with .png or .PNG in any subfolder.

Unity - Scripting API: Networking.DownloadHandlerTexture.texture

Henry de Jongh - 2021-02-14T18:23:26

The texture returned will be read-only. If you wish to generate mipmaps at runtime, you must copy it to a new texture with "mipChain" set to true. For example:
var newTexture = new Texture2D(texture.width, texture.height, texture.format, true); // enable mipmaps on a new texture.
newTexture.SetPixels32(texture.GetPixels32()); // copy the pixels to the new texture.
newTexture.Apply(); // generate the mipmaps.

Unity - Scripting API: Rendering.CommandBuffer.SetGlobalTexture

Chris Wade - 2021-02-02T21:13:47

Sharing a gotcha when using in combination with CommandBuffer.Blit(source, target, material): the global texture set here cannot be the same as the target passed to CommandBuffer.Blit or it will fail to be set

Unity - Scripting API: Shader.globalMaximumLOD

Barnaby Smith - 2021-01-25T18:54:04

Default value (at least on Windows Editor) is int.MaxValue (2147483647)


Nevermind - 2021-01-21T16:07:36

EncodeArrayToJPG creates broken JPGs if the input array does have an alpha channel.

Unity - Scripting API: FrameTimingManager

Barnaby Smith - 2021-01-19T16:29:56

Note you need to enable Frame Timing Stats in Player Settings for this to work. Even then it only seems to work on certain platforms in builds.

Unity - Scripting API: BuildOptions.ShowBuiltPlayer

Barnaby Smith - 2021-01-18T16:25:29

After the build completes this will show the output files in File Explorer or Finder

Unity - Manual: Quality Settings

joonturbo - 2021-01-08T17:12:16

I am convinced tht Maximum LOD Level should be renamed to Minimum LOD level.
To the best of my understanding, if Maximum LOD level is set to 1, it will exclude LOD0 (highest quality) from builds and default to LOD1 (lower quality).

Unity - Scripting API: SerializedProperty.GetEnumerator

Matt Ellis - 2020-12-30T13:00:05

Based on testing, the returned enumerator will perform a depth first iteration over visible serialised properties. It will first return the current SerializedProperty instance (the one used to call GetEnumerator(), then iterate its children (recursively) before moving on to siblings. It does not include properties that are marked [HideInInspector].

The SerializedProperty instance returned from Current is the same C# instance that was used to call SerializedProperty.GetEnumerator, which means that the original instance is updated as you iterate through the properties. Use SerializedProperty.Copy() to work with a copy that does not affect the original instance.

Unity - Scripting API: EditorWindow.Show

Thomas Ingram - 2020-12-15T03:43:12

Show calls EditorGUIUtility.ExitGUI which fires an exception which is caught by the GUI context. This will cause code running after this call to not run.
If you want to you can catch the ExitGUIException and re-throw it once you're done.

Unity - Scripting API: SceneManagement.SceneManager.UnloadSceneAsync

Thomas Pryde - 2020-11-22T03:41:18

As a further comment to the third NOTE and at the bottom of the page UnloadSceneAsync will return null if attempted when a single scene is loaded.

Using Java source files as plug-ins

Graham H Reeves - 2020-11-19T23:09:57

.java files can be located anywhere inside Assets/
The build system now IS gradle, and the Build System -> Gradle option, no longer exists

Unity - Manual: Windows Debugging

Matt Boch - 2020-11-18T22:04:22

I found that I had to use the https:// prefix to make step 4 of "Visual Studio Setup" work. It should read:

Add a “Symbol file (.pdb) location” of https://symbolserver.unity3...


Anomalous Underdog - 2020-11-18T19:40:25

One thing to note is that if the Animator is merely looping one state, there really won't be a "next" Animator State Info (no transition to a different state is occuring), but since AnimatorStateInfo is a struct, this will still return a value. But it's a sort of dummy AnimatorStateInfo: the shortNameHash and fullPathHash will be 0. Use Animator.IsInTransition to check if there actually will be a next state in the first place.

Unity - Scripting API: GraphicsFormat

Barnaby Smith - 2020-11-05T18:15:20

In addition to these named GraphicsFormats there are other values that are supported, these include (names are TextureFormat equivalents):

Alpha8 54
ARGB32 88
YUY2 141
ASTC_HDR_4x4 145
ASTC_HDR_5x5 146
ASTC_HDR_6x6 147
ASTC_HDR_8x8 148
ASTC_HDR_10x10 149
ASTC_HDR_12x12 150
PVRTC_2BPP_RGBA 108875872
PVRTC_2BPP_RGBA 108875872
PVRTC_2BPP_RGBA 108875872
PVRTC_2BPP_RGBA 108875872
PVRTC_2BPP_RGBA 108875872
PVRTC_2BPP_RGBA 108875872


herbst - 2020-10-30T09:55:40

For others wondering about the event order, they are called in this order:

static constructor
regular Awake()
regular OnEnable()
Default (without type attribute)
regular Start()

Unity - Scripting API: RenderTexture

Barnaby Smith - 2020-10-28T18:16:20

Be careful to use one of the constructors that takes parameters (i.e. do not use the parameterless constructor with object initializers) because there is a behavioural difference between the parameterless and parametered constructors when it comes to face flipping due to an internal flag that gets set when the parametered constructor is called. If you encounter face flipping issues it may well be because you're calling the wrong constructor.

Unity - Scripting API: EditorTools.EditorTool.OnToolGUI

bgrz - 2020-10-27T14:45:07

SceneView.onSceneGUIDelegate has been replaced by SceneView.duringSceneGui

Unity - Scripting API: Screen.dpi

Andy Moore - 2020-10-15T17:39:32

Note that Screen.DPI returns the logical DPI on windows, which is 96 multiplied by the windows display properties "scaling factor".

Scriptable Render Pipeline (SRP) Batcher

Barnaby Smith - 2020-09-20T15:55:27

As mentioned, SRP Batcher does not work with Material Property Blocks, so if you need to disable SRP Batcher for a renderer you can do it by assigning an empty property block:

targetRenderer.SetPropertyBlock(new MaterialPropertyBlock());

Unity - Manual: Android SDK/NDK setup

Ariontor - 2020-09-12T06:07:45

This video was super useful for me in getting the new SDK to work with Unity:

Unity - Scripting API: Rigidbody.SweepTestAll

Rafał Tadajewski - 2020-09-10T23:13:54

The collision matrix influences which colliders will be taken into account. The layer assigned to rigidbody determines which colliders are detected with. If colliders in certain layers do not interact, they will not be detected by this method either.

Unity - Scripting API: EditorApplication.update

François Degryse - 2020-09-02T15:50:38

This must not be confused with a player loop update (for instance, only a player loop update advances time).
Any registered callback to EditorApplication.update will be called every "tick" in the editor, whether a player loop update happens or not.
The rate at which the editor ticks can be controlled in the editor preferences (starting Unity 2019.3).
A player loop update can be triggered by calling EditorApplication.QueuePlayerLoopUpdate();

Unity - Scripting API: AssetDatabase.FindAssets

François Degryse - 2020-09-01T15:51:14

Undocumented feature: assets can be filtered depending on their asset bundle assignation by specifying "b:" followed by the asset bundle name in the filter parameter.

Unity - Scripting API: AssetDatabase.FindAssets

François Degryse - 2020-09-01T15:31:26

FindAssets will also list sub assets but because sub assets do not have their own GUID, the GUID of their respective main asset will be listed instead.
If multiple sub assets from the same main asset are listed, its GUID will be listed multiple times.

Unity - Scripting API: MaterialPropertyBlock

Thomas Ingram - 2020-09-01T08:45:53

If you're looking to set Tiling or Offset properties use the "_ST" suffix
propertyBlock.SetVector("_MainTex_ST", new Vector4(0.5f, 0.5f, 0.25f, 0.25f));
See Special Texture properties - Texture tiling & offset

Unity - Scripting API: Screen.width

Andy Moore - 2020-08-11T19:28:59

Note that this documentation doesn't have the VR caveat that Screen.currentResolution does.

In VR, Screen.width is the desktop width/height, not the VR eye texture width/height.

Unity - Scripting API: Vector3Int.Vector3

houkanshan - 2020-08-06T05:10:00


Unity - Scripting API: ScriptableObject.OnEnable()

Andy Moore - 2020-08-03T21:06:26

Note that this runs on LOAD, even if the asset isn't in use in the scene at all. Just existing in the project will trigger this when your application loads.

Unity - Scripting API: Debug.ClearDeveloperConsole

Andy Moore - 2020-08-03T19:35:07

Note that this clears the "developer console", which is the graphical console thing that pops up in Debug Builds of your application. This is NOT the console that is in your Unity Editor. If you want to clear the editor console, you have to use reflection - see this post for more:

Unity - Scripting API: GeometryUtility.TestPlanesAABB

Barnaby Smith - 2020-07-21T13:56:47

Note this will return some false positives when the far plane intersects along with one or two of the side planes even when the frustum faces do not intersect and the frustum does not intersect the AABB. The size of this false positive will depend on the size of the AABB and is likely not too big an issue for most usecases.

Also the code sample will return a null ref due to obj always being null. Changing the to will resolve the error

Unity - Scripting API: PrefabUtility.SaveAsPrefabAsset

houkanshan - 2020-07-15T22:31:46

Example of the assetPath: Assets/Prefabs/PrefabA.prefab

Unity - Scripting API: Animation

Cian Noonan - 2020-07-13T09:02:14

Animating a renderers material property will result in a MaterialPropertyBlock being applied to the Renderer!

Unity - Scripting API: UIElements.VisualElement.EnableInClassList

Thomas Ingram - 2020-07-09T03:00:38

Class names to not include the "." prefix

Unity - Scripting API: Time.realtimeSinceStartup

Barnaby Smith - 2020-07-07T14:54:17

There is an excellent explanation of the difference between Time.realtimeSinceStartup and Time.unscaledTime at

Unity - Scripting API: Texture2D.GetPixel

Thomas Ingram - 2020-07-05T12:56:05

You can use this function to print out a formatted list of the supported formats for a ReadPixels destination texture for the current platform:

StringBuilder stringBuilder = new StringBuilder();
foreach (var value in Enum.GetValues(typeof(TextureFormat)))
bool isFormatSupported = SystemInfo.IsFormatSupported((GraphicsFormat) value, FormatUsage.ReadPixels);
stringBuilder.AppendLine($"{value,-20} supported: {isFormatSupported}");

Copy the result into a text editor with a monospace font (the Unity console is not one of these) to see it with formatting.


Barnaby Smith - 2020-06-30T14:19:30

Because additionalVertexStreams takes a Mesh you may find if you want to set a single channel (such as Colors) that you get an error about there being no vertices (positions) set. In order to side step this issue set SetVertexBufferParams() with an attribute layout that only has the attributes you need.

AssetPostprocessor.OnPostprocessSprites(Texture2D, Sprite[])

Wolfgang Neumayer - 2020-06-30T14:16:16

The example code doesn't actually work. The method needs to be "OnPostprocessSprites", not "OnPostProcessSprites", with a lower-case "p". Same goes for "OnPostProcessTexture".

Unity - Scripting API: SerializedProperty.tooltip

Barnaby Smith - 2020-06-30T12:49:43

This will always return empty and is currently marked Won't Fix by Unity - see https://issuetracker.unity3...

A workaround is either to use EditorGUI.BeginProperty() which populates the tooltip in a returned GUIContent or to call ScriptAttributeUtility.GetHandler() via Reflection (BeginProperty calls GetHandler internally)

Unity - Scripting API: Physics.BoxCastAll

Henry de Jongh - 2020-06-28T20:06:47

BoxCastAll doesn't give you all hits for one collider- just the nearest one. This means you can't get all triangles that were hit.

Unity - Scripting API: PrefabUtility

houkanshan - 2020-06-19T22:48:35

Open the prefab stage from a GameObject in scene:

var assetPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(gameObject);
if (assetPath != string.Empty)

Unity - Scripting API: Shader.Find

Cian Noonan - 2020-05-29T10:08:06

Shader.Find only works on shaders from AssetBundles if the shader is in the Graphics "Always Include Shaders". Once registered you can use Shader.Find on shaders in assetbundles just fine

Script compilation and assembly definition files

Thomas Ingram - 2020-05-27T01:54:56

If you want to search for Assembly Definitions in your project: t:AssemblyDefinitionAsset

Unity - Scripting API: BuildTargetGroup

Thomas Ingram - 2020-05-26T02:48:59

Or, if using an IPreprocessBuildWithReport:

Unity - Manual: Android Player Settings

Nikkolai Davenport - 2020-05-24T18:50:24

The Target Architecture option ARM64 is disabled when Scripting Backend is set to Mono.

To enable the ARM64 option, set the Scripting Backend to IL2CPP.

Unity - Scripting API: SceneManagement.Scene.path

houkanshan - 2020-05-19T19:33:19

Could be null if the scene is not loaded before, especially when you use it in editor.

Use this instead:


Thomas Ingram - 2020-05-06T03:23:25

This flag is totally ignored in Awake "By Design"

Unity - Scripting API: ScriptableObject

Thomas Ingram - 2020-05-02T02:37:03

ScriptableObjects used at runtime must be referenced into the build.
This can be achieved by direct references in the scene, the Resources folder, Asset Bundles/Addressables, and PlayerSettings.preloadedAssets.

Unity - Scripting API: AssetDatabase.CreateFolder

Gabe Cuzzillo - 2020-04-30T16:25:04

Important!! make sure you dont have a trailing slash in the parent

this wont work: AssetDatabase.CreateFolder("Assets/", "My folder");

Unity - Scripting API: AudioClip.GetData

Joseph Humfrey - 2020-04-26T10:50:35

Sometimes I find (maybe only with ogg format?) that the number of samples available to GetData() is actually 1 sample less than would be calculated via clip.samples * clip.channels. I get the warning "Data longer than the AudioClip: <clip name="">. 10434229 sample(s) copied". See how in that example the number of samples copied is an odd number, even though there are 2 channels.

Also, the documentation seems to by lying about wrapping around? (thankfully!)

Unity - Scripting API: AddComponentMenu

Thomas Ingram - 2020-04-25T13:19:37

Using this attribute will also remove the pesky (Script) suffix from component headers.

Unity - Scripting API: AssetDatabase.ExportPackage

RaspberrySpaceJam - 2020-04-20T23:36:59

The fileName field needs to end with ".unitypackage".

By default the package builds into the project folder (on the same level as the Assets folder). You can navigate away from this location by altering the fileName for example: "../package.unitypackage" as a fileName will build the package one level up (on the same level as the project folder).


Barnaby Smith - 2020-04-19T14:57:09

Note that this will return the wrong format if the platform has a format override set but override is disabled. Generally it looks like turning off the platform override in the UI will reset the platform format to Automatic, however our project has recently experienced lots of textures with override turned off but still retaining non-automatic overrides. It's not clear why this has happened (possibly a bug in Unity). This means that the Unity UI for example will tell us that a texture is DXT1 (which it is), but calling GetAutomaticFormat will say DXT5 because it had previously been overriden to DXT5.

To work around this you can call TextureImporter.DefaultFormatFromTextureParameters via reflection and pass in the platform settings if override is enabled (otherwise pass in the default platform settings)

Unity - Manual: Unity Remote

Nikkolai Davenport - 2020-04-17T01:18:03

If Unity (2019.3.9f1) doesn't list any iOS devices under Project Settigns > Editor, try disconnecting the device from USB and reconnecting it while Unity is open.

iTunes needs to be installed, but does not need to be open to connect with Unity Remote 5. Install iTunes on Windows 10 Pro (Version 1909) through the Windows Store.

Step-by-step connection procedure:

1. Open a Unity project on Windows 10.
2. Check current Build Settings by selecting File > Build Settings from the menu.
3. Set the build platform to iOS by selecting iOS from the list of Platforms and select Switch Platform.
4. Connect an iOS device to the computer via USB (this should register the device in Unity).
5. Open Editor settings by selecting Edit > Project Settings from the menu, and select Editor from the sidebar.
6. Set the Unity Remote Device to use your iOS device, or Any iOS Device.
7. From the Game view, select Remote from the Aspect Ratio dropdown (optional).
8. Open Unity Remote 5 on your iOS Device (can be opened at any time).
9. Press the Play button in Unity to start using Unity Remote.

Unity - Scripting API: Application.streamingAssetsPath

Dm. Bondarev - 2020-04-14T18:39:34

also read Streaming Assets

Unity - Scripting API: EventType.ValidateCommand

Bart Heijltjes - 2020-04-14T09:31:05

The command name for delete button on keyboard is actually "SoftDelete"

Unity - Scripting API: EditorPrefs

Barnaby Smith - 2020-04-04T19:48:19

Since my comment above Unity have updated to the documentation to reflect that N is always 5 for Unity 5.5 and above (Unity 2017 and above have not updated this version number beyond 5 as was originally mentioned in the Unity 5.5 docs). Note that my above comment is still correct at the time of writing and the docs should say:

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

Installing from a Git URL

bgrz - 2020-03-11T20:54:28

Git support is available in earlier versions too, it's just not exposed through the UI.

Unity - Manual: Git URLs

Thomas Ingram - 2020-03-11T07:24:00

As of 2019.3.4.f1 (and 2020.1.a21) git urls for packages supports subfolders.

You can specify a repository subfolder for a Git package through the path query parameter. The Package manager will only register the package located in the specified repository subfolder and disregard the rest of the repository.

Special considerations:

path must be a relative path to the root of the repository. An absolute path won't work. (ex: path=c:\my\repo\subfolder is ❌️, path=/subfolder is ✅️)
.. and . indirection notation is supported but will block at the repository root (i.e. /../../.. will resolve to / )
path query parameter must be placed before the revision anchor. The reverse order will fail.
A package manifest (package.json) is expected in the specified path.

Path query parameter

Revision anchor and path query parameter

Two packages from the same repository

Preparing Sprite Atlases for distribution

Josh Killinger - 2020-03-04T21:47:39

The best way I've found to dynamically load a SpriteAtlas at runtime based on something like Quality Settings is to ship the Atlases in the Resources folder, then access them from the SpriteAtlasManager.atlasRequested callback.

Unity - Manual: Smart Merge

joonturbo - 2020-03-04T18:21:50

I was curious if this needed to be kept up to date, but it seems like they haven't upgrade YAML merge since 2017

turbo:~ joon$ /Applications/Unity/Hub/Editor/2017.4.12f1/
Error: need 'merge' command specified
Unity YAML Merge Tool for scene or prefab files - version 1.0.1

turbo:~ joon$ /Applications/Unity/Hub/Editor/2019.3.1f1/
Error: need 'merge' command specified
Unity YAML Merge Tool for scene or prefab files - version 1.0.1

Unity - Scripting API: SpriteMask

Chris Wade - 2020-02-28T16:25:34

NOTE: Using sprite mask and the maskInteraction setting on sprites affects the stencil value of these sprites when they're rendered even if that sprite's material has custom stencil settings.

I found this thread explaining a bit better what's going on:

- Short-ish version is when there's a sprite mask present this happens (going to simplify and pretend only sprites and masks are being rendered):
- Sprite masks with custom ranges encapsulate all the sprites in those ranges
- At the start of each group the sprite mask is rendered incrementing stencil value
- Then all the sprites render and their MaskInteraction setting is used to set the stencil settings. Sprites set to VisibleInsideMask are set to draw if the existing stencil value is >= 1. Sprites set to VisibleOutsideMask are set to draw if existing stencil value is <1. Sprites set to none draw normally. This value is changed even if the spriteRenderer is using a material with a custom stencil setting
- At the end of the transparent pass the sprite mask is rendered again decrementing the stencil value so later things aren't affected

Unity - Scripting API: SpriteMaskInteraction

Chris Wade - 2020-02-28T16:22:07

NOTE: Using sprite mask and this setting on sprites affects the stencil value of these sprites when they're rendered even if that sprite's material has custom stencil settings.

I found this thread explaining a bit better what's going on:

- Short-ish version is when there's a sprite mask present this happens (going to simplify and pretend only sprites and masks are being rendered):
- Sprite masks with custom ranges encapsulate all the sprites in those ranges
- At the start of each group the sprite mask is rendered incrementing stencil value
- Then all the sprites render and their MaskInteraction setting is used to set the stencil settings. Sprites set to VisibleInsideMask are set to draw if the existing stencil value is >= 1. Sprites set to VisibleOutsideMask are set to draw if existing stencil value is <1. Sprites set to none draw normally. This value is changed even if the spriteRenderer is using a material with a custom stencil setting
- At the end of the transparent pass the sprite mask is rendered again decrementing the stencil value so later things aren't affected

Unity - Manual: Git URLs

bgrz - 2020-02-25T10:58:56

Git support is available in earlier versions too, it's just not exposed through the UI.

Unity - Scripting API: RuntimeInitializeLoadType

Michael Chugg - 2020-02-14T21:30:50

It's been awhile since I made the comment... I don't remember exactly why I needed it in a case like that but I did. I think I worked around the issue using a different approach though. I just wished the docs has that as a note on this page about it so I added it.

Unity - Scripting API: RuntimeInitializeLoadType

Dmitriy Pyalov - 2020-02-14T20:43:58

Why should it and which Type should it use for generic argument?

Unity - Manual: Smart Merge

Thomas Ingram - 2020-02-09T23:47:21

If you get an error message referring you to a mergespecfile.txt file, it is easier to configure this via the Unity Preferences.
The External Tools/Revision Control Diff/Merge setting will configure the fallback merger that Smart Merge uses. Once this setting is configured Smart Merge will open this tool when a merge couldn't be totally completed. You will only have to resolve the conflicts where Smart Merge failed.

Unity - Scripting API: SystemInfo

Barnaby Smith - 2020-01-30T22:37:06

Also for Oculus Quest (2019.3.0)

batteryLevel: 1
batteryStatus: Full
operatingSystem: Android OS 7.1.1 / API-25 (NGI77B/4342600057100000)
operatingSystemFamily: Other
processorType: ARM64 FP ASIMD AES
processorFrequency: 1900
processorCount: 3
systemMemorySize: 3790
deviceUniqueIdentifier: [REDACTED]
deviceName: Oculus Quest
deviceModel: Oculus Quest
supportsAccelerometer: True
supportsGyroscope: False
supportsLocationService: True
supportsVibration: False
supportsAudio: True
deviceType: Handheld
graphicsMemorySize: 1024
graphicsDeviceName: Adreno (TM) 540
graphicsDeviceVendor: Qualcomm
graphicsDeviceID: 0
graphicsDeviceVendorID: 0
graphicsDeviceType: OpenGLES3
graphicsUVStartsAtTop: False
graphicsDeviceVersion: OpenGL ES 3.2 [email protected] (GIT@b8c103d, I8a36212832) (Date:05/17/19)
graphicsShaderLevel: 50
graphicsMultiThreaded: True
renderingThreadingMode: MultiThreaded
hasHiddenSurfaceRemovalOnGPU: True
hasDynamicUniformArrayIndexingInFragmentShaders: True
supportsShadows: True
supportsRawShadowDepthSampling: True
supportsRenderTextures: True
supportsMotionVectors: True
supportsRenderToCubemap: True
supportsImageEffects: True
supports3DTextures: True
supports2DArrayTextures: True
supports3DRenderTextures: True
supportsCubemapArrayTextures: True
copyTextureSupport: Basic, Copy3D, DifferentTypes, TextureToRT, RTToTexture
supportsComputeShaders: True
supportsGeometryShaders: True
supportsTessellationShaders: True
supportsInstancing: True
supportsHardwareQuadTopology: False
supports32bitsIndexBuffer: True
supportsSparseTextures: False
supportedRenderTargetCount: 8
supportsSeparatedRenderTargetsBlend: True
supportedRandomWriteTargetCount: 20
supportsMultisampledTextures: 1
supportsMultisampleAutoResolve: True
supportsTextureWrapMirrorOnce: 0
usesReversedZBuffer: False
supportsStencil: 1
npotSupport: Full
maxTextureSize: 16384
maxCubemapSize: 16384
maxComputeBufferInputsVertex: 4
maxComputeBufferInputsFragment: 4
maxComputeBufferInputsGeometry: 4
maxComputeBufferInputsDomain: 4
maxComputeBufferInputsHull: 4
maxComputeBufferInputsCompute: 24
maxComputeWorkGroupSize: 1024
maxComputeWorkGroupSizeX: 1024
maxComputeWorkGroupSizeY: 1024
maxComputeWorkGroupSizeZ: 64
supportsAsyncCompute: False
supportsGraphicsFence: True
supportsAsyncGPUReadback: False
supportsRayTracing: False
supportsSetConstantBuffer: True
minConstantBufferOffsetAlignment: True
hasMipMaxLevel: True
supportsMipStreaming: True
graphicsPixelFillrate: -1
usesLoadStoreActions: True
supportsVertexPrograms: True
supportsGPUFence: False


Barnaby Smith - 2020-01-23T13:33:49

Note this is not the applied setting from switching platform, use activeBuildTarget instead for querying that. See the note on that page for how to get the active build target group too.

selectedBuildTargetGroup instead is the setting currently being viewed in the EditorBuildSettings, and therefore may report a different target to the one you actually have active


Barnaby Smith - 2020-01-23T13:33:11

Note this is not the applied setting from switching platform, use activeBuildTarget instead for querying that.

selectedStandaloneTarget instead is the setting currently being viewed in the EditorBuildSettings, and therefore may report a different target to the one you actually have active


Barnaby Smith - 2020-01-23T13:30:38

To get the active build target group use BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget)

Unity - Scripting API: QualitySettings

Barnaby Smith - 2020-01-23T12:55:45

To access the other quality settings as well as what the per platform defaults are you can't use the static properties and methods, instead you must load the QualitySettings Unity object via the AssetDatabase then work with it via SerializedObject or Reflection. See for reference on how the Unity Editor deals with these properties.

QualitySettings qualitySettings = AssetDatabase.LoadAssetAtPath<qualitysettings>("ProjectSettings/QualitySettings.asset");
SerializedObject serializedObject = new SerializedObject(qualitySettings);

Unity - Scripting API: AssetPostprocessor

Logan - 2020-01-21T22:49:46

If looking to only run on "first time" asset import, then assetImporter.importSettingsMissing will tell you whether this is the first time. That way you can run AssetPostprocessor once to create initial settings, and still allow user to make other custom modifications before checking into version control. If others sync down with .meta file, the importSettingsMissing will return false.

Unity - Scripting API: TextAsset.bytes

PsyKaw - 2020-01-21T15:34:16

This property makes a copy of bytes array. Carefull with memory allocation!

How do I make a Spot Light Cookie?

Olly Skillman-Wilson - 2020-01-15T15:25:44

I'd definitely recommend using the full range of black to white values in your cookies, very easy to get banding on lights if you're only using black to grey.

Unity - Scripting API: ContextMenuItemAttribute

Thomas Ingram - 2020-01-14T02:09:59

If you're looking to apply a context menu generically to many/all properties you can use this delegate.

Unity - Manual: Composite Collider 2D

Thomas Ingram - 2020-01-12T10:35:32

Here's a nice quote from melv, a physics programmer at Unity, from the Unity Discord:

[Why does a Composite Collider require a rigidbody?]
Set the Rigidbody2D body-type to Static. This is identical to not adding a Rigidbody2D as the collider will get added to a static Rigidbody2D behind the scenes. It's not any overhead.
This is actually the core problem I had when I created the CompositeCollider2D. The problem was that colliders that don't have a Rigidbody2D are added to the static ground-body that is created behind the scenes. This means all such colliders are attached to this body that never moves. If you were to tell such a collider to use a composite then there's a few problems. The first is that we have no place for you to define the CompositeCollider2D for this behind-the-scenes body (it's not even a Rigidbody2D but a physics body). The other problem, assuming we could define a composite, was that all colliders like this would go to the same composite making them more and more expensive as you added more of them. When shapes are created in the physics system, they are created and attached to a body otherwise they don't work.

So the composite needs a body and it allows you to set that to static so you get identical behaviour and it allows you to control the scope of what gets blended with what. It also ensures that the colliders that are merged together are on the same rigidbody so they cannot move relative to each other which is how the physics wants to work as it moves bodies, not colliders. Moving colliders relative to the body is expensive. Moving bodies isn't because that's what the physics system is all about; moving bodies and updating transforms.
Adding a Rigidbody2D and setting to Static isn't an overhead. Go ahead and create as many as you like. They're, for the most part, ignored by the physics system. It's colliders, contacts and joints and solving them that costs.

You can follow melv on twitter

Unity - Scripting API: Material.shaderKeywords

Barnaby Smith - 2020-01-09T14:47:23

This list is returned alphabetically sorted regardless of the keyword order specified by inspecting the material in the debug inspector or by examining the yaml of the material in a text editor. For example you can specify the shader keywords B A C in the debug inspector and this will be visible in the .mat file yaml too, but this property will return A B C

Unity - Scripting API: InitializeOnLoadAttribute

Hasan Bayat - 2020-01-07T08:41:17

It doesn't work with Generic classes like MyScript<t> like if you're using it for creating base classes such as MyBaseEditorWindow<t> : EditorWindow with InitializeOnLoad or InitializeOnLoadMethod it wouldn't work.

Unity - Scripting API: PropertyDrawer.fieldInfo

Thomas Ingram - 2019-12-25T09:01:19

If applied to a collection, the FieldInfo will refer to the collection itself, and not the members, which is different to what the property drawer itself is drawing (ie. each member).
This is counter-intuitive, but of course there is no FieldInfo describing a member of a collection.

Unity - Manual: HDR color picker

Thomas Ingram - 2019-12-25T08:02:19

If you want to display this colour picker in a script, you can add [ColorUsage(...)] to a Color property.
Similarly, for HDR colour pickers in shaders, you can add [HDR], as specified here.

Unity - Scripting API: SceneManagement.SceneManager.GetSceneByBuildIndex

Thomas Ingram - 2019-12-22T00:06:55

See also:
EditorBuildSettings.scenes and

Unity - Scripting API: QualitySettings.vSyncCount

Thomas Ingram - 2019-12-12T11:04:00

I think this information is off by one, where a vSyncCount of 1 should be the monitor's refresh rate, 60/1. And the divisions go from there, instead of VSync starting at 1/2 of the refresh rate when enabled.

Unity - Manual: Windows Debugging

sebas77 - 2019-12-11T18:34:28

the way to use this from 2018 onward is this: ? {,,mono-2.0-bdwgc.dll}mono_pmip((void*)0x12345678)

Unity - Manual: Windows Debugging

sebas77 - 2019-12-11T18:28:06

unluckily that plugin doesn't work with 2019.2 and this page is outdated too apparently

Unity - Scripting API: AI.NavMesh.CalculateTriangulation

Barnaby Smith - 2019-12-11T14:59:48

Note that the mesh produced does not appear to be completely deterministic and when testing with 2019.3.0b10 produces different results even with sequential CalculateTriangulation calls. In my tests, the triangulation appears to deterministic but alternates between two different triangulations with each call.

Unity - Scripting API: StaticEditorFlags

Barnaby Smith - 2019-12-10T18:03:56

You can get and set these values using GameObjectUtility.SetStaticEditorFlags and GameObjectUtility.GetStaticEditorFlags

Note that this enum as well as GameObjectUtility is part of UnityEditor, so you cannot use it in builds. This is because static flags are really an editor concept and don't really exist at runtime.

Unity - Scripting API: Graphics.ConvertTexture

Barnaby Smith - 2019-11-28T09:40:10

There are multiple methods in SystemInfo to check if a target format is supported as a RenderTexture, such as IsFormatSupported with FormatUsage.Render supplied and SupportsRenderTextureFormat

Unity - Manual: Windows Debugging

sebas77 - 2019-11-25T14:07:05

Although the code is not maintained anymore, so there is the chance it could break at a given point, this code can be very useful to debug with windbg too.

Unity - Scripting API: AssetDatabase.StartAssetEditing

Thomas Ingram - 2019-11-22T01:18:19


//Edit your assets

Unity - Scripting API: IPreprocessBuild

Nikkolai Davenport - 2019-11-20T21:19:40

IPreprocessBuild was made obsolete starting with Unity 2018.1. Use compiler conditional statements with platform #define directive UNITY_2018_1_OR_NEWER to implement IPreprocessBuildWithReport, and keep IPreprocessBuild for backwards compatibility with older versions of unity.

public class Example : UnityEditor.Editor,
#if UNITY_2018_1_OR_NEWER

Unity - Manual: Font

Thomas Ingram - 2019-11-17T05:18:17

Want a monospaced font for an editor control?

Unity - Scripting API: Transform.GetSiblingIndex

François Degryse - 2019-11-14T13:58:37

If you have objects with HideFlags.HideInHierarchy in your hierarchy, they still count in the sibling index.

Unity - Scripting API: MenuItem

Chris Cunningham - 2019-10-31T14:41:39

When you use this via the context menu with multiple objects selected it will execute multiple times.
You can use the `MenuCommand.context` to see what object it is acting on and compare with your selection if you want it to only execute once.
MenuCommand.context will be null if the menu item is executed from the top menu or keyboard shortcut.

[MenuItem("GameObject/How Many Objects Selected")]
private static void MakeAllSelectedGameObjectsVisible(MenuCommand menuCommand) {
if (Selection.gameObjects.Length > 1 && menuCommand.context != Selection.gameObjects[0]) {
Debug.Log($"You have {objects.Length} objects selected");

Unity - Scripting API: Texture2D

Chris Cunningham - 2019-10-30T13:15:20

Some of the old methods for loading a image from byte array as well as encoding to PNG or EXR have been removed from this calls and re added as extension methods in `ImageConversion`

Unity - Manual: ShaderLab: Pass Tags

Seb - 2019-10-29T16:38:33

ShaderLab has SubShader and Pass Tags to control render order and light modes.

SRP adds a RenderPipeline tag. For the LWRP this must be "RenderPipeline" = "LightweightPipeline". This allows support for different pipelines within the same shader.

LightMode now has a LightweightForward, SRPDefaultUnlit, ShadowCaster and DepthOnly modes for the LWRP. Although it is possible to register new light modes in a custom render pass. See ScriptableRenderPass.cs for details.

If no "RenderPipeline" tag and "LightMode" is specified, the LWRP will still render it. This allows existing simple unlit shaders to work out of the box.

Unity - Manual: Vertical Layout Group

Jacob Lynggaard Olsen - 2019-10-29T14:09:44

For an example of the Use Child Scale property, check out:

Unity - Scripting API: Collider.bounds

Chris Wade - 2019-10-17T07:04:49

Note that these bounds are axis aligned, meaning rotating a collider changes its bounds!

Unity - Scripting API: MonoBehaviour.OnValidate()

Thomas Ingram - 2019-10-16T01:19:01

This function may not actually cause an asset to be reserialized with new data.
If you use this function to populate something and find the changes are not being serialized, you can just use EditorUtility.SetDirty to cause the changes to be recognised, save the project, and then remove the line of code when you're done.

Unity - Manual: Player Settings

crowbarska - 2019-10-14T08:49:25

Something not mentioned here: custom cursors have a few requirements which, if not met, can leave your cursor looking blurry or the wrong scale. You should ensure that your cursor texture is 32 x 32. Also, in the image's import settings change Texture Type to "Cursor".

Unity - Manual: Command line arguments

joonturbo - 2019-10-02T16:18:58

its 2019 and still doesn't seem to be supported for tvOS

Unity - Scripting API: AssetImporter.GetAtPath

Anomalous Underdog - 2019-09-29T07:01:34

The path argument needs to be relative to the project's Assets folder (should start with "Assets/"). If you have a UnityEngine.Object variable, you can use AssetDatabase.GetAssetPath() to get the asset path for it.

Unity - Scripting API: AI.NavMeshPath.corners

Danny Hawk - 2019-09-25T00:46:28

The corners are always in order from closest to furthest. So if you are using the navmeshpath calculations but are moving your AI yourself, then you can just start by seeking corner at index 0, then index 1, and so on.

Unity - Manual: Unity Test Runner

Thomas Ingram - 2019-09-20T15:10:03

If you can't see any docs here go the package docs version

Unity - Scripting API: AudioClip.GetData

joonturbo - 2019-09-20T14:44:49

this was kind of non obvious to me, but the sample count you get from a clip is for one channel.
Meaning you'll have to multiply it by the amount of channels when preparing the array for GetData.
It's in the exampel code (new float[audioSource.clip.samples * audioSource.clip.channels];) but I somehow missed it and took me a while to figre out.

Unity - Scripting API: EditorWindow.ShowModalUtility

François Degryse - 2019-09-18T08:16:40

This method does not work as the documentation specifies and according to this issue on the bug tracker, it will never be fixed.

Unity - Scripting API: MaterialPropertyDrawer

Graham H Reeves - 2019-09-15T17:21:27

One option not listed here, but built-in, is
To hide (but still reflect)

Unity - Scripting API: UIElements.EventBase.timestamp

Thomas Ingram - 2019-09-15T05:25:34

timestamp = (long)(Time.realtimeSinceStartup * 1000.0f);

Unity - Scripting API: MeshCollider

SkywardRay - 2019-09-14T11:33:18

If you want the collider to update after changing the sharedmesh, just disable and then enable the MeshCollider component. See:

Importing from the Asset Store

Barnaby Smith - 2019-09-10T11:56:57

As a slight shortcut on Windows you can also use

%AppData%\Unity\Asset Store-5.x

(Unity 5+ asset store has added a new folder)

Unity - Scripting API: Application.isBatchMode

Barnaby Smith - 2019-09-10T10:31:57

Prior to Unity 2018.2 you can use InternalEditorUtility.inBatchMode

Unity - Scripting API: UnityEvent

Thomas Ingram - 2019-09-09T11:13:08

Looking to add persistent listeners at edit mode, but have noticed that those functions are internal?
UnityEventTools is where you should be looking.


Barnaby Smith - 2019-08-27T12:37:33
When a game object is part of a Scene, the Scene path is returned.

For clarity, the Scene path is the AssetDatabase path to the Scene, e.g. Assets/Scenes/MyScene.unity, not the hierarchy path within the scene.

Unity - Scripting API: Collider.ClosestPoint

joonturbo - 2019-08-23T17:20:48

Just spent a long time figuring out that it just returns the passed vector3 also if it is inside of the collider (at least for boxcollider)

Unity - Scripting API: CreateAssetMenuAttribute

haowan - 2019-08-10T09:19:43

[CreateAssetMenu(fileName = "SUPER NEAT THING", menuName = "SUPER/NEAT/THING", order = 100)]


Barnaby Smith - 2019-08-08T13:59:03

I believe you can use PrefabUtility.IsDefaultOverride to check for most of these

Unity - Scripting API: Physics.CapsuleCast

Chris Wade - 2019-08-06T03:53:03

The example code shown here is misleading. The parameter info above notes Point1 and Point2 must be at the center of the spheres at the ends of the capsule, while the example code uses CapsuleCollider.Height which is the length of a capsule including Radius of the spheres on each end. Here's a code snippet so you can test this yourself:

Unity should tweak the example code to look like this (using TransformPoint also takes into account the capsule being scaled):
Vector3 pointOffset = Vector3.up * (capsule.height / 2f - capsule.radius);
Vector3 p1 = transform.TransformPoint(pointOffset);
Vector3 p2 = transform.TransformPoint(-pointOffset);

Unity - Scripting API: Texture2D.GetPixelBilinear

Barnaby Smith - 2019-07-30T17:02:10

At first glance from the code sample alone you may assume that pixel XY to texel UV would be achieved by by normalizing to 0-1 range:

float u = x / (texture.width - 1);
float v = x / (texture.height - 1);

However as the documentation above says this is not correct, you should instead normalize to one pixel less, as a UV of 1 is would be the same as 0 in repeat filter mode, so instead the conversion should be:

float u = x / (texture.width);
float v = x / (texture.height);

Unity - Scripting API: AssetDatabase.RenameAsset

François Degryse - 2019-07-26T13:22:11

The extension of the original asset name will automatically be added to the new name if it is missing or if the specified extension of the new name is different.

Unity - Scripting API: SerializedProperty.propertyPath

RaspberrySpaceJam - 2019-07-25T17:33:43

The path returned is delimited by periods. If an object in the path is an array it will be followed by "[index]".

Example of path being used to get the object at the end of the path using reflection:
/// <summary>
/// Draw a custom layout for MyClass
/// </summary>
/// <param name="position">Editor window position</param>
/// <param name="property">Serialized property being drawn</param>
/// <param name="label">Property label</param>
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
MyClass class = GetValueByPath(property.serializedObject.targetObject, property.propertyPath) as MyClass;

/// <summary>
/// Navigates to the object at the end of the serialized property path.
/// </summary>
/// <param name="source">The serialized object target.</param>
/// <param name="path">The path to the property.</param>
/// <returns>The object at the end of the property path.</returns>
public object GetValueByPath(object source, string path)
string[] pathStrings = path.Split(new string[] { "." }, System.StringSplitOptions.None);
int i = 0;
while(i < pathStrings.Length && source != null)
if (pathStrings[i] == "Array")
string[] arrayStrings = pathStrings[i].Split(new string[] { "[", "]" }, System.StringSplitOptions.None);
source = ((System.Array)source).GetValue(int.Parse(arrayStrings[1]));
source = GetValue(source, pathStrings[i]);
return source;

/// <summary>
/// Returns the property, field, or value of the given name on the object.
/// </summary>
/// <param name="source">The object to find the property, field, or value on.</param>
/// <param name="name">The name of the property, field, or value.</param>
/// <returns>The property, field, or value.</returns>
public object GetValue(object source, string name)
if (source == null)
return null;
var type = source.GetType();
var f = type.GetField(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
if (f == null)
var p = type.GetProperty(name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
if (p == null)
return null;
return p.GetValue(source, null);
return f.GetValue(source);

Unity - Scripting API: CopyTextureSupport

Barnaby Smith - 2019-07-24T13:04:02
Metal and WebGL currently do not have texture copy support

This does not appear to be correct, or may have changed - SystemInfo.copyTextureSupport reports the following for Metal on iPhone 7 (Unity 2019.3.0a10):

Basic | Copy3D | DifferentTypes | TextureToRT | RTToTexture

CopyTexture definitely works on device, tested by copying RGBA32 texture into a larger RGBA32 texture

It also appears to work in a Mac Editor set to Metal (so may also work in macOS standalone)

Unity - Scripting API: SkinnedMeshRenderer.BakeMesh

Liza Knipscher - 2019-07-16T20:51:18

Note: if you're creating new meshes to use temporarily to bake skinned meshes, make sure to explicitly destroy them or you'll end up with orphaned meshes retained in memory. See example:

Unity - Manual: Using Animation Events

Thomas Pryde - 2019-07-10T12:55:20

A small gotcha when blending animations is events wont trigger if the animations' blend weight is 50% or less. This is commonly noticed when adding an OnComplete event on the last frame. Consider making a custom StateMachineBehaviour or a coroutine to wait the duration of the animation clip.

Unity - Scripting API: EventSystems.PointerEventData.pointerId

Hugo Scott-Slade - 2019-07-01T10:09:03

"When using touchscreen on mobile versions (such as iPad, iPhone, or Android), touches go from 0 up to however many touches the device supports." is not accurate.

I have found that during the begin and end phases of a touch, it can have the id of -1. This is true of both iOS and Android.

I created something to stop multi-touch on UI and the check I now use is eventData.pointerId <= 0

Unity - Scripting API: MonoBehaviour.OnEnable()

Felewin - 2019-06-30T20:00:21

Description is misleading; objects cannot "become enabled", rather monobehaviours can.
Here's a more accurate description:
These functions are called when either:
• the monobehaviour is toggled (this is toggling of enablement) – while the object is active
• the monobehaviour's object is toggled (this is toggling of activity) – while the monobehaviour is enabled

Unity - Scripting API: EditorGUI.DrawPreviewTexture

Thomas Ingram - 2019-06-29T02:19:22

If you want to draw transparent textures with this method you can use this material:
new Material(EditorGUIUtility.LoadRequired("Previews/PreviewTransparent.shader") as Shader) {hideFlags = HideFlags.HideAndDontSave};

Unity - Scripting API: EditorGUI.DrawPreviewTexture

Thomas Ingram - 2019-06-26T06:35:04

Textures drawn by this function will flicker if drawn using a PropertyDrawer. Custom Inspectors will disable this behaviour, but for consistency your property drawer can override CanCacheInspectorGUI and return false, which fixes the issue.

Unity - Scripting API: Mathf.Sign

Thomas Ingram - 2019-06-25T12:52:46

Due to the properties of 0 signing to 1, and Random.Range(int, int) having an inclusive lower bound and an exclusive upper bound you can use:
Mathf.Sign(Random.Range(-1, 1)); to generate a -1 or 1.

Unity - Scripting API: Component.CompareTag

Thomas Ingram - 2019-06-24T04:07:52

Component.CompareTag internally calls .gameObject.CompareTag so eek out those very small performance gains if possible.

Unity - Scripting API: Android

Noah - 2019-06-19T10:41:11

If you're trying to get BuildPipeline.BuildPlayer to emit a Gradle project instead of an apk, you need to add BuildOptions.AcceptExternalModificationsToPlayer to the BuildPlayerOptions.
See this thread:

Unity - Manual: Audio Source

Maize Wallin - 2019-06-17T03:12:37

While the low pass filter only works if the component is added, there is also high pass filter, which does not appear in the graph but there is also a component for.

Unity - Manual: Rich Text

Thomas Ingram - 2019-06-16T03:32:44

You can escape a rich text tag by placing a redundant one immediately after the opening bracket like:
*the asterisk symbols are to be removed, disqus strips away the tags otherwise
Which will print:
Which can be helpful when you wish to display these tags in the console.

You can also replace the angle bracket characters with U+3008 and U+3009.

Unity - Scripting API: AudioSettings.dspTime

Felewin - 2019-06-14T22:20:24

It would seem pertinent to explain what "DSP" actually stands for. It stands for "Digital Signal Processing":

Unity - Scripting API: PlayableExtensions

HilariousCow - 2019-06-13T12:50:31

Note that setting input weight to zero on any playable will result in any nodes upstream of that input not being evaluated - transforms and animated properties will therefore not filter down.
This is unimportant in the case of AnimationLayerMixerPlayables and AnimationMixerPlayables because the mixer math means that zero weight on the inputs would have zero change to the outcome.

The progression of a playable's time, however, is unaffected. You're merely skipping the animation evaluations in the leaf nodes, (or any IAnimationJob processes? I could be wrong?)

Obviously this is an optimisation, and a perfectly sensible one.

In the case of IAnimationJobs, however, you might be tempted to have a "dead" input stream (weight = 0f) which you still sample for other data.

If you'd like to do something like this (case in point, we wanted to have a PropertyStreamHandle, animated by a custom curve, drive the weight of each input), just fix the playable's inputs to be greater than 1, then in your mixer math, use something other than stream.GetInputWeight as your effective weight (i.e, we used the PropertyStreamHandle's value for each input).
Just know you're going to jettison an optimization by doing that.

Unity - Scripting API: TransformSceneHandle -

HilariousCow - 2019-06-12T12:21:03

(Copied from the TransformStreamHandle page)

Difference between TransformStreamHandle and TransformSceneHandle is really important (and the similar names can trip you up!)

Stream Handles are values which are adjusted inside the playable graph/animation job. But only inside. If you try to change the outside, all that happens is, they'll override their positions based on any animations that animate their properties. If they are not animated by anything, they will use the "default" values for their orientation... i.e. localPosition =, localRotation = Quaternion.identity.

If you need some bone or target you need to manipulate and have the graph use it, use a Scene Handle, not Stream Handle. Also bear in mind that you cannot write to this inside the job.

SceneHandles = Job Inputs (kinda like the parameters for your job)
StreamHandles = Job Outputs (which start out animated/at default values, but you can manipulate them in the stream)

Unity - Scripting API: TransformStreamHandle

HilariousCow - 2019-06-12T12:20:22

Difference between TransformStreamHandle and TransformSceneHandle is really important (and the similar names can trip you up!)

Stream Handles are values which are adjusted inside the playable graph/animation job. But only inside. If you try to change the outside, all that happens is, they'll override their positions based on any animations that animate their properties. If they are not animated by anything, they will use the "default" values for their orientation... i.e. localPosition =, localRotation = Quaternion.identity.

If you need some bone or target you need to manipulate and have the graph use it, use a Scene Handle, not Stream Handle. Also bear in mind that you cannot write to this inside the job.

SceneHandles = Job Inputs (kinda like the parameters for your job)
StreamHandles = Job Outputs (which start out animated/at default values, but you can manipulate them in the stream)

Unity - Manual: Audio Reverb Filter

Danny Hawk - 2019-06-11T23:37:44

Audio reverb filter (along with other effects) will not work in a WebGL build for this reason.

Unity - Scripting API: Selectable

Ben Haderle - 2019-06-10T22:32:14

IsPressed() is protected not public

Unity - Scripting API: Renderer.SetPropertyBlock

HilariousCow - 2019-06-07T15:14:42

Oh for real? You can't just call it once when you create a new instance? It has to always be upkept?

Unity - Scripting API: SerializedProperty.Next

Noah - 2019-06-07T12:43:52

Used this in a property drawer for elements in an array, but on the last iteration of the loop, prop would be the next element in the array. Switching the order of the conditionals in the while loop worked:

SerializedProperty end = prop.GetEndProperty();
while (prop.Next(true) && !SerializedProperty.EqualContents(prop, end))

Unity - Scripting API: AsyncOperation.completed

rjkward - 2019-06-03T15:04:43

this doesn't seem to fire for the AsyncOperation returned by EditorSceneManager.LoadSceneAsyncInPlayMode in 2018.4.1f1

Unity - Scripting API: SerializedProperty.Next

Thomas Ingram - 2019-05-26T14:14:28

To iterate over the children of a Property as hinted at in GetEndProperty, you need to:
SerializedProperty end = prop.GetEndProperty();
while (!SerializedProperty.EqualContents(prop, end) && prop.Next(true))

Where prop is your SerializedProperty.
Using the Next iterator will advance your SerializedProperty, so use Copy if you want to make a copy to iterate over.

Execution Order of Event Functions

HilariousCow - 2019-05-24T14:48:06

Also missing: ProcessRootMotion (part of IAnimationJob) is executed just before OnAnimatorMove, but after ProcessGraph (e.g. "PrepareFrame" calls to your ScriptablePlayables)

Unity - Scripting API: IAnimationJob

HilariousCow - 2019-05-24T14:43:32

I hadn't realized but the Order of Execution page has actually been updated to cover this.

Still doesn't cover everything, though. ParentConstraint is notably missing.

Execution Order of Event Functions

HilariousCow - 2019-05-24T14:42:13

Constraints systems fire last thing before LateUpdate.

Understanding the managed heap

bgrz - 2019-05-21T14:14:21

Cool history tidbit from stack overflow:

It was in early 2008 that Unity and Mono announced their collaboration, and at that time Unity licensed the Mono runtime (GPL covered for open source usage) so as to embed it. And the Boehm GC was the primary GC in Mono then.

Time passed and Mono 4.x/5.x by default uses SGen GC with generational/compacting features. However, Unity did not want to pay the licensing again. Thus, you see the documentation remains it was.

Microsoft acquired Xamarin in 2016, and hence gained control of Mono core assets. It republished the code base under MIT, so solving the licensing issue for ever. Unity joined .NET Foundation and started to work with Microsoft/Xamarin to incorporate the latest Mono runtime into the game engine.

That effort is still undergoing and should soon reach maturity (currently an experimental feature).

BTW, Unity cannot use the standard .NET GC yet. Microsoft does not open source its GC in .NET Framework, but a version in .NET Core. That GC is different from Mono's, and would require more efforts to be embedded into Unity. I guess that's why Mono 5 was chosen to be integrated right now. Maybe in the future Unity would migrate to the .NET Core GC.

Unity - Scripting API: Playables.PlayableDirector.time

Robert Yang - 2019-05-05T23:04:46

note: this value goes back to 0 after it finishes playing a Playable, even if its WrapMode (extrapolationMode) is set to "None"... to detect when a PlayableDirector is done playing, I do a little hack:
playableDirector.time = 0.001;
if ( playableDirector.time <= 0 ) // director is finished

Unity - Scripting API: IAnimationJob

HilariousCow - 2019-05-01T13:51:25

Execution order:

After Updates and Coroutines, non manually evaluated animators will execute:

1. ProcessRootMotion
2. OnAnimatorMove
3. ProcessAnimation
4 (ProcessHuman if you have one)
5. LateUpdate etc.

So if you have world space IK targets to process in your ProcessAnimation calls, your safest bet is to update them in OnAnimatorMove after you've updated the position if your Animator transform or any of its parents.
This was an issue for me because I had a camera rotation target as a TransformSceneHandle, which was a child of the animator system, so it was pushed around by the root motion, and thus my IK for first person didn't have a fresh world space target camera orientation to bind to - it had been moved just in time, so to speak!

Unity - Scripting API: AssetDatabase.FindAssets

Thomas Ingram - 2019-05-01T06:45:40

When using the type search t:ObjectType some types will not be found. If this is the case you should provide the FullName (the namespace and type).
This will work for types that were previously already being found, so it's advisable to use instead of the simple type Name.

Unity - Manual: Log Files

Thomas Ingram - 2019-05-01T04:24:51

You can change the directory that the Editor logs to, the same Command Line Arguments detail under Player describes this process.

Unity - Scripting API: Editor.OnPreviewGUI

Thomas Ingram - 2019-04-30T14:53:13

If you do implement this method you should also implement HasPreviewGUI.

Unity - Scripting API: IPreprocessBuild

Rémy Maetz - 2019-04-26T08:55:00

See here for new version :

Unity - Scripting API: Build.IPreprocessBuild.OnPreprocessBuild

Rémy Maetz - 2019-04-26T08:54:29

New method :

Unity - Scripting API: Editor.OnSceneGUI()

Thomas Ingram - 2019-04-22T23:34:54

OnSceneGUI is called once per target. So making a multi-Object inspector involves no work using the targets array.

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.

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: 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 - 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.