Hero image

Conseils de nommage et de style de code pour le scripting C# dans Unity

Cette page a été traduite automatiquement pour faciliter votre expérience. Nous ne pouvons pas garantir l'exactitude ou la fiabilité du contenu traduit. Si vous avez des doutes quant à la qualité de cette traduction, reportez-vous à la version anglaise de la page web.

Bien qu'il n'y ait peut-être pas une seule bonne façon de formater votre code C#, s'accorder sur un style cohérent au sein de votre équipe peut aboutir à un code plus propre, plus lisible et évolutif. Un guide de style bien organisé peut vous aider à maîtriser les incohérences pour produire un produit final cohérent.

Les noms de vos variables, classes et méthodes ne sont pas de simples étiquettes. Ils portent du poids et du sens. Un bon style de nommage influence la façon dont quelqu'un lisant votre programme peut comprendre l'idée que vous essayez de transmettre.

Cette page fournit des conseils et des considérations clés à garder à l'esprit pour les conventions de nommage et le formatage du code lors de la création de votre propre guide de style.

Remarque : Les recommandations partagées ici sont basées sur celles fournies par Microsoft. Les meilleures règles de guide de style de code sont celles qui répondent le mieux aux besoins de votre équipe.

Vous pouvez trouver un exemple de guide de style de code ici ou télécharger le livre électronique complet, Utilisez un guide de style C# pour un code de jeu propre et évolutif (édition Unity 6).

Noms d'identificateurs

Un identificateur est tout nom que vous attribuez à un type (classe, interface, struct, délégué ou énumération), membre, variable ou espace de noms.

Évitez les caractères spéciaux (barres obliques inverses, symboles, caractères Unicode) dans vos identificateurs, même si C# les autorise. Cela peut interférer avec certains outils de ligne de commande Unity. Évitez les caractères inhabituels pour garantir la compatibilité avec la plupart des plateformes.

Terminologie de la casse

Vous ne pouvez pas définir de variables avec des espaces dans le nom car C# utilise le caractère espace pour séparer les identifiants. Les schémas de casse peuvent atténuer le problème d'avoir à utiliser des noms ou des phrases composés dans le code source.

Ci-dessous, plusieurs conventions de nommage et de casse bien connues :

Notation Camel (camelCase)

Également connu sous le nom de camel caps, camel case est la pratique d'écrire des phrases sans espaces ni ponctuation, séparant les mots par une seule lettre majuscule. La toute première lettre est en minuscule. Les variables locales et les paramètres de méthode sont en camel case. Par exemple :


exempleJoueurContrôleur

maxHealthPoints

endOfFile

Notation Pascal (PascalCase)

Le cas Pascal est une variation du cas de chameau, où la lettre initiale est en majuscule. Utilisez ceci pour les classes, les champs publics et les noms de méthodes dans le développement Unity. Par exemple :


ExempleJoueurContrôleur

MaxHealthPoints

FinDeFichier

Notation Snake (snake_case)

Dans ce cas, les espaces entre les mots sont remplacés par un caractère de soulignement. Par exemple :

example_player_controller

max_health_points

end_of_file

Notation Kebab (kebab-case)

Ici, les espaces entre les mots sont remplacés par des tirets. Les mots apparaissent sur une "broche" de caractères tiret. Par exemple :

exemple-joueur-controleur

points-de-vie-max

fin-de-fichier

méthodologie-des-conventions-de-nommage

La notation Kebab est largement utilisée dans les technologies web et notamment pour le CSS. Nous le recommandons également pour une utilisation avec UI Toolkit USS.

notation_hongroise

Le nom de la variable ou de la fonction indique souvent son intention ou son type. Par exemple :

int iCompteur

string strNomJoueur


La notation hongroise est une ancienne convention et n'est pas courante dans le développement Unity.

Champs et variables

Considérez ces règles pour vos variables et champs :

  • Utilisez des noms de noun pour les noms de variables : Les noms de variables doivent être descriptifs, clairs et sans ambiguïté car ils représentent une chose ou un état. Utilisez donc un nom lorsque vous les nommez, sauf lorsque la variable est de type bool (voir ci-dessous).
  • Préfixez les booléens avec un verbe : Ces variables indiquent une valeur true ou false. Souvent, elles sont la réponse à une question, comme – le joueur court-il ? Le jeu est-il terminé ? Préfixez-les avec un verbe pour rendre leur signification plus évidente. Souvent, cela est associé à une description ou une condition, par exemple isDead, isWalking, hasDamageMultiplier, etc.
  • Utilisez des noms significatifs. Ne pas abréger (sauf en mathématiques) : Vos noms de variables doivent révéler leur intention. Choisissez des noms qui sont faciles à prononcer et à rechercher – non seulement pour vos collègues mais aussi pour fournir un contexte supplémentaire au code lors de l'utilisation d'outils d'IA, car cela peut contribuer à une génération de code et des suggestions plus précises. Choisissez des noms d'identifiants qui sont facilement lisibles. Par exemple, une propriété nommée HorizontalAlignment est plus lisible que AlignmentHorizontal. Les variables à une seule lettre sont acceptables pour les boucles et les expressions mathématiques, mais sinon, n'abrégez pas. La clarté est plus importante que le temps gagné en omettant quelques voyelles. Vous pourriez être tenté d'utiliser des noms courts "junk" lors du prototypage, mais cela ne vous fera pas gagner de temps si vous devez refactoriser le code à une date ultérieure. Choisissez des noms significatifs dès le début.
  • Utilisez la casse pascal (MyPropertyName) pour les champs publics. Utilisez la casse camel (myPrivateVariable) pour les variables privées : Pour une alternative aux champs publics, utilisez des propriétés avec un accesseur public (voir le formatage ci-dessus et ci-dessous).
  • Envisagez d'utiliser des préfixes ou un encodage spécial : Certaines guides suggèrent d'ajouter un préfixe aux variables membres privées avec un underscore (_) pour les différencier des variables locales. Dans nos guides de style, nous utilisons des préfixes pour les variables membres privées (m_), les constantes (k_) ou les variables statiques (s_), afin que le nom puisse révéler plus d'informations sur la variable d'un coup d'œil. Par exemple, movementSpeed devient m_movementSpeed. Mélanger PascalCase avec le préfixe tel que m_MovementSpeed est également une option, mais est généralement moins couramment utilisé dans le C# moderne. Alternativement, utilisez le mot-clé this pour distinguer entre les variables membres et locales dans le contexte et sauter le préfixe. Les champs et propriétés publics n'ont généralement pas de préfixes. Les variables locales et les paramètres utilisent le camel case sans préfixe. De nombreux développeurs évitent cela et comptent plutôt sur l'éditeur. Cependant, tous les IDE ne prennent pas en charge la mise en surbrillance et le codage couleur, et certains outils ne peuvent pas montrer de contexte riche du tout.
  • Les champs sont automatiquement initialisés à leurs valeurs par défaut : La valeur par défaut est généralement 0 pour les types numériques comme int, tandis que les champs de type référence (par exemple, objets) sont initialisés à null par défaut, et les champs booléens sont initialisés à false par défaut. Étant donné cela, définir explicitement un champ à sa valeur par défaut est généralement inutile.
  • Nommez les variables constantes avec k_ comme préfixe et en PascalCase : Cela aide à distinguer les constantes des variables ou propriétés régulières, et rend le code plus facile à lire et à maintenir.
  • Spécifiez (ou omettez) les modificateurs de niveau d'accès de manière cohérente : Si vous omettez le modificateur d'accès, le compilateur supposera que le niveau d'accès est privé. Cela fonctionne bien, mais soyez cohérent dans la façon dont vous omettez le modificateur d'accès par défaut. Les directives de MSFT recommandent de spécifier explicitement privé pour clarifier le niveau d'accès et éviter toute ambiguïté. D'autres guides soutiennent que vous devriez supprimer les spécificateurs d'accès redondants (laisser de côté 'privé' au niveau de type) et, de même, supprimer les initialisateurs redondants (c'est-à-dire pas '= 0' sur les ints, '= null' sur les types de référence, etc.). N'oubliez pas que vous devrez utiliser protected si vous voulez cela dans une sous-classe plus tard. Cependant, il est généralement considéré comme une bonne pratique de spécifier les modificateurs de niveau d'accès.
  • Favorisez la lisibilité plutôt que la brièveté : Comme cet exemple de la documentation MSFT le montre, le nom de la propriété CanScrollHorizontally est meilleur que ScrollableX (une référence obscure à l'axe X).
  • Utilisez une déclaration de variable par ligne : C'est moins compact, mais cela améliore la lisibilité.
  • Évitez les noms redondants : Si votre classe s'appelle Player, vous n'avez pas besoin de créer des variables membres appelées PlayerScore ou PlayerTarget. Réduisez-les à Score ou Target.
  • Supprimez les initialisateurs redondants (c'est-à-dire pas de '= 0' sur les entiers, '= null' sur les types de référence, etc.).
  • Évitez les blagues ou les jeux de mots : Bien qu'ils puissent susciter un rire maintenant, les variables infiniteMonkeys ou dudeWheresMyChar ne tiendront pas après quelques dizaines de lectures, et plus important encore, cela viole notre objectif précédemment énoncé de nommer en révélant le contexte.
  • Limitez l'utilisation du mot-clé var uniquement aux variables locales typées implicitement si cela aide à la lisibilité et que le type est évident : Précisez quand utiliser var dans votre guide de style. Par exemple, de nombreux développeurs évitent var lorsqu'il obscurcit le type de la variable ou avec des types primitifs en dehors d'une boucle.
Table des champs et des variables
// EXAMPLE: Public and private variables

public float DamageMultiplier = 1.5f;
public float MaxHealth;
public bool IsInvincible;

private bool _isDead;
private float _currentHealth;

// parameters
public void InflictDamage(float damage, bool isSpecialDamage)
{
    // local variable
    int totalDamage = damage;

    // local variable versus public member variable
    if (isSpecialDamage)
    {
    	totalDamage *= DamageMultiplier;
    }

    // local variable versus private member variable
    if (totalDamage > _currentHealth)
    {
        /// ...
    }
}

Énumérations

Les énumérations sont des types de valeur spéciaux définis par un ensemble de constantes nommées. Par défaut, les constantes sont des entiers, comptant à partir de zéro.

Utilisez la casse Pascal pour les noms et valeurs d'énumération. Vous pouvez placer des énumérations publiques en dehors d'une classe pour les rendre globales. Utilisez un nom singulier pour le nom de l'énumération car il représente une seule valeur d'un ensemble de valeurs possibles. Ils ne doivent avoir ni préfixe ni suffixe.

Remarque : Les énumérations bit à bit marquées avec l'attribut System.FlagsAttribute sont l'exception à cette règle. Vous les mettez généralement au pluriel car elles représentent plus d'un type.


// EXAMPLE: Enums use singular nouns …
public enum WeaponType
{
    Knife,
    Gun,
    RocketLauncher, 
    BFG
}

public enum FireMode
{
    None = 0,
    Single = 5,
    Burst = 7,
    Auto = 8, 
}

// EXAMPLE: … but a bitwise enum is plural.

[Flags] 
public enum AttackModes 
{
  // Decimal                          // Binary
   None = 0,                          // 000000
   Melee = 1,                         // 000001
   Ranged = 2,                        // 000010
   Special = 4,                       // 000100

   MeleeAndSpecial = Melee | Special  // 000101
}

Classes et interfaces

Suivez ces règles standard lors de la nomination de vos classes et interfaces :

  • Utilisez des noms ou des phrases nominales en casse Pascal pour les noms de classe : Cela distingue les noms de type des méthodes, qui sont nommées avec des phrases verbales.
  • Si vous avez un Monobehaviour dans un fichier, le nom du fichier source doit correspondre : Vous pouvez avoir d'autres classes internes dans le fichier, mais il ne doit y avoir qu'un seul Monobehaviour par fichier.
  • Préfixez les noms d'interface par un I majuscule : Suivez cela par un adjectif qui décrit la fonctionnalité.
// EXAMPLE: Class formatting
public class ExampleClass : MonoBehaviour
{

    public int PublicField;
    public static int MyStaticField;

    private int _packagePrivate;
    private int _myPrivate;

    private static int _myPrivate;

    protected int _myProtected;

    public void DoSomething()
    {

    }
}

// EXAMPLE: Interfaces
public interface IKillable
{
    void Kill();
}

public interface IDamageable<T>
{
    void Damage(T damageTaken);
}

Méthodes

En C#, chaque instruction exécutée est effectuée dans le contexte d'une méthode.

Note : « fonction » et « méthode » sont souvent utilisés de manière interchangeable dans le développement Unity. Cependant, parce que vous ne pouvez pas écrire une fonction sans l'incorporer dans une classe en C#, « méthode » est le terme accepté.

Les méthodes effectuent des actions, appliquez donc ces règles pour les nommer en conséquence :

  • Commencez le nom par un verbe ou des phrases verbales : Ajoutez du contexte si nécessaire. par exemple ObtenirDirection, TrouverCible, etc.
  • Utilisez le camel case pour les paramètres : Formatez les paramètres passés dans la méthode comme des variables locales.
  • Les méthodes retournant un booléen doivent poser des questions : Tout comme les variables booléennes elles-mêmes, préfixez les méthodes avec un verbe si elles retournent une condition vrai-faux. Cela les formule sous la forme d'une question, par exemple EstJeuTerminé, ACommencéTour.
// EXAMPLE: Methods start with a verb.
public void SetInitialPosition(float x, float y, float z)
{
    transform.position = new Vector3(x, y, z);
}

// EXAMPLE: Methods ask a question when they return bool.
public bool IsNewPosition(Vector3 currentPosition)
{
    return (transform.position == newPosition);
}

Événements et gestionnaires d'événements

Les événements en C# implémentent le modèle observateur. Ce modèle de conception logicielle définit une relation dans laquelle un objet, le sujet (ou éditeur), peut notifier une liste d'objets dépendants appelés observateurs(ou abonnés). Ainsi, le sujet peut diffuser des changements d'état à ses observateurs sans coupler étroitement les objets impliqués. Vous pouvez en apprendre davantage sur l'utilisation de l'observateur et d'autres modèles de conception dans vos projets Unity dans l'e-book Améliorez votre code avec des modèles de conception et SOLID.

Utilisez des verbes

Nommez l'événement avec une phrase verbale. Choisissez un nom qui communique le changement d'état avec précision. Utilisez le présent ou le participe passé pour indiquer des événements « avant » ou « après ». Par exemple, spécifiez « OuvrirPorte » pour un événement avant d'ouvrir une porte ou « PorteOuverte » pour un événement après.

Utilisez System.Action

Dans la plupart des cas, le Action délégué peut gérer les événements nécessaires au gameplay. Vous pouvez passer de 0 à 16 paramètres d'entrée de différents types avec un type de retour de void. Utiliser le délégué prédéfini permet d'économiser du code.

Remarque : Vous pouvez également utiliser les délégués GestionnaireÉvénements ou GestionnaireÉvénements. Concordez en équipe sur la manière dont chacun mettra en œuvre les événements.

// EXAMPLE: Events 

// using System.Action delegate

public event Action OpeningDoor;    // event before
public event Action DoorOpened;     // event after

public event Action<int> PointsScored;
public event Action<CustomEventArgs> ThingHappened;

Préfixez la méthode par "On"

Le sujet qui invoque l'événement le fait généralement à partir d'une méthode préfixée par « On », par exemple. « OnOuvrirPorte » ou « OnPorteOuverte ».

// raises the Event if you have subscribers
public void OnDoorOpened()
{
    DoorOpened?.Invoke();
}

public void OnPointsScored(int points)
{
    PointsScored?.Invoke(points);
}

Préfixez par le nom du sujet et un soulignement

Si le sujet s'appelle « GameEvents », vos observateurs peuvent avoir une méthode appelée « GameEvents_OpeningDoor » ou « GameEvents_DoorOpened ». Notez que cela s'appelle la "méthode de gestion des événements", à ne pas confondre avec le délégué EventHandler.

Utilisez EventArgs avec précaution

Créez des EventArgs personnalisés uniquement si nécessaire. Si vous devez passer des données personnalisées à votre événement, créez un nouveau type d'EventArgs, soit hérité de System.EventArgssoit d'une structure personnalisée.

// define an EventArgs if needed

// EXAMPLE: Read-only, custom struct used to pass an ID and Color
public struct CustomEventArgs
{
    public int ObjectID { get; }
    public Color Color { get; }

    public CustomEventArgs(int objectId, Color color)
    {
        this.ObjectID = objectId;
        this.Color = color;
    }
}

Espaces de noms

Utilisez les espaces de noms pour vous assurer que vos classes, interfaces, énumérations, etc. ne seront pas en conflit avec celles existantes d'autres espaces de noms ou de l'espace de noms global. Les espaces de noms peuvent également éviter les conflits avec des actifs tiers provenant de l'Asset Store.

Lors de l'application des espaces de noms :

  • Utilisez PascalCase sans symboles spéciaux ni traits de soulignement.
  • Ajoutez une directive using en haut du fichier pour éviter de taper plusieurs fois le préfixe de l'espace de noms.
  • Créez également des sous-espaces de noms. Utilisez l'opérateur point (.) pour délimiter les niveaux de nom, vous permettant d'organiser vos scripts en catégories hiérarchiques. Par exemple, vous pouvez créer MyApplication.GameFlow, MyApplication.AI, MyApplication.UI, etc. pour contenir différents composants logiques de votre jeu.
  • Il est généralement considéré comme une bonne pratique d'avoir des espaces de noms qui reflètent la structure des dossiers du projet, car regrouper logiquement des classes et des composants connexes facilite également la recherche et la compréhension de la structure de la base de code.
namespace Enemy 
{
    public class Controller1 : MonoBehaviour 
    {
        ...
    }
    
    public class Controller2 : MonoBehaviour 
    {
        ...
    }
}

Préfixes

Dans le code, ces classes sont appelées Enemy.Controller1 et Enemy.Controller2, respectivement. Ajoutez une ligne using pour éviter de taper le préfixe :

using Enemy;

Lorsque le compilateur trouve les noms de classe Controller1 et Controller2, il comprend que vous voulez dire Enemy.Controller1 et Enemy.Controller2.

Si le script doit faire référence à des classes avec le même nom provenant de différents espaces de noms, utilisez le préfixe pour les différencier. Par exemple, si vous avez une classe Controller1 et une classe Controller2 dans l'espace de noms Player, vous pouvez écrire Player.Controller1 et Player.Controller2 pour éviter tout conflit. Sinon, le compilateur signalera une erreur.

using Enemy;

Obtenez plus de conseils sur le style de code

En savoir plus sur le formatage général ici ou consultez le livre électronique complet. Vous pouvez également explorer notre exemple de guide de style de code.