Automatic C# code formatter that reorganizes class members following style conventions for Unity projects.
UnityClassFormatter automatically reorders the members of your C# classes in Unity, grouping them by type and access level, while preserving [Header] groupings to not disperse related properties in the Inspector.
This repository is included as a Git submodule rather than being copied into the project. The goal is to avoid duplicating this external tool across multiple Unity projects while keeping it available locally.
- Prevents storing 20MB of binaries in this repository.
- Keeps the formatter versioned and reusable across multiple projects.
- Does not affect the Unity asset pipeline.
- Can be updated independently when needed.
The submodule is located under:
Tools/UnityClassFormatter
This keeps it clearly separated from Assets/ and from any game-specific code.
When cloning the main repository, run:
git submodule update --init --recursive
or clone directly with:
git clone --recursive <repo-url>
To pull the latest changes from the remote formatter repository:
cd Tools/UnityClassFormatter
git pull origin main # or the relevant branch
cd ../..
git commit -am "Update UnityClassFormatter submodule"
VSCode or other tools can reference the executable directly from:
Tools/UnityClassFormatter/bin/Publish/UnityClassFormatter.exe
No files from the submodule are included in the Unity build.
To integrate UnityClassFormatter into your own Unity project as a Git submodule, follow these steps:
- Open a terminal in your Unity project's root directory.
- Add the submodule under the
Tools/folder:git submodule add https://github.com/EtnasSoft/UnityClassFormatter.git Tools/UnityClassFormatter - Initialize and update the submodule:
git submodule update --init --recursive - The formatter executable will be available at
Tools/UnityClassFormatter/bin/publish/UnityClassFormatter.exe. - Configure your code editor (e.g., VSCode) to use this executable for automatic formatting of
.csfiles. See the "Usage in VSCode" section below for an example configuration.
This setup ensures the formatter is versioned and reusable across your projects without duplicating binaries.
Members are organized in this order:
- Constant Fields (constant fields)
- Static Fields (static fields)
- Fields (instance fields)
- Constructors (constructors)
- Properties (properties)
- Events / Delegates (events and delegates)
- Lifecycle Methods (Unity lifecycle methods)
AwakeOnEnableOnDisableOnDestroy
- Public Methods (public methods)
- Private Methods (private methods)
- Nested Types (nested types)
Within each section, members are sorted by:
-
Access level:
publicinternalprotectedprivate
-
**
[Header]group:** Fields/properties with the same[Header]are kept together -
**
[Header]position:** The field that has the[Header]attribute always goes first in its group -
Alphabetical order: Within each group, they are sorted alphabetically by name
The formatter respects Unity groupings:
// BEFORE (unordered)
[Header("General Settings")]
[SerializeField] private float radius = 0f;
[SerializeField] private float startMinSpeed = 0f;
[SerializeField] private float startMaxSpeed = 0.3f;
[SerializeField] private float gravityModifier = 0f;
// AFTER (alphabetically ordered within the group)
[Header("General Settings")]
[SerializeField] private float radius = 0f; // ← Has [Header], goes first
[SerializeField] private float gravityModifier = 0f; // ↓
[SerializeField] private float startMaxSpeed = 0.3f; // ↓ Ordered
[SerializeField] private float startMinSpeed = 0f; // ↓ alphabeticallyFields remain grouped and are not scattered throughout the class.
The formatter runs automatically from VSCode via a configured command:
"commands": [
{
"cmd": "Formatter\\UnityClassFormatter\\bin\\publish\\UnityClassFormatter.exe \"${file}\"",
"match": "\\.cs$"
}
]When executed, it reformats the current .cs file automatically.
The source code is in:
Formatter/UnityClassFormatter/UnityClassFormatter.cs
- Open a terminal in the project folder (where the
.csprojis) - Run:
dotnet publish src/UnityClassFormatter/UnityClassFormatter.csproj --configuration Release --output bin/publish
- This generates the updated files:
bin/publish/UnityClassFormatter.exebin/publish/UnityClassFormatter.pdb
Formatter/
└── UnityClassFormatter/
├── UnityClassFormatter.cs ← Source code (edit here)
├── UnityClassFormatter.csproj ← Project configuration
└── bin/
└── publish/
├── UnityClassFormatter.exe ← Executable (generated)
└── UnityClassFormatter.pdb ← Debug symbols
- .NET 9.0 SDK to compile
- Microsoft.CodeAnalysis.CSharp 4.14.0 (included as dependency)
- The formatter does not modify the content of methods, only reorganizes their position
- Comments and attributes are kept with their respective members
- If a field has no
[Header], it is sorted alphabetically in its corresponding access level - Lifecycle methods (
Awake,OnEnable, etc.) are kept in their special section regardless of their visibility
Before:
public class PlayerController : MonoBehaviour {
private void Update() { }
[Header("Movement")]
[SerializeField] private float speed;
[SerializeField] private float jumpForce;
private Rigidbody rb;
public void Jump() { }
private void Start() { }
private void Awake() { }
[Header("Audio")]
[SerializeField] private AudioClip walkSound;
}After:
public class PlayerController : MonoBehaviour {
[Header("Audio")]
[SerializeField] private AudioClip walkSound;
[Header("Movement")]
[SerializeField] private float jumpForce;
[SerializeField] private float speed;
private Rigidbody rb;
private void Awake() { }
private void Start() { }
public void Jump() { }
private void Update() { }
}This project includes unit tests to verify the correctness of the class reordering functionality. The tests are located in the tests/UnityClassFormatter.Tests/ directory and use the xUnit testing framework.
To run the unit tests, ensure you have the .NET SDK installed and execute the following command from the project root:
dotnet testThe unit tests validate various aspects of the formatter's behavior, including:
- Basic reordering of class members (fields and methods) by access level and alphabetical order.
- Handling of
[Header]attributes to preserve Unity Inspector groupings. - Reordering within multiple header groups.
- Sorting of fields with and without headers, ensuring grouped fields remain together.
- Placeholder tests for main program functionality (e.g., file handling).
These tests ensure that the formatter correctly reorganizes C# classes without altering the logic or content of the code, while respecting Unity-specific attributes.
For changes in formatting rules, edit the file UnityClassFormatter.cs and adjust the logic in:
VisitClassDeclaration(): Define the categoriesSortMembers(): Define the sorting orderGetAccessOrder(): Define the access level priority