mcpField
U
Unity Refactor

Unity Refactor

github.com/juliankerignardDevelopment854 installsUpdated 32w ago
Repository

About Unity Refactor

A skill for analyzing Unity C# codebases, prioritizing code smells by risk, and carrying out refactoring one change at a time. It verifies references and compilation after each change, with the goal of preserving existing behavior.

Key features

  1. 01Scan for Unity code smells
  2. 02Prioritize refactoring by risk
  3. 03Present a plan before changes
  4. 04Apply one refactor at a time
  5. 05Verify references and compilation

Use cases

  1. 01Review technical debt in Unity scripts
  2. 02Break up long methods or manager classes
  3. 03Replace magic strings with constants
  4. 04Reduce direct dependencies between systems

MCP support

The skill has no Unity MCP dependency; it uses Read, Write, Edit, Grep, Glob, and Bash tools.

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/juliankerignard/unity-skills --skill unity-refactor

After installing, type/unity-refactorin Claude Code to confirm it loaded.

Bundled filesreferences/refactor-recipes.md

Details

From the project README

Unity Refactor

Ce que fait cette skill

Cette skill analyse une codebase Unity C# pour detecter les code smells, propose un plan de refactoring priorise par niveau de risque, puis execute les changements un par un avec verification apres chaque modification. L'objectif est d'ameliorer la qualite du code sans jamais changer le comportement existant.

Prerequis

  • Projet Unity avec du code C# existant dans Assets/Scripts/
  • Pas de dependance MCP Unity : utilise uniquement Read, Write, Edit, Grep, Glob, Bash

Arbre de decision

Quel type de dette technique ?
|
+-- Code trop long / illisible ?
|   +-- Fichier > 500 lignes --> God class split (risque eleve)
|   +-- Methode > 50 lignes --> Extraction de methodes (risque faible)
|
+-- Couplage fort entre classes ?
|   +-- References directes cross-systeme --> Event Channel SO (risque moyen)
|   +-- Singleton partout --> SO / Service Locator (risque eleve)
|
+-- API obsolete ?
|   +-- Old Input --> New Input System (risque moyen, recette 6)
|   +-- Coroutines --> async Awaitable (risque moyen, recette 4)
|
+-- Code smells generaux ?
    +-- Magic strings --> Constantes / enum (risque faible)
    +-- Champs publics --> [SerializeField] private (risque faible)

Voir le catalogue de refactoring ci-dessous pour les recettes detaillees.

Demarrage rapide

  1. Scanner la codebase pour detecter les code smells
  2. Classer et prioriser les refactorings par risque
  3. Presenter le plan a l'utilisateur
  4. Executer UN refactoring a la fois
  5. Verifier compilation + references apres chaque changement
  6. Repeter jusqu'a completion du plan

Guide etape par etape

Etape 1 : Scanner la codebase pour les code smells

Lancer toutes les detections en parallele avec Grep, Glob et Bash :

Glob : Assets/Scripts/**/*.cs                                    # Tous les fichiers C#
Bash : find Assets/Scripts -name "*.cs" -exec wc -l {} + | sort -rn | head -20  # Fichiers volumineux
Grep : "static\s+\w+\s+Instance" dans Assets/Scripts/**/*.cs    # Singletons
Grep : "void\s+Update\s*\(\)" dans Assets/Scripts/**/*.cs       # Update polling
Grep : "Find\(\"" dans Assets/Scripts/**/*.cs                    # Magic strings (Find)
Grep : "CompareTag\(\"" dans Assets/Scripts/**/*.cs              # Magic strings (Tags)
Grep : "StartCoroutine" dans Assets/Scripts/**/*.cs              # Coroutine spaghetti
Grep : "public\s+(?!void|static|override|class)" dans *.cs      # Champs publics exposes
Grep : "class\s+\w+\s*:\s*\w+" dans Assets/Scripts/**/*.cs      # Heritage (tracer les chaines)
Etape 2 : Classer et prioriser

Utiliser le catalogue de refactoring ci-dessous pour classer chaque smell detecte.

Catalogue de refactoring Unity
SmellPattern de detection (Grep)RefactoringRisque
God Manager (>500 lignes)Fichiers .cs avec "Manager" > 500 lignesSplit en services focusesEleve
Singleton MonoBehaviourstatic.*Instance.*get dans MonoBehaviourRemplacer par SO + Service LocatorEleve
Heritage profond (>3 niveaux)Chaines de class X : Y sur >3 niveauxAplatir avec composition + interfacesEleve
Update pollingUpdate() avec checks booleensRemplacer par events/callbacksMoyen
God UpdateUpdate() avec >5 responsabilitesSeparer en composants distinctsMoyen
Feature envyMethodes accedant intensivement aux donnees d'une autre classeDeplacer la methode vers le proprietaire des donneesMoyen
Primitive obsessionGroupes repetes de int/float/stringExtraire en value types/structsMoyen
Magic strings"string" dans Find/CompareTag/AnimatorRemplacer par const/enum/SOFaible
Champs publics InspectorNombreux champs public[SerializeField] private + SO configFaible
Methode geante (>50 lignes)Methodes longuesExtraire des sous-methodesFaible
Seuils de detection
MetriqueSeuilVerdict
Lignes par classe> 500God class
Lignes par methode> 50Methode trop longue
Methodes par classe> 15Trop de responsabilites
Parametres par methode> 5Parameter object necessaire
Niveaux d'heritage> 3Aplatir la hierarchie

Ordre de priorite : Faible (magic strings, champs publics, methodes longues) puis Moyen (Update polling, feature envy, God Update) puis Eleve (singletons, God classes, heritage).

Etape 3 : Presenter le plan a l'utilisateur

Avant toute modification, presenter un tableau : # | Fichier | Smell | Refactoring | Risque | Fichiers impactes. Proposer tout / selection / annuler. Attendre la validation avant de commencer.

Etape 4 : Executer UN refactoring a la fois

Pour chaque refactoring du plan valide :

1. Read : Lire le fichier cible completement
2. Grep : Identifier TOUTES les references au code qui va changer
         Grep : "NomClasse" dans Assets/Scripts/**/*.cs
         Grep : "NomMethode" dans Assets/Scripts/**/*.cs
3. Edit : Effectuer le changement (une seule modification atomique)
4. Edit : Mettre a jour toutes les references trouvees
5. Grep : Verifier qu'aucune reference orpheline ne subsiste
6. Passer au refactoring suivant
Etape 5 : Verifier apres chaque changement

Apres chaque refactoring individuel :

1. Grep pour les anciens noms de classes/methodes : doit retourner 0 resultats
2. Grep pour les references cassees : "using.*OldNamespace" absent
3. Verifier coherence : les nouveaux fichiers sont dans le bon dossier
4. Verifier que les [SerializeField] et references Inspector ne sont pas casses

Si un probleme est detecte, annuler le changement et notifier l'utilisateur avant de continuer.

Etape 6 : Repeter jusqu'a completion

Parcourir le plan dans l'ordre de priorite (risque faible en premier). Apres chaque refactoring termine, indiquer la progression :

[2/8] Termine : EnemyController.cs - Extraction de methodes
       Fichiers modifies : 1
       References mises a jour : 0
       Status : OK

Recettes de refactoring

6 recettes detaillees avec code avant/apres dans references/refactor-recipes.md :

RecetteRisqueDescription
Singleton vers SO ServiceEleveRemplacer les singletons MonoBehaviour par des ScriptableObjects injectes
God Manager vers servicesEleveDecouper un manager monolithique en services focuses
Magic strings vers constantesFaibleExtraire les strings en constantes et Animator.StringToHash
Coroutines vers async AwaitableMoyenMigrer les IEnumerator vers async Awaitable (Unity 6+)
References directes vers Event ChannelMoyenDecouple publisher/subscriber avec ScriptableObject events
Old Input vers New Input SystemMoyenMigrer de UnityEngine.Input vers InputSystem

Regles strictes

  • JAMAIS faire 2 refactorings en meme temps sur le meme fichier
  • JAMAIS changer le comportement observable (refactoring != nouvelle feature)
  • JAMAIS renommer un champ [SerializeField] sans avertir que les references Inspector seront perdues
  • JAMAIS supprimer du code sans verifier toutes les references (Grep dans tout le projet)
  • JAMAIS refactorer un fichier sans l'avoir lu completement d'abord
  • TOUJOURS verifier la compilation apres chaque changement individuel
  • TOUJOURS verifier les references cassees avec Grep apres un renommage
  • TOUJOURS presenter le plan complet avant la premiere modification
  • TOUJOURS commencer par les refactorings a risque faible
  • TOUJOURS preferer le plus petit changement possible
  • TOUJOURS utiliser Edit (pas Write) pour les modifications de fichiers existants
  • TOUJOURS preserver les attributs Unity ([SerializeField], [Header], [Tooltip], etc.)

Skills connexes

  • Generer du nouveau code propre ? Utiliser /unity-code-gen (Unity Code Gen)
  • Audit de performance (detection sans refactoring) ? Utiliser /perf-audit (Unity Perf Audit)
  • Tester le code apres refactoring ? Utiliser /unity-test (Unity Test)
  • Diagnostiquer un bug decouvert pendant le refactoring ? Utiliser /unity-debug (Unity Debug)

Troubleshooting

ProblemeSolution
References Inspector cassees apres renommage de champLe champ [SerializeField] a ete renomme. Utiliser [FormerlySerializedAs("oldName")] pour migrer les donnees serialisees
Erreur de compilation apres split de classeVerifier les using manquants dans les nouveaux fichiers et les references d'assembly definition
Comportement change apres refactoringAnnuler le changement (Edit pour restaurer), analyser la difference, et refaire avec une approche plus conservatrice
Prefab override perduLe champ a change de nom ou de type. Ajouter [FormerlySerializedAs] et re-verifier les prefabs concernes
Circular dependency apres splitExtraire une interface dans un assembly partage, ou inverser la dependance avec un event channel SO
Tests cassent apres refactoringLes tests testaient l'implementation (noms de methodes) plutot que le comportement. Mettre a jour les tests pour utiliser les nouveaux noms
AnimatorController reference casseeLes string parameters ont ete remplaces par des hash. Verifier que Animator.StringToHash est utilise avec la meme string que dans le controller
ScriptableObject reference nullL'asset SO n'a pas ete cree dans le projet. Creer l'asset via le menu Create et l'assigner dans l'Inspector

Comments

Markdown supported