Using Cursor with Unity


Understanding Cursor's Unity capabilities
Cursor can greatly benefit Unity developers who want to increase their productivity by combining powerful AI assistance with a streamlined coding editor, but it's not a replacement for more tightly integrated IDEs like Rider or Visual Studio. Here's what makes it special:
Key Features
AI Coding Agent: Autonomous agent that can independently explore, plan, and execute complex codebase changes using a full suite of development tools
Contextual Codebase Understanding: Deep comprehension of your Unity project's structure, custom scripts, and package dependencies
Powerful Development Tools: Integrated tools for searching codebases, modifying files, web research, and applying custom rule logic
Smart Code Completion: Cursor can understand Unity's API and provides context-aware suggestions for MonoBehaviour methods, component properties, and common Unity patterns
Refactoring Tools: Automated code restructuring that conforms with Unity's architecture and lifecycle methods
Unity-Specific Advantages
Intelligent handling of Unity's serialization system (custom serialization using
ISerializationCallbackReceiver
and[SerializeField]
/[SerializeReference]
attributes)Understanding of Unity's lifecycle methods and execution order
Support for Unity's special folders and project structure
Insight and understanding of Unity centric design patterns via
@Web
search and indexing codebase.
Current Limitations
Zero debugging or breakpoint support with Unity, requires switching to Rider or Visual Studio
Zero support for creating content for Unity's visual scripting systems
Prefabs or asset modifications are not possible
Unity package manager operations require editor integration
AI-generated code may require tweaking or follow-up requests to get to where you want it
Performance Considerations
Cursor's AI features work best with smaller to medium-sized Unity projects
Large script files may impact indexing performance
Real-time code analysis may need adjustment for very large codebases
💡 Tip: Keep your Unity project structure clean and organized to maximize Cursor's effectiveness.
Setting up Cursor for Unity development
Setting up Cursor for Unity development requires some specific configuration to ensure optimal performance and relevant AI code assistance. There are advanced areas we might want to go into more depth on a later article, but to start we are mostly concerned with our project's configuration.
This is what I would recommend based on my experience with Cursor and Unity.
Project Configuration
My own projects always have the Unity project as a sub-folder of a git repository. Keep this in mind as your organization could be different.
graph TD
A[Repository Root Folder] --> B[Unity]
B --> C[Assets]
B --> D[Library]
Indexing
Cursor can index your codebase in order to provide better, more accurate responses, but this should be limited to only the files that the AI should consider.
We can create a .cursorignore
file to include or exclude files from being indexed by Cursor; the format used is the same as a .gitignore
. For Unity projects we only want to index C# (.cs
) files, so we should make a custom .cursorignore
to handle that.
In your git repository root folder, create a .cursorignore
with the following contents:
# ignore everything by default
*
# Un-ignore Unity directory and all its subdirectories
!Unity/
!Unity/**/
# Include all .cs files in Unity and its subdirectories
!Unity/**/*.cs
This ignore file helps to ignore otherwise banal or unhelpful text files like .meta
or .json
files that might get sucked up into the indexing process, but include all .cs
files that would be included in your Unity project's Assets and Library folder (includes all downloaded packages).
Workspace Setup
- Project Structure: To make Cursor AI more effective in where it creates files and what they're named, it can help to keep your scripts organized into relevant folders and keep naming consistent. This can reduce down the number of times that Cursor might create files in the wrong place or with a weird name.
Keep scripts organized in logical folders (e.g.,
Scripts/
,Scripts/Components/
,Scripts/Managers/
)Maintain consistent naming conventions for scripts and components
Use namespaces to organize code by feature or module
⚠️ Note: Cursor works best with Unity projects that follow a clean, modular architecture. Take time to organize your project structure before starting development.
- Performance Optimization:
Whenever we make a request to Cursor or really any LLM service, we provide it with two types of data called Context.
Input Context describes what we've asked the AI to do, provided by the Chat or Agent prompt.
State Context describes the state of the current world, which in this case is our project. This can include chunks of code or whole files, logs, screenshots we've attached, etc...
The more focused and relevant the provided context is for an AI request, the more likely the results will be helpful and have fewer hallucinations.
To help accomplish this:
Be specific in your request; the more latitude or unknowns the AI needs to guess at, the more likely you'll have hallucinations.
KISS isn't just for humans; keep script files focused and single-purpose and avoid circular dependencies between scripts
Use partial classes for large classes; this can help avoid bringing in too much irrelevant context.
When explicitly including snippets of code or files/folders, attach only what you want the focus to be on.
Include links to Unity's API documentation if necessary. This can be helpful where the API might have changed over the years if a specific version of it needs to be used over another.
Cursor itself will automatically pull in the parts of the codebase that it think are relevant based on a variety of circumstances, but it can be more helpful to use Cursor's hotkeys and commands to attach the specific areas of code you want to include.
Highlighting a snippet of code and using the hotkey
CMD + I
will insert it into the AI Panel.Files and even folders can be dragged manually into the AI Panel.
Unity-specific development workflows
Let's look at some practical examples of how Cursor can help with common Unity development tasks. These are pretty typical use-cases where using Cursor has really helped my productivity by largely automating tasks that might otherwise require a lot of rote typing or boilerplate code. The results I've gotten from Cursor in these cases largely haven't required a lot of tweaking
Documentation Generation
When working with a complex codebase, Cursor can help document your code.
Request:
Please document all public members and classes in the `Scripts/Combat` folder using XML documentation comments. Include parameter descriptions, return values, and any exceptions that might be thrown.
Cursor will then:
Scan the specified folder
Identify all public members and classes
Generate appropriate XML documentation
Maintain existing documentation if present
Example output:
/// <summary>
/// Handles the combat state and actions for a character entity.
/// </summary>
public class CombatController : MonoBehaviour
{
/// <summary>
/// The current health of the character.
/// </summary>
[SerializeField] private float currentHealth;
/// <summary>
/// Applies damage to the character and triggers appropriate effects.
/// </summary>
/// <param name="damage">The amount of damage to apply</param>
/// <param name="damageType">The type of damage being applied</param>
/// <returns>True if the character survived the damage, false if defeated</returns>
/// <exception cref="System.ArgumentOutOfRangeException">Thrown when damage is negative</exception>
public bool TakeDamage(float damage, DamageType damageType)
{
// Implementation
}
}
Extending Third-Party Plugins
Cursor can help extend existing plugins to work with other systems.
Request:
I'm using the DOTween plugin and want to add support for my custom Transform component. Please create an extension class that adds DOTween animation methods for my @CustomTransform component, similar to how DOTween extends Unity's Transform.
Cursor will then:
Analyze the DOTween API
Create appropriate extension methods
Maintain consistent naming and behavior
Example output:
public static class CustomTransformDOTweenExtension
{
public static Tweener DOMove(this CustomTransform target, Vector3 endValue, float duration)
{
return DOTween.To(
() => target.Position,
x => target.Position = x,
endValue,
duration
).SetTarget(target);
}
// Additional extension methods...
}
Debug Visualization
Cursor can help add debug visualization to existing components.
Request:
Please add debug drawing methods to my @PathfindingAgent component. Include visualization for the current path, waypoints.
Cursor will:
Add appropriate debug drawing methods
Handle both editor and runtime visualization
Include toggle options for different debug features
Use appropriate Unity debug drawing APIs
Example output:
[System.Serializable]
public class InventoryItem : ISerializationCallbackReceiver
{
[SerializeField] private string itemName;
[SerializeField] private ItemState currentState;
// Non-serialized runtime data
private Dictionary<ItemModifierType, float> modifiers;
// Serialization helpers
[SerializeField] private List<ItemModifierType> modifierKeys;
[SerializeField] private List<float> modifierValues;
public void OnBeforeSerialize()
{
// Convert dictionary to serializable lists
modifierKeys ??= new List<ItemModifierType>();
modifierKeys.Clear();
modifierValues ??= new List<float>();
modifierValues.Clear();
foreach (var kvp in modifiers)
{
modifierKeys.Add(kvp.Key);
modifierValues.Add(kvp.Value);
}
}
public void OnAfterDeserialize()
{
// Reconstruct dictionary from serialized lists
modifiers ??= new Dictionary<ItemModifierType, float>();
modifier.Clear();
for (int i = 0; i < modifierKeys.Count; i++)
{
if (i < modifierValues.Count)
{
modifiers[modifierKeys[i]] = modifierValues[i];
}
}
}
}
Custom Serialization
Cursor can help implement custom serialization for complex types.
Request:
Please implement `ISerializationCallbackReceiver` for my `InventoryItem` class to handle custom serialization of the item's properties. The class needs to serialize a `Dictionary` of item modifiers and a custom enum-based state system.
Cursor will:
Implement the serialization interface
Handle complex data structures
Maintain Unity's serialization system compatibility
Example output:
[System.Serializable]
public class InventoryItem : ISerializationCallbackReceiver
{
[SerializeField] private string itemName;
[SerializeField] private ItemState currentState;
// Non-serialized runtime data
private Dictionary<ItemModifierType, float> modifiers;
// Serialization helpers
[SerializeField] private List<ItemModifierType> modifierKeys;
[SerializeField] private List<float> modifierValues;
public void OnBeforeSerialize()
{
// Convert dictionary to serializable lists
modifierKeys ??= new List<ItemModifierType>();
modifierKeys.Clear();
modifierValues ??= new List<float>();
modifierValues.Clear();
foreach (var kvp in modifiers)
{
modifierKeys.Add(kvp.Key);
modifierValues.Add(kvp.Value);
}
}
public void OnAfterDeserialize()
{
// Reconstruct dictionary from serialized lists
modifiers ??= new Dictionary<ItemModifierType, float>();
modifier.Clear();
for (int i = 0; i < modifierKeys.Count; i++)
{
if (i < modifierValues.Count)
{
modifiers[modifierKeys[i]] = modifierValues[i];
}
}
}
}
💡 Tip: When making requests to Cursor, be specific about your requirements and include any relevant context. For example, mention if you need editor-only functionality, runtime behavior, or both.
Cursor Rules and Agentic workflows
While Cursor is powerful out of the box, its true potential is unlocked when you leverage its advanced features for custom workflows and automated development. There are two key areas that deserve their own deep-dive articles.
Cursor Rules
Cursor Rules are a powerful way to guide the AI's code generation and maintain consistency across your project. Think of them as a combination of:
Architectural guidelines
Development workflows
Code standards
Personal preferences
For example, you might create rules that:
Enforce specific Unity design patterns
Define naming conventions for components
Specify serialization requirements
Establish testing requirements
Here's a quick example of a rule I created for Unity development:
---
description: Apply Unity Inspector field guidelines when exposing fields to the Unity Editor
globs: Unity/**/*.cs
alwaysApply: false
---
# Unity Inspector Field Guidelines
## Context
- When creating fields that need to be modified in the Unity Inspector
- When organizing Inspector fields for better usability
- When setting up component references and configuration values
## Requirements
- Use private access modifier for Inspector fields
- Decorate fields with [SerializeField] attribute
- Group fields with [TitleGroup] attribute based on their category
- Use meaningful categories (UI, Scene Reference, Data, etc.)
## Examples
✅ Correct
~~~csharp
public class PlayerController : MonoBehaviour
{
[SerializeField]
[TitleGroup("Movement")]
private float _moveSpeed;
[SerializeField]
[TitleGroup("Scene References")]
private Transform _groundCheck;
[SerializeField]
[TitleGroup("UI")]
private TMP_Text _healthDisplay;
}
~~~
❌ Incorrect
~~~csharp
public class PlayerController : MonoBehaviour
{
public float moveSpeed; // No SerializeField, public field
[SerializeField] // No grouping
private Transform groundCheck;
}
~~~
## Critical Rules
- Always use [SerializeField] for Inspector-visible fields
- Always use [TitleGroup] to organize fields
- Keep fields private
- Use clear, categorical grouping
💡 Note: Cursor Rules are important enough to go into in a future article, including how to create effective rules (and generate them largely automatically), manage rule sets, and integrate them into your development workflow.
Agentic Workflows
One of the most powerful ways to use Cursor is through agentic workflows, where you take on the role of a product manager while the AI acts as your engineering team. This approach is particularly effective for larger features or refactoring tasks.
While there are a lot of different methods for achieving an agentic workflow, it typically follows these steps:
Task Breakdown
Define the overall feature or goal
Break it down into smaller, manageable units
Establish clear acceptance criteria
Planning Phase
Let the AI analyze the requirements
Review and refine the proposed implementation plan
Set up any necessary project structure
Implementation
The AI works autonomously on each unit
You review and provide feedback as needed
The AI handles the implementation details
Integration
The AI ensures all components work together
You verify the results
The AI makes any necessary adjustments
💡 Note: I’ll go through my agentic workflow setup in detail in a future article, including real-world examples, best practices, and tips for effective collaboration with the AI.
Subscribe to my newsletter
Read articles from Jeff Campbell directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by