Checks Reference

intermediate feature

Editor Doctor Pro · Features

This page lists every check Editor Doctor Pro performs, grouped by the Doctor tab where the finding surfaces. Each check has a stable Rule ID (used by reports, the suppression store and the CLI), a title, a default severity, and an Auto-fix indicator. Total: 120 checks across 5 categories.

Fix tiers: Auto means EDP can apply the fix itself from the Doctor row; Manual opens the offender so you can resolve it by hand; None means the rule is advisory (typically Code Audit findings that depend on author intent).

Asset Health (46)

14 Auto-fix, 32 Manual.

Asset import and reference health: textures, materials, meshes, audio, animation, scriptable objects, prefab references, project settings. When the Scene Pilot Pro bridge is enabled, an additional 64 in-scene SPP checks run across every scene and prefab in the project; they surface under the Scenes tab and follow the same severity / suppression model. Click any finding in the Doctor to expand the explanation panel (Why / Safe fix / Risk); rule copy lives in Editor/Data/rule-explanations.json so teams can extend it without forking EDP.

#Rule IDTitleSeverityAuto-fixDescription
1EDP-ADDR-001Asset is both Resources and AddressableWarnManualAn asset under a Resources/ folder is also marked Addressable. Pick one runtime loading path to avoid duplicate inclusion and ownership ambiguity.
2EDP-ANIM-001Animation clip has no curvesWarnManualA standalone .anim clip carries zero curves and zero object-reference curves. Usually a leftover from a renamed import or a half-authored clip; populate or delete to stop shipping dead weight.
3EDP-ANIM-002Animator layer has no entry stateErrorManualAn AnimatorController layer has zero states, or its default state is null. The Animator silently sits in AnyState at runtime. Pick a default state per affected layer.
4EDP-ANIM-003Animator layer missing avatar maskWarnManualAn additive or override Animator layer has non-zero weight but its Avatar Mask is null. The layer silently drives all body parts instead of the masked subset.
5EDP-ANIM-004Animation clip has stale eventsWarnManualAn AnimationClip carries one or more events with an empty function name. The event silently no-ops at runtime; wire it to a method or strip it.
6EDP-ANIM-005Override controller has missing sourceWarnManualAn AnimatorOverrideController points to a deleted source controller, so it no longer drives anything. Repoint to a valid source or delete the override.
7EDP-ANIM-006Animator references missing parametersWarnManualAnimatorController transitions or blend trees reference parameter names that are not declared on the controller. The conditions never evaluate as authored.
8EDP-AUD-001Long clip uses Decompress On LoadWarnAutoA clip longer than ~5s ships with load type Decompress On Load, holding the full decompressed PCM in RAM as soon as it is referenced. Switch to Compressed In Memory unless instant playback is required.
9EDP-AUD-002Stereo clip is a force-mono candidateInfoAutoA stereo clip lacks Force To Mono. Stereo on a 3D-spatialised source is downmixed at runtime, doubling memory for no gain. Enable Force To Mono if the clip is only played 3D. Heuristic: opt-in because stereo can be intentional.
10EDP-AUD-003Short clip ships at high bitrateInfoManualA clip shorter than ~1s imports at >192 kbps. The extra quality is inaudible at that duration and costs disk + bandwidth. Lower the quality on the default sample settings.
11EDP-AUD-004Short clip uses StreamingWarnAutoA clip shorter than ~1s imports with load type Streaming. Streaming a tiny clip keeps a file handle open per-instance for no benefit. Switch to Decompress On Load.
12EDP-AUD-005Long clip preloads audio dataWarnAutoA clip longer than ~5s has Preload Audio Data on. Long clips loaded eagerly stall scene transitions. Disable to lazy-load on first play.
13EDP-MAT-001Material has no shader assignedErrorManualThe material's shader reference is null (deleted or GUID changed). Every renderer pointing at it falls back to the magenta error material at runtime. Pick a replacement shader manually.
14EDP-MAT-002Material's shader has compile errorsErrorManualThe material points at a shader that fails to compile. Renderers will fall back to magenta at runtime. Open the shader source and resolve before shipping.
15EDP-MAT-003URP shader used without URP installedWarnManualThe material is wired to a Universal Render Pipeline shader, but the URP package is not loaded in this project. The material renders as magenta. Install URP or swap the shader.
16EDP-MAT-004Material could enable GPU InstancingInfoAutoThe material's shader supports instancing (Standard / URP Lit / Simple Lit / Unlit) but Enable Instancing is off. Enabling lets repeated instances draw in fewer batches.
17EDP-MAT-005Material overrides render queueInfoAutoThe material sets an explicit render queue different from the shader's default. Often a leftover from manual debugging that breaks transparent / opaque sort order across pipelines. Reset unless the override is intentional.
18EDP-MAT-006Material has orphan shader keywordsWarnAutoThe material has shader keywords enabled that its current shader does not declare. Auto-fix strips the orphan keywords; the material's render look is unchanged because Unity already ignored them at build time.
19EDP-MESH-001Mesh has Read/Write enabledWarnAutoThe model importer keeps a CPU-side copy of the mesh, doubling memory. Disable unless the mesh is sampled from C# code (Mesh.vertices, MeshCollider with non-convex collider, etc.).
20EDP-MESH-002Mesh exceeds vertex budgetWarnManualTotal vertex count across all sub-meshes exceeds the budget (default 65k). Consider authoring an LOD chain or simplifying the mesh.
21EDP-MESH-003Model imports redundant materialsInfoAutoThe model imports materials with location InPrefab. If your project assigns materials manually, the imported sub-assets are dead weight; set Material Import Mode to None.
22EDP-MESH-004Model imports normals as NoneWarnManualThe model importer's normals are set to None, so meshes ship unlit-looking. Often a leftover from a thumbnail / props preset reused on production assets. Pick Import or Calculate.
23EDP-MESH-005Model imports clips with compression offWarnAutoThe model imports animation but Animation Compression is Off. Wastes disk and runtime memory. Pick Keyframe Reduction or Optimal to shrink clips.
24EDP-REF-001Prefab has missing scriptsErrorManualA prefab asset has at least one component slot whose script reference is null (the script was deleted or its GUID changed). Remove or replace the slots to restore the prefab.
25EDP-REF-002Scene has missing scriptsErrorManualA scene asset contains GameObjects whose component slot points at a script that no longer resolves. Open the scene and remove or replace the slots.
26EDP-REF-003Prefab has broken material referenceErrorManualA Renderer component on a prefab carries a material slot whose reference is missing (the material asset was deleted while the prefab kept the fileID). Repoint or clear the slot.
27EDP-REF-004Prefab has broken sprite referenceErrorManualA SpriteRenderer or UI Image component carries a sprite slot whose reference is missing (the sprite asset was deleted while the prefab kept the fileID). Repoint or clear the slot.
28EDP-REF-005Prefab has broken mesh referenceErrorManualA MeshFilter or SkinnedMeshRenderer carries a mesh slot whose reference is missing. Repoint or clear the slot so the prefab renders.
29EDP-REF-006Prefab has broken audio referenceErrorManualAn AudioSource on a prefab carries a clip slot whose reference is missing. Repoint or clear the slot to silence the warning at runtime.
30EDP-REF-007Prefab has dangling object referencesWarnAutoA custom MonoBehaviour field on the prefab points at a deleted asset (the fileID still serializes a non-zero instance id). Clearing the slot is safe and removes the warning.
31EDP-REF-008Prefab has broken animator referenceErrorManualAn Animator component carries a controller slot whose reference is missing. The Animator does nothing at runtime; repoint or clear the slot.
32EDP-REF-009Scene or prefab has broken serialized referencesWarnManualA scene or prefab serializes object references whose asset GUID no longer resolves. Repoint the fields or clear them in the inspector.
33EDP-SETTINGS-001ProjectSettings has broken asset referencesErrorManualA ProjectSettings asset serializes a GUID that no longer resolves, commonly a deleted URP/HDRP pipeline asset, renderer, profile or build setting.
34EDP-SO-001ScriptableObject has missing scriptErrorManualThe ScriptableObject's m_Script reference is null (type renamed, deleted or moved without a FormerlySerializedAs migration). The asset deserialises to null at runtime.
35EDP-SO-002ScriptableObject has broken referencesErrorManualA ScriptableObject field points at a deleted asset. Repoint or strip the field manually; auto-clearing might silently neutralise behaviour that depends on it.
36EDP-SO-003ScriptableObject has no referencesInfoManualNo other asset in the project references this ScriptableObject through AssetDatabase. It may still be loaded by name from Resources/ or Addressables; confirm or remove.
37EDP-SO-004Resources/ ScriptableObject is never loadedInfoManualThe asset lives under Resources/ but no script in the project mentions its load name. Strong heuristic for 'ships in the build but never used'. Move out of Resources/ or remove.
38EDP-SO-005ScriptableObject reference cycleWarnManualTwo or more ScriptableObjects reference each other, directly or transitively. Often safe at runtime but resists clean import / version-control diffs. Break the cycle on whichever side makes sense.
39EDP-TEX-001Normal map imported as sRGBErrorAutoThe asset's name (_n / _normal / etc.) strongly suggests a normal map but its importer type is not NormalMap. The texture is sampled as sRGB, producing wrong lighting at runtime.
40EDP-TEX-002UI / Sprite texture has mipmapsWarnAutoA texture imported as Sprite (or living under a UI / Sprites folder) has mipmaps enabled. UI is screen-space; mipmaps waste ~33% of texture memory for no visual gain.
41EDP-TEX-003Texture maxSize above 2048 for smaller sourceWarnAutoThe importer's maxTextureSize is above 2048 even though the source image is smaller. Wastes import / build time without adding any detail. Clamp to a tighter cap.
42EDP-TEX-004Texture ships uncompressedWarnManualA non-tiny texture (256px or larger) ships with compression set to Uncompressed. Rarely intentional and inflates build size dramatically. Pick a compressed format unless lossless quality is required.
43EDP-TEX-005Texture has Read/Write enabledWarnAutoThe texture importer keeps a CPU-side copy, doubling memory. Auto-fix clears Read/Write on the importer; suppress per-asset when the texture is sampled from C# (GetPixels, custom CPU shaders).
44EDP-TEX-006Non-power-of-two texture (no scale)InfoManualA non-Sprite texture has non-POT dimensions and NPOT Scale is set to None. Compressed formats often fall back to RGBA32 in that combination, blowing up texture memory.
45EDP-TEX-007NormalMap type without normal-map nameInfoManualThe importer's texture type is NormalMap but the filename has no normal-map markers. Often a leftover from a copy-pasted preset; confirm the type is correct.
46EDP-TEX-008Sprite alpha but transparency offWarnAutoThe texture is imported as Sprite, the source has an alpha channel, but Alpha Is Transparency is off. Edges show dark bleed in atlases / UI.

Prefab Drift (9)

Prefab instances vs. their source assets: redundant overrides, added or removed components and GameObjects, deep variant chains, sibling instances that have drifted apart. Findings group automatically into drift clusters - every instance of the same source prefab is shown together so you can reconcile in bulk via Apply to source or Revert all in cluster. Every drift action is recorded in Action History and reverts as a single batch.

#Rule IDTitleSeverityAuto-fixDescription
1EDP-DRIFT-001Prefab instance has override sprawlWarnManualAn instance carries more property overrides than the configured threshold. Signals that values are being authored per-instance instead of on the asset. Apply or revert in bulk to keep instances aligned.
2EDP-DRIFT-002Redundant property overrideInfoAutoA property modification on the instance carries the same value as the source's current value. The override exists for no reason and can be reverted safely.
3EDP-DRIFT-003Added component on prefab instanceWarnAutoA prefab instance carries a component that does not exist on its source. Structural drift; decide whether to apply the component to the asset, keep it on the instance only, or revert.
4EDP-DRIFT-004Removed component on prefab instanceErrorManualA prefab instance is missing a component that exists on its source. Often someone deleted a required component on one instance only. Decide whether to re-add it or apply the removal to the source.
5EDP-DRIFT-005Added GameObject on prefab instanceWarnAutoA prefab instance has a child GameObject that does not exist on its source. Structural drift; revert the extra child or apply it back to the asset.
6EDP-DRIFT-006Removed GameObject on prefab instanceErrorManualA prefab instance is missing one or more child GameObjects that exist on its source. The removal usually breaks references the source prefab still ships. Re-add it or apply the removal to the source.
7EDP-DRIFT-007Variant chain too deepWarnManualA prefab variant chain is longer than the maintainable threshold (3 levels). Long chains force every change to cascade through every intermediate variant. Flatten an intermediate level.
8EDP-DRIFT-008Variant has missing parent prefabErrorManualA prefab variant declares a parent that no longer exists in the project. The instance still loads but future edits behave unpredictably. Restore the parent asset or unpack the variant.
9EDP-DRIFT-009Sibling instances drift apartInfoManualTwo or more instances of the same source prefab carry different override sets. Suggests the prefab is being authored ad-hoc per instance instead of on the asset; reconcile via Bulk Apply on a canonical instance.

Build Review (6)

EditorBuildSettings consistency plus shipped-payload hygiene: orphan scene paths, missing-on-disk entries, duplicates, scenes referenced but disabled, paths that escape the project, and demo packages that ship a stray Resources/ folder. All auto-fixes operate on a whole-array snapshot of EditorBuildSettings.scenes (or the renamed folder, for BUILD-006), so reverting from Action History restores the exact state before the fix - even when a single fix removes multiple entries. The Apply All Auto Fixes button at the top of the Build Review tab batch-fixes every auto-tier finding in one operation and reverts as a single Action History entry.

#Rule IDTitleSeverityAuto-fixDescription
1EDP-BUILD-001Build settings entry orphan pathErrorAutoAn EditorBuildSettings.scenes entry has a path that does not resolve to a .unity asset on disk, even though the GUID still resolves elsewhere. Auto-fix removes the orphan entry.
2EDP-BUILD-002Build settings entry missing on diskErrorAutoAn EditorBuildSettings.scenes entry refers to a deleted asset (its GUID resolves to nothing). The build still ships the dead entry. Auto-fix removes it.
3EDP-BUILD-003Duplicate scene in build settingsWarnAutoThe same scene path is listed twice in EditorBuildSettings.scenes. Auto-fix dedupes by keeping the first occurrence.
4EDP-BUILD-004Scene disabled in build but referencedWarnManualA scene is disabled in EditorBuildSettings yet a ScriptableObject under Resources/ still holds a SceneAsset reference to it. The runtime load will fail. Enable the scene or drop the reference.
5EDP-BUILD-005Scene path traverses outside projectErrorAutoAn EditorBuildSettings.scenes entry contains '..', is absolute, or otherwise escapes the project's canonical layout. Auto-fix normalises to a project-relative path or removes the entry.
6EDP-BUILD-006Resources folder under demo contentWarnAutoA Resources/ folder sits inside a Demo or Demos tree. Unity bundles every Resources/ folder into the player regardless of Build Settings, so the demo assets ship with every production build. Auto-fix renames the folder to DemoResources/ (GUID-preserving); rename back in the editor when you need to run the vendor demo.

Conventions (3)

Project-wide structural rules. Beyond the three native checks listed below, the Conventions module exposes user-defined rules: see Custom Rules to author predicates (Asset Path / Asset Type / Prefix / HasComponent / Not) paired with recipes (Flag / MoveAsset / Rename / Ignore) for project-specific contracts. Tag-related rules are configured under Settings > Conventions > Tag Contracts.

#Rule IDTitleSeverityAuto-fixDescription
1EDP-LINT-STRAYStray asset outside dominant folderWarnManualAn asset of a given type lives outside the folder where most of its peers live within the same content root and editor/runtime context (learned per package, not hardcoded). Move it to the dominant folder if the placement is unintentional.
2EDP-LINT-TAG-CLOSEDTag declared but unusedInfoManualA tag declared in the user-defined tag contract is not used by any GameObject in the scoped prefabs or scenes. Prune the entry or re-tag the relevant objects.
3EDP-LINT-TAG-CONTRACTTag missing required componentWarnManualA GameObject inside a prefab carries a tag whose contract requires specific components, but at least one is missing. Add the component (or relax / strict-flag the entry).

Code Audit (56)

IL-level analysis of every assembly the project compiles. Performance pitfalls inside per-frame messages, lifecycle correctness, async hygiene, naming conventions, Unity-API anti-patterns. Code Audit walks every assembly with Mono.Cecil (Unity's com.unity.nuget.mono-cecil package, no fork). Every Code Audit rule ships as Manual tier because the fix requires author intent: replacing a string-typed API call, moving an Instantiate out of Update, or adding a CancellationToken to an async method always depends on how the call is used. Most checks are Info / Warn by default; enable the convention rules under Settings > Rules to enforce a house style.

#Rule IDTitleSeverityAuto-fixDescription
1EDP-CODE-LIFECYCLE-ALLOCATE-IN-UPDATETexture2D / Mesh / Material constructed every frameErrorNoneA per-frame message body constructs a new Texture2D, Mesh, Material, RenderTexture, Sprite or Cubemap. These wrap unmanaged memory that GC cannot release on its own; leaving the constructor inside Update leaks memory every frame. Move it to Awake or pair it with a Destroy call.
2EDP-CODE-PERF-ANIMATOR-STRING-PARAMAnimator.Set*/Get* with string parameter nameInfoNoneAnimator.SetFloat / SetInteger / SetBool / SetTrigger (and Get / Reset) hash the string parameter every call. Cache the hash with Animator.StringToHash("Name") in a static readonly int and pass the int overload to bypass the hash on every call.
3EDP-CODE-ASMDEF-DUPLICATE-NAMEDuplicate asmdef nameErrorNoneTwo or more AssemblyDefinition files declare the same 'name' field. Unity rejects all but one and silently demotes the rest to Assembly-CSharp; the obvious symptom is that runtime references to the demoted asmdef stop resolving. Rename one of the duplicates.
4EDP-CODE-ASMDEF-EDITOR-RT-LEAKRuntime asmdef references editor-only asmdefCriticalNoneAn AssemblyDefinition that ships in the player references an editor-only AssemblyDefinition (includePlatforms set to ['Editor']). The build will fail; the error only surfaces when the user actually triggers a player build, sometimes days after the reference was added. Move the consumed types into a runtime asmdef, add a runtime-side stub, or drop the reference.
5EDP-CODE-ASMDEF-EMPTYEmpty asmdef (no scripts)WarnNoneAn AssemblyDefinition file owns a folder tree with no C# scripts. Empty assemblies still ship in the build, slow the compile graph, and usually mean an incomplete refactor (scripts moved away, asmdef left behind). Either populate the assembly or delete the asmdef.
6EDP-CODE-ASMDEF-MISSING-FOLDERScripts not under any asmdefInfoNoneA folder contains C# scripts but no AssemblyDefinition (.asmdef) file owns them. Scripts in this state are compiled into the global Assembly-CSharp catch-all, which slows incremental compile and lets every other script reference them implicitly. Author an asmdef in this folder (or an ancestor) to scope the assembly.
7EDP-CODE-ASMDEF-NAME-MISMATCHAsmdef name does not match file nameWarnNoneAn AssemblyDefinition file's 'name' field disagrees with its file name on disk. Unity uses the JSON name for assembly identity, so a rename on one side without the other silently breaks every reference. Decide which side is canonical and align the other.
8EDP-CODE-ASYNC-VOIDasync void methodWarnNoneAn async void method has no awaitable handle and its exceptions are unobservable - in modern .NET an unhandled async-void exception kills the process. Switch to async Task and await it from the caller, or wrap the body in a try/catch that logs via Debug.LogException.
9EDP-CODE-API-BARE-EXCEPTIONThrowing the bare Exception base typeInfoNonethrow new Exception(...) (or ApplicationException) forces every callsite into catch (Exception). Use a specific exception subtype (ArgumentException, InvalidOperationException, a domain-specific subclass) so callers can opt into the failure they care about.
10EDP-CODE-PERF-BOXING-IN-UPDATEValue-type boxing inside per-frame messageWarnNonePer-frame method body contains a box IL instruction. Boxing wraps a value type in a heap object - one allocation per call, every frame. Common triggers: string.Format with int args, List<object>.Add(struct), non-generic Equals. Use generic overloads or EqualityComparer<T> to avoid the box.
11EDP-CODE-PERF-CAMERA-ALLCAMERAS-IN-UPDATECamera.allCameras inside per-frameInfoNoneCamera.allCameras / .allCamerasCount allocate a fresh Camera[] every read. Inside per-frame messages this becomes a hot allocation. Cache on Awake, maintain a manual list via Camera.onPreCull, or switch to the allocation-free Camera.GetAllCameras(buffer) overload (not flagged by this rule).
12EDP-CODE-LIFECYCLE-CAMERA-MAIN-IN-UPDATECamera.main accessed every frameWarnNoneCamera.main is implemented as FindWithTag("MainCamera") on every access; calling it inside Update / FixedUpdate / LateUpdate scans the active scene every frame. Cache the Camera reference in Awake or expose a serialized field instead.
13EDP-CODE-CONV-NAMING-CLASSType not in PascalCaseInfoNoneClass / struct / enum name does not start with an uppercase letter. .NET / C# convention is PascalCase for every type. Disabled by default.
14EDP-CODE-CONV-NAMING-CONSTconst field not in PascalCaseInfoNoneConst field name does not start with an uppercase letter. The .NET Framework design guidelines specify PascalCase for constants; SCREAMING_SNAKE_CASE is a Java / C++ holdover that breaks C# reading rhythm. Disabled by default.
15EDP-CODE-API-DEBUG-LOG-IN-PLAYERDebug.Log* in runtime-shipping codeInfoNoneDebug.Log / LogWarning / LogError / LogFormat called from runtime-shipping code. Each call allocates a string and pays the platform-log cost in a player build. Wrap with [Conditional("UNITY_EDITOR")] or strip via a Player Settings define for release builds.
16EDP-CODE-PERF-DEBUG-LOG-IN-UPDATEDebug.Log* inside per-frame messageWarnNoneDebug.Log inside Update / FixedUpdate / LateUpdate allocates the formatted string and pays the console cost every frame. Forgotten log lines in hot paths are a common framerate-regression source. Gate via [Conditional] or a verbosity flag.
17EDP-CODE-API-DESTROY-IMMEDIATE-AT-RUNTIMEDestroyImmediate from runtime codeWarnNoneObject.DestroyImmediate skips Unity's deferred destruction queue, breaks coroutines that reference the object, and is intended for editor tooling only. From a runtime-shipping assembly use Destroy instead.
18EDP-CODE-API-EMPTY-CATCHEmpty catch blockInfoNoneA catch block has an effectively empty body (no log, no rethrow, no recovery). Swallowed exceptions hide real bugs and make field debugging nearly impossible. At minimum, log the exception or rethrow.
19EDP-CODE-CONV-EMPTY-NAMESPACEType in global namespaceInfoNoneType lives in the global namespace. Global types clash with anything an external package brings in under the same name and pollute IDE auto-import. Wrap in a namespace named after the product / company / module.
20EDP-CODE-LIFECYCLE-EMPTY-UPDATEEmpty Update / FixedUpdate / LateUpdateWarnNoneA MonoBehaviour declares Update / FixedUpdate / LateUpdate with an empty body. Unity still pays the per-frame, per-instance dispatch cost even when the body does nothing; populated scenes lose 5-15% framerate to the flat floor. Delete the method.
21EDP-CODE-LIFECYCLE-EVENT-NOT-UNSUBSCRIBEDEvent subscribed without matching unsubscribeErrorNoneAn event is subscribed in OnEnable / Awake / Start but never removed in OnDisable / OnDestroy. The publisher keeps the subscriber alive, leaking the GameObject and firing the handler on destroyed instances. Pair every += with a -= in the matching disposal message.
22EDP-CODE-LIFECYCLE-FIND-IN-STARTUPFind* / FindObject* called in Awake / StartWarnNoneFind / FindWithTag / FindObjectOfType / FindAnyObjectByType (and the rest of the Find* family) scan the full active hierarchy. Calling them inside Awake / Start / OnEnable adds tens to hundreds of milliseconds to scene load on populated scenes. Wire a serialized field in the Inspector so the reference resolves at import time.
23EDP-CODE-LIFECYCLE-FINDOBJECT-IN-UPDATEFindObjectOfType / FindObjectsByType called every frameErrorNoneFindObjectOfType / FindAnyObjectByType / FindObjectsByType (and their pre-6.0 cousins) scan every loaded GameObject. Calling them inside Update / FixedUpdate / LateUpdate turns a 60fps scene into a slideshow as the Hierarchy grows. Cache the reference in Awake or expose a serialized field.
24EDP-CODE-API-FINDOBJECTS-INCLUDE-INACTIVEFindObjects opts into includeInactiveWarnNoneFindObjectsOfType / FindObjectsByType / FindAnyObjectByType called via the (bool includeInactive) overload. Scanning inactive objects is markedly slower than the default. If the call really needs inactive objects, suppress the rule for that site; otherwise drop the bool argument.
25EDP-CODE-ASYNC-FIRE-AND-FORGETasync method called without awaitWarnNoneA Task-returning method is called and its result discarded. Exceptions land in the unobserved-task queue and surface on the finalizer thread, making field reports impossible to triage. Await the call, or route it through a fire-and-forget helper that logs Task.Exception in a continuation.
26EDP-CODE-LIFECYCLE-GETCOMPONENT-IN-UPDATEGetComponent called every frameWarnNoneGetComponent / GetComponentInParent / GetComponentInChildren (and the plural GetComponents variants) walk the GameObject's component list on every call. Per-frame use shows up as a flat profiler hot spot. Cache the reference in Awake or expose a serialized field.
27EDP-CODE-PERF-INSTANTIATE-IN-UPDATEInstantiate inside UpdateErrorNoneObject.Instantiate inside per-frame messages clones the full prefab hierarchy, runs every Awake/Start, reparents transforms and rebakes physics every frame. Replace with an object pool warmed on Start and toggle pooled instances via SetActive.
28EDP-CODE-CONV-NAMING-INTERFACEInterface name doesn't start with IInfoNoneInterface name does not start with the letter I. .NET / C# convention reserves the leading I prefix for interfaces so callers can distinguish 'depends on a contract' from 'depends on a type' at a glance. Disabled by default.
29EDP-CODE-API-INVOKE-STRINGInvoke / StartCoroutine by string nameWarnNoneInvoke / InvokeRepeating / StartCoroutine called with a string method name. The IDE will not catch the dangling literal on rename; the call is also slower because Unity has to look the method up reflectively. Switch to the typed overload (method group or lambda).
30EDP-CODE-PERF-LINQ-IN-UPDATELINQ inside Update / FixedUpdate / LateUpdateWarnNoneEvery LINQ chain allocates an enumerator and most terminal operators (.ToList, .ToArray, .Count, .First) walk the source eagerly. Per-frame use is a stable GC contributor that the profiler attributes to opaque allocations. Replace the chain with manual loops or precompute the result outside the per-frame messages.
31EDP-CODE-CONV-LONG-METHODMethod body over ~400 IL instructionsInfoNoneMethod body exceeds the convention's instruction threshold (~400 IL ops, roughly 100-200 source lines). Long methods are a known maintenance smell. Split into smaller helpers, extract guard clauses, or move logic into a dedicated type. Disabled by default.
32EDP-CODE-PERF-MATERIAL-INSTANCERenderer.material instantiatesInfoNoneReading Renderer.material (or .materials) instantiates a per-renderer copy of the shared material on first access, allocates GC, and breaks SRP batching. Use sharedMaterial when reading; reach for material only when the per-instance copy is the goal.
33EDP-CODE-CONV-MULTIPLE-TYPES-PER-FILEMultiple top-level types in one fileInfoNoneSource file declares two or more top-level types. The one-type-per-file convention makes navigation predictable, aligns with IDE refactor heuristics, and scopes merge conflicts. Disabled by default.
34EDP-CODE-PERF-NEW-ARRAY-IN-UPDATENew array allocated every frameWarnNonePer-frame message body contains a newarr IL instruction. Each call allocates the array header plus the element buffer. Reuse a field-stored array (and clear if needed), or rent from ArrayPool<T>.Shared for variable-length scratch space.
35EDP-CODE-PERF-NEW-COLLECTION-IN-UPDATENew collection allocated every frameWarnNonePer-frame message constructs a new List / Dictionary / HashSet / Queue. Each constructor allocates the object and a backing array. Reuse a field-stored instance with Clear, or construct it outside Update.
36EDP-CODE-ASYNC-NEW-THREADManual System.Threading.Thread creationWarnNoneCreating raw threads with new Thread(...) bypasses the .NET thread pool, breaks under WebGL (which disallows them), and integrates poorly with async/await. Use Task.Run for one-shot background work, Unity's Job system for parallel compute, or UniTask.RunOnThreadPool when shipping with UniTask.
37EDP-CODE-ASYNC-NO-CANCELLATION-TOKENAsync API without CancellationTokenInfoNoneTask.Run / Task.Delay called without a CancellationToken cannot be cancelled when the scene unloads, the app quits, or the user moves on. The task runs to its natural end and may call into destroyed Unity objects. Pass a CancellationToken sourced from a CancellationTokenSource you cancel in OnDestroy.
38EDP-CODE-API-OBSOLETEObsolete API callWarnNoneProject code calls a method, type or property marked [Obsolete]. Migrate to the recommended replacement before the deprecated symbol is removed in a future Unity / .NET version.
39EDP-CODE-API-PARSE-NO-FORMAT-PROVIDERNumeric Parse / TryParse without IFormatProviderInfoNoneint / float / double / decimal Parse (or TryParse) called without an IFormatProvider uses the current culture; the same code parses '1,5' as 15 in German or fails on '1,500' in English. Pass CultureInfo.InvariantCulture for stored data, a specific culture for user input.
40EDP-CODE-PERF-PHYSICS-CAST-NO-LAYERMASKPhysics cast without LayerMaskInfoNonePhysics.Raycast / OverlapSphere / SphereCast called without a LayerMask uses the default ~0 mask, forcing the broad-phase to test every collider in the scene. Pass a layer mask keyed to the expected hit set.
41EDP-CODE-CONV-NAMING-PRIVATE-FIELDPrivate field doesn't start with underscoreInfoNonePrivate instance field name does not start with an underscore. The Unity / Microsoft / .NET Foundation convention is _camelCase for privates and PascalCase for publics. Disabled by default; enable in Settings to enforce.
42EDP-CODE-CONV-NAMING-PRIVATE-STATICPrivate static field namingInfoNonePrivate static field name should start with s_ or _ to make 'this is process-wide state' visible at the call site. Convention used by Roslyn / Microsoft style guides. Disabled by default.
43EDP-CODE-CONV-PUBLIC-FIELD-IN-MONOBEHAVIOURPublic field in MonoBehaviourInfoNoneA MonoBehaviour exposes a public field. Convention is [SerializeField] private + a method or event for state changes so external scripts can't mutate it without notification. Disabled by default; enable in Settings if your team's convention forbids public fields.
44EDP-CODE-CONV-NAMING-PUBLIC-METHODPublic method not in PascalCaseInfoNonePublic method name does not start with an uppercase letter. .NET / C# convention reserves camelCase for parameters and locals; public API surface is always PascalCase. Disabled by default.
45EDP-CODE-API-RESOURCES-LOADResources.Load / LoadAll callInfoNoneResources.Load forces every asset under any Resources/ folder into the build payload and bypasses Addressables / AssetBundles. For larger projects migrate to Addressables; small projects can keep Resources/.
46EDP-CODE-API-SCENE-LOAD-STRINGSceneManager.LoadScene literal not in buildWarnNoneA SceneManager.LoadScene or LoadSceneAsync string literal does not match an enabled Build Settings scene or Addressable scene address.
47EDP-CODE-LIFECYCLE-STARTCOROUTINE-IN-UPDATEStartCoroutine called every frameWarnNoneStartCoroutine inside Update / FixedUpdate / LateUpdate allocates a new Coroutine + IEnumerator state machine on every call and stacks parallel coroutines on top of each other. Move the StartCoroutine to Start (a long-lived loop) or replace it with a regular timer pattern that doesn't allocate.
48EDP-CODE-API-STRING-COMPARE-CULTUREString comparison without StringComparisonInfoNoneString.Compare / Equals / StartsWith / EndsWith called without a StringComparison argument uses the current culture, behaving differently in Turkish and other non-invariant locales. Pass StringComparison.Ordinal (or InvariantCulture / OrdinalIgnoreCase, etc.) to make the comparison deterministic.
49EDP-CODE-PERF-STRING-FORMAT-IN-UPDATEstring.Format / Concat / Join inside per-frameInfoNonestring.Format / Concat / Join inside Update / FixedUpdate / LateUpdate allocates the result every frame and (for Format with value-type args) boxes the args into the params array. Cache the string and rebuild only when source data changes.
50EDP-CODE-ASYNC-RESULT-WAITTask.Result / Task.Wait / GetAwaiter().GetResult()ErrorNoneSynchronously blocking on a Task (Result, Wait, GetAwaiter().GetResult()) deadlocks the Unity main thread when the task tries to continue on the same SynchronizationContext. Use await instead - if the call site can't be async, restructure the code path so the blocking call lives on a dedicated thread.
51EDP-CODE-PERF-TRANSFORM-FIND-IN-UPDATETransform.Find inside per-frameWarnNoneTransform.Find walks the transform's children comparing names every call. Inside Update / FixedUpdate / LateUpdate the cost scales with sibling count and is invisible until the hierarchy grows. Cache the resolved Transform in a field on Awake.
52EDP-CODE-PERF-OBJECT-NULL-CHECK-IN-UPDATEUnityEngine.Object null check inside per-frameInfoNoneThe == / != operator on UnityEngine.Object is overloaded so it crosses into native code to check whether the underlying object was destroyed. Per-frame null checks accumulate that cost. Cache the result in a local, or use ReferenceEquals when the destroyed-state check isn't needed.
53EDP-CODE-PERF-VECTOR-MAGNITUDEVector magnitude (sqrt) readInfoNoneVector2 / Vector3 / Vector4 .magnitude does a square root every call. When the result is only compared against another length (or zero), switch to sqrMagnitude and square the threshold; the math identity holds and the sqrt drops out.
54EDP-CODE-PERF-WAITFOR-NOT-CACHEDWaitFor* allocated inlineInfoNoneCoroutines re-evaluate the yield expression on every iteration. Inline new WaitForSeconds(x) / new WaitForFixedUpdate() allocates a fresh object on the heap each tick. Cache the instance as a readonly field and yield the field; for variable durations, reuse a single WaitForSeconds and call its constructor only when the duration changes.
55EDP-CODE-API-SEND-MESSAGESendMessage / BroadcastMessage by string nameWarnNoneSendMessage / BroadcastMessage / SendMessageUpwards resolve the callee by string at runtime. Renames silently break the call and Unity walks the hierarchy reflectively on every dispatch. Replace with a direct method call, a UnityEvent, an Action delegate, or an interface.
56EDP-CODE-API-TAG-STRING-COMPAREComponent.tag compared with ==WarnNoneReading Component.tag allocates a fresh string every call; comparing it with == / != compounds the cost. Switch to CompareTag("Player") - allocation-free and the same result.
Was this page helpful?