Hero image

Unity での C# スクリプティングのフォーマットに関するベストプラクティス

このウェブページは、お客様の便宜のために機械翻訳されたものです。翻訳されたコンテンツの正確性や信頼性は保証いたしかねます。翻訳されたコンテンツの正確性について疑問をお持ちの場合は、ウェブページの公式な英語版をご覧ください。

C# コードを形式する正しい方法は 1 つとは限りませんが、チーム全体で一貫したスタイルにすることで、よりクリーンで読みやすく、スケーラブルなコードベースを結果できます。このページでは、独自のスタイルガイドを作成する際に留意すべきクラス、メソッド、およびコメントに関するヒントとキー考慮事項を紹介します。

注:ここで紹介する推奨事項は、Microsoft が提供する推奨事項に基づいています。最適なコードスタイルガイドのルールは、チームのニーズに合ったものです。

コード スタイル ガイドの例はこちらから、または完全なeBook「Use a C# style guide for clean and scalable game code (Unity 6 edition)」をダウンロードしてください。

コードのフォーマット

命名に加えて、フォーマットすることで当て推量を減らし、コードの明瞭性を高めます。標準化されたスタイルガイドに従うことで、コードレビューはコードの見た目ではなく、コードの内容によって変わります。

これらのサンプルルールは、チームのニーズに合わせて省略、拡張、変更することができます。

いずれの場合も、各フォーマットルールをチームでどのように実装するかを検討し、全員に均一に適用させます。意見の食い違いを解決するには、チームのスタイルを見直しましょう。

Unity開発スタイル ガイドを設定する際には、次のコード形式に関する推奨事項をそれぞれ考慮してください。

プロパティ

プロパティは、クラス値の読み取り、書き込み、または計算を行うための柔軟なメカニズムを提供します。プロパティは public メンバー変数のように動作しますが、実際にはアクセサーと呼ばれる特殊なメソッドです。各プロパティには、バッキングフィールドと呼ばれる非公開フィールドにアクセスする get メソッドと set メソッドがあります。

このようにして、プロパティはデータをカプセル化し、ユーザーや外部オブジェクトによる不要な変更からデータを非表示にします。取得メソッドと設定メソッドにはそれぞれ独自のアクセスモディファイア子があり、プロパティを読み書き可能、読み取り専用、または書き込み専用にすることができます。

また、アクセサーを使用してデータの妥当性検査や換算 (例: データが目的の形式に適合するかの確認、特定の単位への値の変更) を行うこともできます。

プロパティの構文は変わる可能性があるため、スタイル ガイドで形式を定義する必要があります。これらのヒントを使用して、コード内でプロパティーの一貫性を保つことができます。

式のプロパティ

1 行の読み取り専用プロパティには式本体のプロパティを使用する(=>)。これは private バッキングフィールドを返します。

// EXAMPLE: Expression-bodied properties
public class PlayerHealth
{
    // the private backing field
    private int maxHealth;

    // read-only, returns backing field
    public int MaxHealth => maxHealth;

    // equivalent to:
    // public int MaxHealth { get; private set; }
}

自動実装プロパティ

その他はすべて古い {get; set; 構文:バッキングフィールドを指定せずに public プロパティを公開するだけの場合は、自動実装プロパティを使用します。set および get アクセサーに式本体構文を適用します。書き込みアクセスを許可しない場合は、setter を private にしてください。複数行のコードブロックでは、閉じ波かっこと開始波かっこの位置を合わせます。

// EXAMPLE: Expression-bodied properties
public class PlayerHealth
{
    // backing field
    private int _maxHealth;

    // explicitly implementing getter and setter
    public int MaxHealth
    {
        get => _maxHealth;
        set => _maxHealth = value;
    }

    // write-only (not using backing field)
    public int Health { private get; set; }

    // write-only, without an explicit setter
    public SetMaxHealth(int newMaxValue) => _maxHealth = newMaxValue;

}

シリアル化

スクリプト シリアル化は、データ構造やオブジェクトの状態を、後でUnityが保存および再構築できる形式に変換する自動プロセスです。パフォーマンス上の理由から、Unityはシリアル化を他のプログラミング環境とは異なる方法で処理します。

シリアル化されたフィールドは Inspector に表示されますが、静的、定数、または読み取り専用のフィールドはシリアル化できません。public であるか、[SerializeField] 属性でタグ付けされている必要があります。Unity は特定のフィールド タイプのみをシリアル化するため、シリアル化ルールの完全なセットについてはドキュメント ページを参照してください。

シリアライズされたフィールドを扱う際には、いくつかの基本的なガイドラインに従ってください。

  • <[SerializeField] 属性を使用します。SerializeField 属性は、private 変数または protected 変数を Inspector に表示するために使用できます。これにより、変数を public とマークするよりもデータがカプセル化され、外部オブジェクトがその値を上書きするのを防ぎます。
  • 範囲属性を使用して最小値と最大値を設定します。[範囲(分、最大)] 属性は、ユーザーが数値フィールドに割り当てることができるものを制限する場合に便利です。また、Inspector でフィールドをスライダーとして表すのにも便利です。
  • データをシリアライズ可能なクラスまたは構造体にグループ化して Inspector をクリーンアップ:public クラスまたは構造体を定義し、[Serializable] 属性でマークします。Inspector で公開する型ごとに public 変数を定義します。

別のクラスからこのシリアライズ可能クラスを参照します。結果として得られる変数は、Inspector の折りたたみ可能なユニット内に表示されます。

シリアライズ可能なクラス

シリアル化可能なクラスや構造体は INSPECTOR を整理するのに役立ちます。

// EXAMPLE: A serializable class for PlayerStats

using System;
using UnityEngine;

public class Player : MonoBehaviour
{
    [Serializable]
    public struct PlayerStats
    {
        public int MovementSpeed;
        public int HitPoints;
        public bool HasHealthPotion;
    }

// EXAMPLE: The private field is visible in the Inspector.

    [SerializeField]
    private PlayerStats _stats;
}

波かっこまたはインデントのスタイル

C# では 2 つの一般的なインデントスタイルがあります。

  • Allman スタイルは、BSD スタイルとも呼ばれます (BSD Unix の場合)。
  • K&R スタイル(「1 つの真の波かっこスタイル」)では、左波かっこが前のヘッダーと同じ行に保持されます。

これらのインデントスタイルにもバリエーションがあります。このガイドの例は、Microsoft Framework Design Guidelines の Allman スタイルを使用しています。どのチームを選択しても、全員が同じインデントと波かっこスタイルに従うようにしてください。

// EXAMPLE: Allman or BSD style puts opening brace on a new line.

void DisplayMouseCursor(bool showMouse) 
{
     if (!showMouse)
     {
          Cursor.lockState = CursorLockMode.Locked;
          Cursor.visible = false;
     }
     else
     {
          Cursor.lockState = CursorLockMode.None;
          Cursor.visible = true;
     }
}

// EXAMPLE: K&R style puts opening brace on the previous line.

void DisplayMouseCursor(bool showMouse){
     if (!showMouse) {
          Cursor.lockState = CursorLockMode.Locked;
          Cursor.visible = false;
     }
     else {
          Cursor.lockState = CursorLockMode.None;
          Cursor.visible = true;
     }
}

インデントを統一する

インデントは通常、2 つまたは 4 つのスペースです。タブとスペースの競争に火をつけることなく、チームの全員がエディターの設定について合意できるようにします。Visual Studio には、タブをスペースに換算するオプションがあります。

Visual Studio(Windows)で、[Tools]> [Options]> [Text Editor]> [C#]> [Tabs] を選択します。

Visual Studio for Macで、環境設定><ソースコード>C#ソースコードに移動します。テキストスタイルを選択して設定を調整します。

C シャープタブ

WINDOWS 用 VISUAL STUDIO のタブ設定

波かっこを省略しない

波かっこは省略しないでください(1 行のステートメントでも)。波かっこを使用すると、一貫性が高まり、コードが読みやすくなり、保守しやすくなります。この例では、波かっこがアクション DoSomething をループから明確に分離しています。

あとでデバッグ行を追加したり、DoSomethingElse を実行する必要がある場合は、波かっこがすでに配置されています。句を別の行にすることで、ブレークポイントを簡単に追加できます。

// EXAMPLE: Keep braces for clarity...

for (int i = 0; i < 100; i++) { DoSomething(i); }

// … and/or keep the clause on a separate line.
for (int i = 0; i < 100; i++)
{
    DoSomething(i);
}

// AVOID: Omitting braces

for (int i = 0; i < 100; i++) DoSomething(i);

複数行のステートメントをわかりやすくするために波かっこを付ける

ネストされた複数行のステートメントから波かっこを削除しない。波かっこを削除してもエラーにはなりませんが、混乱を招く可能性が高いです。任意であっても、わかりやすくするために波かっこを付けます。また、波かっこを使用すると、新しいロジックの追加などの変更を、周囲の構造体をリファクタリングすることなく安全に行うことができます。

// EXAMPLE: Keep braces for clarity.

for (int i = 0; i < 10; i++)
{
	for (int j = 0; j < 10; j++)
     {
		ExampleAction();
     }
}
// AVOID: Removing braces from nested multiline statements

for (int i = 0; i < 10; i++)
	for (int j = 0; j < 10; j++)
		ExampleAction();

switch ステートメントの標準化

フォーマットはさまざまであるため、スタイルガイドでチームの好みを文書化し、適宜switchステートメントを標準化してください。

case ステートメントをインデントする例を 1 つ示します。通常は、デフォルトケースを含めることをお勧めします。デフォルトのケースが必要ない場合 (例えば、すべての可能性が網羅されている場合) でも、ケースを含めることで、予期しない値をハンドルできるようにコードが準備されます。

// EXAMPLE: Indent cases from the switch statement.
switch (someExpression) 
{
   case 0:
      DoSomething();
      break;
   case 1:
      DoSomethingElse();
      break;
   case 2: 
      int n = 1;
      DoAnotherThing(n);
      break;
}

水平方向の間隔

間隔などの簡単な設定によって、画面上のコードの外観を向上させることができます。書式の設定は好みによって変わりますが、読みやすさを向上させるために以下の提案を試してみてください。

スペースを追加

スペースを追加してコード密度を下げる。余分な空白を入れることで、行の各部分が視覚的に分離され、読みやすくなります。

// EXAMPLE: Add spaces to make lines easier to read.
for (int i = 0; i < 100; i++) { DoSomething(i); }

// AVOID: No spaces
for(inti=0;i<100;i++){DoSomething(i);}

カンマの後の間隔

関数の引数の間には、カンマの後にスペースを 1 つ入れる。

// EXAMPLE: Use a single space after comma between arguments.
CollectItem(myObject, 0, 1);

// AVOID:
CollectItem(myObject,0,1);

括弧の後に間隔なし

括弧と関数の引数の後にスペースを入れないでください。

// EXAMPLE: No space after the parenthesis and function arguments
DropPowerUp(myPrefab, 0, 1);

//AVOID:
DropPowerUp( myPrefab, 0, 1 );

関数とかっこの間にはスペースを入れないでください

関数名とかっこの間にはスペースを入れないでください。

// EXAMPLE: Omit spaces between a function name and parenthesis.
DoSomething()

// AVOID:
DoSomething ()

角括弧内のスペースを避ける

角かっこ内にはスペースをできるだけ入れないようにしましょう。

// EXAMPLE: Omit spaces inside brackets.
x = dataArray[index];

// AVOID:
x = dataArray[ index ];

フロー制御条件前の間隔

フロー制御条件の前にスペースを 1 つ入れ、フロー比較演算子とかっこの間にスペースを入れます。

// EXAMPLE: Use space before condition; separate parentheses with a space.
while (x == y)

// AVOID:
while(x==y)

比較演算子との間隔

比較演算子の前後にスペースを 1 つ入れる。

// EXAMPLE: Use space before condition; separate parentheses with a space.
if (x == y)

// AVOID:
if (x==y)

読みやすさのヒント

行は短くしてください。水平空白を考慮する:標準的な行幅(80 ~ 120 文字)を決めます。長い行をオーバーフローさせるのではなく、小さな文に分割する。

インデント/階層を維持する:コードをインデントして、読みやすさを高める。

読みやすくするために必要でない限り、列整列を使用しない:このタイプの間隔は変数を揃えますが、型と名前の組み合わせが難しくなります。

ただし、ビット単位の式や大量のデータを扱う構造体では、列整列が便利です。項目を追加すると、列の整列を維持する作業が増える可能性があることに注意してください。オートフォーマッタによっては、 列のどの部分を揃えるかも変更される可能性があります 。

// EXAMPLE: One space between type and name

    public float Speed = 12f;
    public float Gravity = -10f;
    public float JumpHeight = 2f;

    public Transform GroundCheck;
    public float GroundDistance = 0.4f;
    public LayerMask GroundMask;

// AVOID: Column alignment

    public float                Speed = 12f;
    public float                Gravity = -10f;
    public float                JumpHeight = 2f;
    public Transform            GroundCheck;
    public float                GroundDistance = 0.4f;
    public LayerMask            GroundMask;

垂直間隔と領域

垂直間隔も必要に応じて使用できます。スクリプトの関連する部分をまとめ、空白行を使用してわかりやすくします。次の提案を試して、コードを最初から最後まで整理してください。

  • グループに依存するメソッドや類似のメソッドを組み合わせる:コードは論理的で一貫性がある必要があります。誰かがファイルを飛び回らなくても済むように、同じことを行うメソッドを並べておく。
  • クラスの異なる部分を区切るために、次のように縦方向の空白を使用します。例えば、次の間に 2 つの空白行を追加できます。
  • 変数の宣言とメソッド
  • クラスとインターフェース
  • if-then-else ブロック (読みやすさに役立つ場合)

これは最小限に留め、必要に応じてスタイルガイドにメモしてください。

コードでのリージョンの使用

#region ディレクティブを使用すると、C# ファイルのコードセクションを折りたたんだり非表示にしたりできるため、サイズの大きなファイルの管理が容易になります。

ただし、このガイドのクラスに関する一般的なアドバイスに従う場合は、クラスサイズを管理しやすく、#region ディレクティブを過剰に使用するようにしてください。コードブロックをリージョンの後ろに隠す代わりに、コードを小さなクラスに分割します。ソースファイルが短い場合は、リージョンを追加する傾向が少なくなります。

注:多くの開発者は、リージョンをコード臭またはアンチパターンと考えています。ディベートのどちらの側につくかをチームで決めましょう。

Visual Studio でのコードフォーマット

これらのフォーマットルールが圧倒しているように見えても、絶望しないでください。最新の IDE なら、設定と適用が効率的です。フォーマット規則のテンプレートを作成し、プロジェクトファイルを一度に換算できます。

スクリプト エディタのフォーマット規則を設定するには:

  • Visual Studio(Windows)で、[Tools]> [Options] に移動します。「Text Editor」>「C#」>「Code Style Formatting」を選択します。設定を使用して、「一般」、「インデント」、「改行」、「間隔」、「折り返し」のオプションを変更します。
  • Visual Studio for Mac で「Visual Studio」>「環境設定」を選択し、「ソースコード」>「コードフォーマット」>「C#ソースコード」に移動します。上部のポリシーを選択します。次に、「Text Style」タブで間隔とインデントを設定します。「C# 形式」タブで、インデント、改行、間隔、および折り返しの設定を調整します。

スクリプト ファイルをスタイル ガイドに準拠する必要がある場合は、いつでも次の手順を実行します。

  • Visual Studio(Windows)で、「 Edit」>「Advanced」>「Format Document 」(Ctrl + K、Ctrl + D ホットキーコード)に移動します。空白文字の形式とタブ整列だけを行いたい場合は、エディタの下部で「コードクリーンアップを実行」(Ctrl+K 、Ctrl+E) を使用することもできます。
  • Visual Studio for Mac で、編集> 形式ドキュメント (Ctrl + I ホットキー) を選択します。

Windows では、「ツール」>「インポートおよびエクスポート設定」からエディタ設定を共有することもできます。スタイル ガイドのC#コード フォーマットでファイルをエクスポートし、すべてのチーム メンバーにそのファイルをインポートさせます。

Visual Studio では、スタイルガイドに従って簡単に作業を進めることができます。フォーマットはホットキーを使用するのと同じくらい簡単になります。

注意:Visual Studio の設定をインポートおよびエクスポートする代わりに、EditorConfig ファイルを構成できます。こうすることで、異なる IDE 間でフォーマットをより簡単に共有でき、Version Control を使用するメリットも得られます。詳細については、.NET コードスタイルルールのオプションを参照してください。

これはクリーン コードに固有のものではありませんが、Visual StudioでUnityのプログラミング ワークフローをスピードアップする10の方法をご確認ください。これらの生産性向上のヒントを適用すれば、クリーンなコードの形式とリファクタリングがはるかに簡単になります。

C シャープペレンス

ウィンドウ示されます。

.editorconfig ファイルを設定する

Visual Studio コードで .editorconfig ファイルを設定するには、次の手順に従います。

  • プロジェクトのルートディレクトリに、 .editorconfig という名前の新しいファイルを作成します。
  • .editorconfig ファイルを開き、必要な設定を追加します。

C# の設定例を次に示します。

# 最上位の EditorConfig ファイル

root = true

# Unix スタイルの改行(すべてのファイルの末尾が改行)

[*]

end_of_line = lf

insert_final_newline = true

# 4 スペースインデント

[*.cs]

indent_style = space

indent_size = 4

charset = utf-8

trim_trailing_whitespace = true

# メイクファイルのタブインデント

[Makefile]

indent_style = tab

# JSON ファイル固有の設定

[*.json]

indent_style = space

indent_size = 2

コードスタイルのヒントをさらに得る

命名規則の詳細については、こちらをご覧いただくか、e ブック全文をご覧ください。詳細なコードスタイルガイド例も探ることができます。