The “var” Error in C# — Why “The contextual keyword ‘var’ may only appear within a local variable declaration” Happens
If you’re working with Unity or learning C#, sooner or later you’ll see this legendary error:
The contextual keyword ‘var’ may only appear within a local variable declaration
At first glance, it feels completely cryptic.
You typed var like everyone says you should… and the compiler just yelled at you.
In this article you’ll learn:
- What
varactually is in C# - Why it only works in local variable declarations
- The real difference between C# and old UnityScript / JavaScript-style syntax
- How to fix common patterns that trigger this error
- A clean, idiomatic C# version of the sprint/movement code
1. What var really means in C
In C#, var is a contextual keyword, not a magic dynamic type.
This works:
void Update()
{
var speed = 10.0f; // compiler infers: float
var name = "Player"; // compiler infers: string
var pos = transform.position; // compiler infers: UnityEngine.Vector3
}
Why? Because:
- You’re inside a method (
Update()) - You’re declaring a local variable
- The variable has an initializer, so the compiler can infer its type
The compiler rewrites it to:
float speed = 10.0f;
string name = "Player";
Vector3 pos = transform.position;
So far so good.
2. Where var is allowed (and where it isn’t)
✅ var is allowed in:
-
Local variable declarations inside methods, constructors, property getters/setters,
foreach, etc.
void Start()
{
var rb = GetComponent<Rigidbody>(); // local variable
}
void Update()
{
foreach (var enemy in enemies) // foreach variable
{
// ...
}
using var scope = myLock.EnterScope(); // C# 8+ using declaration
}
❌ var is NOT allowed in:
- Fields (class-level variables)
- Method parameters
- Return types
- Properties, events, indexers
- Any place where the type must be known outside the method body
Examples of illegal var usage:
public class PlayerController : MonoBehaviour
{
// ❌ Not allowed – this is a field
var speed = 10.0f;
// ❌ Not allowed – return type
public var CreateEnemy() { ... }
// ❌ Not allowed – parameter type
public void Move(var direction) { ... }
}
All of these will give you some version of:
The contextual keyword ‘var’ may only appear within a local variable declaration
Because the compiler only lets var live in local variable declarations, where the type is fully inferable from the initializer and stays inside the method scope.
3. The Unity trap: mixing UnityScript and C
Many old Unity forum posts and tutorials use UnityScript (a JavaScript-like language Unity used to support) or JScript-style syntax, such as:
#pragma strict
@script RequireComponent( CharacterController )
var moveTouchPad : Joystick;
var rotateTouchPad : Joystick;
This is not C#.
So if you try to “translate” that into C# and write something like:
var Sprint : MonoBehaviour {
var float NaturalSpeed = 10.0f;
var float tempSpeed = 0.0f;
var float SpeedMultiplier = 1.2f;
var Vector3 moveDirection;
var float FirstPersonControl;
...
}
You’ll get multiple errors, including our friend:
The contextual keyword ‘var’ may only appear within a local variable declaration
…because in C# you don’t write types after the variable name and you don’t use var in fields.
Correct C# field declarations
Here’s how these should actually look in C#:
public class Sprint : MonoBehaviour
{
public float naturalSpeed = 10.0f;
private float tempSpeed = 0.0f;
public float speedMultiplier = 1.2f;
private Vector3 moveDirection;
private float firstPersonControl;
}
Notes:
- Access modifiers come before the type in C#:
public float speed; - No
varhere — these are fields, not local variables - Types are
float,Vector3, notvar floatorvar Vector3
Use var inside methods, not at the field level.
4. Fixing the sprint / movement logic in clean C
Let’s refactor the sprint-related code into idiomatic C# and solve other common errors along the way (like Vector3 + float issues).
Common error 2: Operator '+' cannot be applied to operands of type 'UnityEngine.Vector3' and 'float'
In Unity, you can’t add a Vector3 and a float directly:
// ❌ Won’t compile
transform.Translate(moveDirection + tempSpeed * Time.deltaTime);
Here moveDirection is a Vector3 and tempSpeed * Time.deltaTime is a float.
You need either:
- A
Vector3multiplied by the float, or - Add the float to a specific component:
moveDirection.x + something
A clean C# sprint controller
Here’s a more idiomatic version of a simple sprint/movement script:
using UnityEngine;
public class SprintController : MonoBehaviour
{
[Header("Movement")]
public float naturalSpeed = 5.0f;
public float sprintMultiplier = 1.5f;
private Vector3 _moveDirection;
private CharacterController _characterController;
private void Awake()
{
_characterController = GetComponent<CharacterController>();
}
private void Update()
{
// 1. Read input
float horizontal = Input.GetAxis("Horizontal");
float vertical = Input.GetAxis("Vertical");
// 2. Base movement direction in local space
_moveDirection = new Vector3(horizontal, 0f, vertical);
if (_moveDirection.sqrMagnitude > 1f)
{
_moveDirection.Normalize();
}
// 3. Calculate speed
float currentSpeed = naturalSpeed;
if (Input.GetKey(KeyCode.LeftShift))
{
currentSpeed *= sprintMultiplier;
}
// 4. Apply speed and deltaTime
Vector3 velocity = _moveDirection * currentSpeed;
// 5. Move with CharacterController to handle collisions
_characterController.Move(velocity * Time.deltaTime);
}
}
Where does var fit here? In local variables:
private void Update()
{
var horizontal = Input.GetAxis("Horizontal"); // OK – local
var vertical = Input.GetAxis("Vertical"); // OK – local
var input = new Vector3(horizontal, 0f, vertical);
// ...
}
You can use var for locals if it improves readability, but fields keep their explicit type.
5. Patterns that will always trigger this var error
Use this as a quick mental checklist. If you do this with var, you’ll get the error:
❌ Using var in a field
public class Example : MonoBehaviour
{
var speed = 10f; // ❌ Not allowed
}
✅ Fix:
public class Example : MonoBehaviour
{
public float speed = 10f;
}
❌ Using var in a method signature
public var GetSpeed() // ❌
{
var speed = 10f; // ✅ local – this is fine
return speed;
}
public void Move(var direction) // ❌
{
// ...
}
✅ Fix:
public float GetSpeed()
{
var speed = 10f; // OK
return speed;
}
public void Move(Vector3 direction)
{
// ...
}
❌ Trying to “combine” UnityScript-style syntax with C
// ❌ This is not C#
var float NaturalSpeed = 10.0f;
var Vector3 moveDirection;
✅ Fix:
// ✅ Proper C#
public float naturalSpeed = 10.0f;
private Vector3 moveDirection;
6. When should you actually use var in C#?
Now that you know the rules, here’s a practical guideline:
👍 Great places to use var
- When the type is obvious on the right-hand side:
var rb = GetComponent<Rigidbody>();
var enemy = new Enemy(); // clear enough
var pos = transform.position; // Unity devs know this is Vector3
- When working with LINQ or long generic types:
var grouped = items
.GroupBy(x => x.Category)
.ToDictionary(g => g.Key, g => g.ToList());
👎 Places to avoid var
- Public API boundaries (method parameters/return types)
- Fields that represent important domain concepts and benefit from being explicit:
// Prefer explicit type here
private float _moveSpeed;
private Vector3 _currentDirection;
Use var primarily for local inference, not to hide important types.
7. Key takeaways
Let’s recap the big ideas so you never get bitten by this error again:
-
varis only for local variables inside methods, not for fields, parameters or return types. - It requires an initializer so the compiler can infer the type.
- UnityScript syntax (
var x : float) is not C#. In modern Unity projects, you should use pure C#. - For sprint/movement code:
- Use explicit fields for configuration (
float,Vector3) - Use
varonly for locals when it makes the code more readable - Don’t add
Vector3+floatdirectly; multiplyVector3byfloatinstead
- Use explicit fields for configuration (
- When in doubt, start with explicit types, then introduce
varwhere it’s safe and clear.
Written by: Cristian Sifuentes – C# / .NET Engineer | Unity Enthusiast | Clean Code Advocate
Have you run into other confusing C# compiler errors in your Unity projects?
Drop them in the comments — they often hide deeper language concepts that are worth mastering.

Top comments (0)