Ask an AI for “a player movement script in Unity” and you’ll get something. It might use the old Input Manager, a Rigidbody API that Unity 6 renamed, or a package you don’t have. The fix isn’t a better AI. It’s a better prompt. This guide shows how to prompt AI to write Unity C# scripts that compile on the first try: what context to give, how to state constraints, how to use your own code as an example, and how to check the result before you paste it in. It works the same with ChatGPT, Claude, Copilot Chat or Cursor.
Why AI Unity Code Fails to Compile
Language models learned Unity from years of forum posts, tutorials and GitHub repos. Most of that code predates Unity 6. So when your prompt leaves things out, the model fills the gaps with the most common answer it has seen, which is often outdated:
- Input:
Input.GetAxis("Horizontal")from the old Input Manager, which throws an exception if your project only uses the Input System package. - Physics names:
rb.velocityandrb.drag, which Unity 6 renamed tolinearVelocityandlinearDamping. - Find methods:
FindObjectOfType, deprecated in favour ofFindFirstObjectByTypeandFindAnyObjectByType. - Packages: Cinemachine 2 class names when you have Cinemachine 3, or Built-in pipeline shader code when you use URP.
- Your own code: it calls
player.Health.Damage()because that sounds plausible, when your method isTakeDamage(float).
None of this is the AI being bad at C#. It’s missing information. Every item above is fixed by telling it.
The Context Block: Version and Packages
Write a short context block once and paste it at the top of every Unity coding conversation. Many tools let you save it as custom instructions or a project rules file, which is even better.
Context for all Unity code in this chat:
- Unity 6 (6000.0 LTS), URP 17, C# 9.
- Input System package 1.x ONLY. Active Input Handling = Input System.
Do not use UnityEngine.Input.
- Rigidbody uses Unity 6 names: linearVelocity, linearDamping, angularDamping.
- Use FindFirstObjectByType / FindAnyObjectByType, never FindObjectOfType.
- Installed packages: Cinemachine 3 (namespace Unity.Cinemachine),
TextMeshPro (namespace TMPro), Unity Test Framework.
- Not installed: DOTween, Odin, Addressables. Don't use them.
- Style: [SerializeField] private fields, cache GetComponent in Awake,
no allocations in Update.
- If you're not sure an API exists in Unity 6, say so instead of guessing.
Get the exact package list from Window > Package Manager (In Project) or from Packages/manifest.json. The “not installed” line matters as much as the installed one. Without it, models happily reach for DOTween because it shows up in so many tutorials.
The last line is the most underrated. Giving the model explicit permission to say “I’m not sure” reduces invented methods noticeably.
State Constraints, Not Just Goals
“Make the player move” is a goal. A useful prompt adds the constraints that pin down one correct answer:
- Where it lives: which GameObject, which components already exist (Rigidbody? CharacterController? Animator?).
- How input arrives: an
InputActionReference, aPlayerInputcomponent with Send Messages, or a generated C# class. - Which loop: physics in
FixedUpdate, input reading inUpdate. - Inputs and outputs: “exposes a public event when health hits zero”, “takes damage as a float”.
- What not to do: no singletons, no coroutines, no external packages.
- Scope: one script, under about 80 lines, no editor code.
Small scope matters. A model asked for “a complete inventory system” writes six files, and the chance that all six compile and fit your project is low. Ask for the data class first, then the UI, then the save logic, checking each one.
A Full Prompt and Its Output
Here’s a real prompt, after the context block above:
Write one MonoBehaviour called PlayerMover for a 3D top-down game. The GameObject has a Rigidbody (gravity on, rotation frozen on X and Z). Movement input comes from an InputActionReference field for a Vector2 “Move” action. Read input in Update, apply it in FixedUpdate by setting the Rigidbody’s horizontal velocity directly and keeping the current vertical velocity. Expose moveSpeed in the Inspector. Enable and disable the action in OnEnable/OnDisable. No other components, no packages beyond the Input System.
And the kind of answer that prompt produces:
using UnityEngine;
using UnityEngine.InputSystem;
[RequireComponent(typeof(Rigidbody))]
public class PlayerMover : MonoBehaviour
{
[SerializeField] InputActionReference moveAction;
[SerializeField] float moveSpeed = 6f;
Rigidbody rb;
Vector2 moveInput;
void Awake()
{
rb = GetComponent<Rigidbody>();
}
void OnEnable() => moveAction.action.Enable();
void OnDisable() => moveAction.action.Disable();
void Update()
{
moveInput = moveAction.action.ReadValue<Vector2>();
}
void FixedUpdate()
{
Vector3 horizontal = new Vector3(moveInput.x, 0f, moveInput.y) * moveSpeed;
rb.linearVelocity = new Vector3(horizontal.x, rb.linearVelocity.y, horizontal.z);
}
}
Every decision in that script was made in the prompt: the Input System, the Unity 6 property name, the update loops, the Inspector field. The model had nothing left to guess. If you’re new to action references, our Input System beginner’s guide shows how to create the Move action and drag it into that field.
Show It Your Own Code
When the new script has to work with existing code, paste the parts it touches. Not the whole project: just the public surface. For example:
Here is my existing Health class. Write a HealthPickup that heals the player on trigger enter and returns itself to the pool I already have. Match my style: [SerializeField] private fields, no public fields.
public class Health : MonoBehaviour
{
public event System.Action<float, float> Changed; // current, max
public float Current { get; private set; }
public void Heal(float amount) { /* ... */ }
public void TakeDamage(float amount) { /* ... */ }
}
You can strip method bodies to save space. The model needs names, signatures and types, not implementation. One existing script also works as a style example: “write it like this one” gets you matching naming and structure without a long list of rules.
If you’re using an agent that can read the project (Claude Code, Cursor and similar), point it at the files instead of pasting. Our Claude Code Unity setup guide shows how to put the context block into a CLAUDE.md so it applies to every session automatically.
📚 AI writes faster when you can read faster
The better you know C# and game architecture, the faster you spot an AI’s wrong turn. Our book list covers the programming and design fundamentals worth having on your shelf.
Verify Before You Paste
Read the code before it touches your project. A two-minute check catches most problems:
- Usings. Does every
usingmatch a package you have?using DG.Tweening;when you don’t have DOTween is an instant CS0246. - Unity APIs. Any method you don’t recognise, search the Unity Scripting API docs or hover it in your IDE. Invented methods usually have very convenient names.
- Your APIs. Does it call your classes with the right names and signatures?
- Class name = file name. For MonoBehaviours, Unity needs them to match or you can’t add the component.
- Loop placement. Physics in
FixedUpdate, input reading inUpdate, noGetComponentorFindcalls every frame. - Null safety. Which serialized fields must be assigned in the Inspector? You’ll get a NullReferenceException on Play if you forget.
Then paste it, let Unity compile, and check the Console. An IDE with working IntelliSense underlines bad APIs before Unity even compiles, which makes this loop much faster.
Iterate With Errors, Not Complaints
“It doesn’t work” gives the model nothing. Paste the exact compiler error with its line:
This gives: Assets/Scripts/PlayerMover.cs(27,12): error CS1061: ‘Rigidbody’ does not contain a definition for ‘SetVelocity’. Don’t guess another method name. Use only members that exist on UnityEngine.Rigidbody in Unity 6, and tell me which one you’re using.
The error code tells the model what kind of mistake it made, and the line number tells it where. Our compiler errors guide explains what CS0246, CS0103 and CS1061 mean if you want to fix simple ones yourself.
Two habits that help:
- Fix one error at a time when there are several. The first error often causes the rest.
- Start a fresh conversation after a long back-and-forth. Long chats drift, and old wrong versions of the code keep influencing new answers. Paste the context block, the current code and the one remaining problem.
Troubleshooting
InvalidOperationException: You are trying to read Input using the UnityEngine.Input class, but you have switched active Input handling to Input System package in Player Settings.
The AI used the old Input Manager. Add “Input System only, never UnityEngine.Input” to your context block and ask it to rewrite input with an InputActionReference or PlayerInput.
error CS0246: The type or namespace name ‘DG’ could not be found
The code uses DOTween, which you don’t have. Same pattern for any missing package. List installed and not-installed packages in the prompt.
warning CS0618: ‘Rigidbody.velocity’ is obsolete
Pre-Unity 6 naming. Replace with linearVelocity, and add Unity 6 physics names to your context block.
Can’t add script component because the script class cannot be found
The class name doesn’t match the file name, or the project has other compile errors. Fix all Console errors first, then check the names.
The code compiles but nothing happens
Usually the input action isn’t enabled, a serialized field is unassigned, or the logic sits in a method Unity never calls (a typo like Fixedupdate). Ask the AI to add one Debug.Log per step so you can see where it stops.
FAQ
Which AI is best for Unity C#?
The major assistants are all capable. The prompt matters far more than the tool. Version, packages and constraints decide whether the code compiles.
Should I tell the AI my Unity version every time?
Yes, or save it once as custom instructions or a project rules file. It’s the single biggest fix for outdated code.
How long should a prompt be?
A context block plus four to eight sentences for the task is usually right. Long enough to remove guesses, short enough to stay one task.
Can AI write a whole game system at once?
It can try, but big multi-file answers rarely fit your project. Build in small pieces and compile after each one.
Is it okay to ship AI-written code?
Yes, once you’ve read it, understand it and tested it. Treat it like code from a stranger on a forum: useful, but your responsibility.
Reader questions
Asked by readers of this article and answered by AI. Behavior can differ between Unity versions, so test in yours.




Leave a Reply