【Unity】コードスタイル

Unityでスクリプトを書くコツ、綺麗に書くにはといった、一見正解がないようなものを整理して定型化したものがありますので、それを学習していきましょう

コードの書式設定

ネーミングに加えて、書式設定は当て推量を減らし、コードの明瞭さを向上させるのに役立ちます。標準化されたスタイルガイドに従うことで、コードレビューはコードがどのように見えるかではなく、それが何をするかについてより多くなります。

チームがコードをフォーマットする方法をパーソナライズすることを目指しています。Unityスタイルガイドを設定する際には、次の各コード書式設定の提案を検討してください。チームのニーズに合わせて、これらのサンプルルールを省略、展開、または変更することを選択できます。

いずれの場合も、チームが各書式設定ルールをどのように実装するかを検討し、全員に均一に適用してもらいます。不一致を解決するには、チームのスタイルガイドを参照してください。フォーマットについてあまり考えなければ、より生産的かつ創造的に働くことができます。

いくつかの書式設定ガイドラインを見てみましょう。

プロパティ

プロパティは、クラス値を読み、書き、または計算するための柔軟なメカニズムを提供します。プロパティはパブリックメンバー変数であるかのように振る舞いますが、実際にはアクセサと呼ばれる特別なメソッドです。

各プロパティには、バッキングフィールドと呼ばれるプライベートフィールドにアクセスするためのgetおよびsetメソッドがあります。このようにして、プロパティはデータをカプセル化し、ユーザーまたは外部オブジェクトによる不要な変更からデータを非表示にします。「ゲッター」と「セッター」にはそれぞれ独自のアクセス修飾子があり、プロパティを読み取り/書き込み読み取り専用、または書き込み専用にすることができます。

アクセサを使用してデータを検証または変換することもできます(たとえば、データが好みの形式に適合していることを確認したり、特定の単位に値を変更したりします)。

プロパティの構文は異なる可能性があるため、スタイルガイドではそれらをフォーマットする方法を定義する必要があります。コード内のプロパティの一貫性を維持するためのヒントについては、次の例を参照してください。

式形式のプロパティ

単一行の読み取り専用プロパティ(=>)に式形式のプロパティを使用します。これは、プライベートバッキングフィールドを返します。


// 例: 式形式のプロパティ
public class PlayerHealth
{
    // プライベートのバッキングフィールド
    private int maxHealth;

    // 読み取り専用, バッキングフィールドを戻す
    public int MaxHealth => maxHealth;

    // これと同じ:
    // public int MaxHealth { get; private set; }
}

自動実装されたプロパティ

他のすべては、expression-bodied { get; set; }構文を使用します。バッキングフィールドを指定せずにパブリックプロパティを公開したい場合は、自動実装プロパティを使用してください。

セットに式ボディの構文を適用し、アクセサを取得します。書き込みアクセスを提供したくない場合は、「セッター」を非公開にすることを忘れないでください。クロージングをマルチラインコードブロックのオープニングブレースに合わせます。

// 例: 式形式のプロパティ
public class PlayerHealth
{
    // バッキングフィールド
    private int _maxHealth;

    // ゲッターとセッターの明示的な実装
    public int MaxHealth
    {
        get => _maxHealth;
        set => _maxHealth = value;
    }

    // 書き込み専用 (バッキングフィールドを使わない)
    public int Health { private get; set; }

    // 書き込み専用, 明示的なセッターなし
    public SetMaxHealth(int newMaxValue) => _maxHealth = newMaxValue;

}

シリアル化

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

シリアル化

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

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

シリアル化されたフィールドを扱うときは、これらの基本的なガイドラインを守ってください。

  • [SerializeField] 属性を使用するSerializeField 属性は、プライベート変数または保護された変数を使用して、インスペクタに表示できます。これは、変数をパブリックにマークするよりも優れたデータをカプセル化し、外部オブジェクトがその値を上書きするのを防ぎます。
  • Range 属性を使用して、最小値と最大値を設定します[Range(min, max)] 属性は、ユーザーが数値フィールドに割り当てることができるものを制限したい場合は便利です。また、インスペクタのスライダーとしてフィールドを便利に表します。
  • シリアライズ可能なクラスまたは構造体内のデータをグループ化してインスペクタをクリーンアップする: パブリッククラスまたは構造体を定義し、[シリアライズ可能]属性でマークします。インスペクタで公開する各タイプのパブリック変数を定義します。

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

// 例: PlayerStats のシリアライズ可能なクラス

using System;
using UnityEngine;

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

// 例: プライベート・フィールドはインスペクタに表示されます

    [SerializeField]
    private PlayerStats _stats;
}

ブレースまたはインデントスタイル

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

  • BSDスタイル(BSD Unixから)とも呼ばれるオールマンスタイルは、オープニングカーリーブレースを新しい行に置きます。
  • K&Rスタイル、または「1つの真のブレーススタイル」は、前のヘッダーと同じ行にオープニングブレースを保ちます。

これらのインデントスタイルにもバリエーションがあります。このガイドの例は、Microsoftフレームワーク設計ガイドラインのAllmanスタイルを使用しています。チームとしてどちらを選択するかに関係なく、全員が同じインデントとブレーススタイルに従っていることを確認してください。次のセクションでヒントを試すこともできます。

// 例: オールマンやBSDのスタイルは、開く中括弧を新しい行に記述する

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

// 例: K&Rスタイルでは、開く中括弧を後ろに書く

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

CSharpタブ

WINDOWS用VISUAL STUDIOのタブ設定

均一なインデントを決める

インデントは通常2つまたは4つのスペースです。タブ対スペースの炎の戦争に火をつけることなく、チームの全員にエディターの好みの設定に同意してもらいましょう。

Visual Studio for Windows で、[ツール] > [オプション] > [テキスト エディタ] > [C#] > [タブ] に移動します

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

:Visual Studioは、タブをスペースに変換するオプションを提供します。

中括弧を省略しない

単行のステートメントでも、中括弧を省略しないでください。ブレースは一貫性を高め、コードの読み取りとメンテナンスを容易にします。この例では、中括弧はアクションDoSomethingをループから明確に分離しています。

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

// 例: 中括弧を明確にしておく...

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

// ...または違う行に書く
for (int i = 0; i < 100; i++)
{
    DoSomething(i);
}

// 避ける: 中括弧の省略

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

複数行のステートメントを明確にするためにブレースを保つ

ネストされた複数行のステートメントから中括弧を削除しないでください。この場合、ブレースを削除してもエラーは発生しませんが、混乱を招く可能性があります。オプションであっても、明確にするために中括弧を適用します。

// 例: 中括弧を明確にしておく

for (int i = 0; i < 10; i++)
{
	for (int j = 0; j < 10; j++)
     {
		ExampleAction();
     }
}
// 避ける: 入れ子になった複数行のステートメントから中括弧を削除する

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

スイッチ文を標準化する

フォーマットは異なる場合がありますので、チームの好みをスタイルガイドに記録し、それに応じてスイッチステートメントを標準化してください。

ケースステートメントをインデントする1つの例を次に示します。

// 例: switchステートメントからcaseをインデントする
switch (someExpression) 
{
   case 0:
      DoSomething();
      break;
   case 1:
      DoSomethingElse();
      break;
   case 2: 
      int n = 1;
      DoAnotherThing(n);
      break;
}

空白の考え方

スペースのような単純なものは、画面上のコードの外観を高めることができます。個人的な書式設定の好みは異なる場合がありますが、読みやすさを向上させるために以下の提案を検討してください。

スペースを追加する

コード密度を減らすためにスペースを追加します。余分な空白は、線の一部間の視覚的な分離の感覚を与えます。

// 例: 行を読みやすくするためにスペースを入れる
for (int i = 0; i < 100; i++) { DoSomething(i); }

// 避ける: スペースがない
for(inti=0;i<100;i++){DoSomething(i);}

コンマの後の間隔

関数引数の間にコンマの後に単一のスペースを使用します。

// 例: 引数間のカンマの後に半角スペースを入れる
CollectItem(myObject, 0, 1);

// 避ける:
CollectItem(myObject,0,1);

括弧の後にスペースなし

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

// 例: 括弧とメソッド引数の後にスペースを入れない
DropPowerUp(myPrefab, 0, 1);

//避ける:
DropPowerUp( myPrefab, 0, 1 );

関数と括弧の間にスペースがない

関数名と括弧の間にスペースを使用しないでください。

// 例: メソッド名と括弧の間のスペースは省略する
DoSomething()

// AVOID:
DoSomething ()

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

可能な限り、中括弧内のスペースを避けてください。

// 例: 括弧内のスペースは省略する
x = dataArray[index];

// AVOID:
x = dataArray[ index ];

フロー制御前の間隔

フロー制御条件の前に単一のスペースを使用し、フロー比較演算子と括弧の間にスペースを追加します。

// 例: 括弧はスペースで区切る
while (x == y)

// 避ける:
while(x==y)

比較演算子との間隔

比較演算子の前後に単一のスペースを使用します。

// 例: 括弧はスペースで区切る
if (x == y)
// 避ける:
if (x==y)

読みやすさのヒント

行を短くし、水平方向の空白を考慮してください。標準的な行幅(80〜120文字)を決定し、長い行をオーバーフローさせるのではなく、小さなステートメントに分割します。

先に説明したように、インデント/階層を維持するようにしてください。コードをインデントすると、読みやすさが向上します。

読みやすさのために必要でない限り、列の配置を使用しないでください。このタイプの間隔は変数を整列させますが、タイプと名前のペアリングを複雑にする可能性があります。

ただし、列のアライメントは、多くのデータを持つビット単位の式や構造体に役立ちます。より多くのアイテムを追加すると、列の配置を維持するための作業が増える可能性があることに注意してください。一部の自動フォーマットは、列のどの部分が整列されるかを変更することもあります。

// 例: 種類と名前の間に1スペース

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

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

// 避ける: 列を揃える

    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ディレクティブは不要でなければなりません。コードブロックをリージョンの後ろに隠すのではなく、コードを小さなクラスに分割します。ソースファイルが短い場合、リージョンを追加する傾向が低くなります。

:多くの開発者は、地域をコード臭いやアンチパターンだと考えています。議論のどちら側に落ちるかをチームとして決めてください。

CSharpの設定

プレビューウィンドウには、スタイルガイドの選択が表示されます。

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

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

スクリプトエディタの書式設定ルールを設定するには:

  • Visual Studio for Windowsで、[ツール] > [オプション] に移動し、[テキスト エディタ] > [C#] > [コード スタイル フォーマット] を見つけます。
    • 設定を使用して、一般インデント新しい行間隔、および折り返しオプションを変更します。
  • Visual Studio for Mac で、Visual Studio > Preferences を選択し、[ソースコード] > [コードの書式設定] > [C# ソースコード] に移動します。
    • 上部のポリシーを選択し、[テキストスタイル]タブに移動します。C#フォーマットタブで、インデント新しい行間隔、およびラッピング設定を調整します。

スクリプトファイルをスタイルガイドに強制的に従うには:

  • Windows 用 Visual Studio で、[編集] > [詳細設定] > [ドキュメントのフォーマット] (Ctrl + K、Ctrl + D ホットキーコード) に移動します。空白とタブの配置のみをフォーマットしたい場合は、エディタの下部にある実行コードクリーンアップ(Ctrl + K、Ctrl + E)を使用することもできます。
  • Visual Studio for Macで、[編集] > [ドキュメントのフォーマット] (Ctrl + I ホットキー) に移動します。

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

Visual Studioは、スタイルガイドに従うのに役立ちます。その後、フォーマットはホットキーを使用するのと同じくらい簡単になります。

注: Visual Studio 設定をインポートおよびエクスポートする代わりに、EditorConfig ファイル (上記参照) を設定できます。これにより、異なるIDE間でフォーマットの共有が容易になります。また、バージョン管理を操作するという追加の利点もあります。を参照してください詳細については、NETコードスタイルのルールオプションを参照してください。

これはコードのクリーンアップに固有のものではありませんが、Visual Studioを使用してUnityでプログラミングワークフローを高速化する10の方法を必ず確認してください。これらの生産性のヒントを適用すると、クリーンなコードをフォーマットしてリファクタリングする方が便利であることを覚えておいてください。

参考

引用元になります

コードでまとめたもの

// スタイルシートの例
// - これは、あなたのUnityプロジェクトで使用するためのスタイルガイドの例です。
// - チームの好みに合わせて、これらのルールを省略したり追加したりしてください。
// - スタイルガイドの例を参考にしてください:
// - Microsoftのフレームワークデザインガイドラインはこちら: https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/
// - Googleもスタイルガイドをここで管理しています: https://google.github.io/styleguide/csharp-style.html

// - これらのルールをカスタマイズして、チーム独自のスタイルガイドを作成し、一貫して適用する。
// - 疑問がある場合は、チームのスタイルガイドを優先すること。

// 命名/ケーシング:
// - 特に断りのない限り、パスカルケース(例:ExamplePlayerController、MaxHealthなど)を使用する。
// - ローカル/プライベート変数、パラメータにはキャメルケース(examplePlayerController、maxHealthなど)を使用する。
//  -スネークケース、ケバブケース、ハンガリー記法は避ける。
// - ファイル内にMonobehaviourがある場合、ソースファイル名を一致させること


// フォーマット:
// - K&R(同じ行で中括弧を開く)またはオールマン(改行で中括弧を開く)スタイルの中括弧を選択する。
// - 行を短くする。水平方向の空白を考慮する。スタイルガイドで標準的な行の幅を定義する(80~120文字)。
// - フロー制御条件の前に半角スペースを入れる 例:while (x == y)。
// - 括弧の中にはスペースを入れない。例;x = dataArray[index]
// - 関数の引数間のカンマの後には半角スペースを使用する。
// - 括弧と関数引数の後にスペースを追加しないでください。例えば、CollectItem(myObject, 0, 1);
// - 関数名と括弧の間にスペースを使用しない。例:DropPowerUp(myPrefab, 0, 1);
// - 視覚的に区切るために、縦の間隔(余分な空白行)を使用する。

// コメント
// - 単に "何を"、"どのように "と答えるのではなく、コメントによってギャップを埋め、"なぜ "なのかを伝えることができる。
// - コメントを使用して、ロジックの隣に説明を置いてください。
// - シリアライズされたフィールドには、コメントの代わりにツールチップを使用してください。
// - リージョンは避けてください。大きなクラスサイズを助長します。折りたたまれたコードは読みにくくなります。
// - 法的な情報やライセンスについては、外部リファレンスへのリンクを使用してスペースを節約してください。
// - パブリック・メソッドや関数の前にサマリーXMLタグを記述して、ドキュメントやインテリセンスを出力する。


// 行を使用する:
// - ファイルの先頭にusing行を残す。
// - 未使用行を削除する。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

// NAMESPACES:
// - 特殊記号やアンダースコアは使わない。
// - 名前空間を繰り返し入力しないように、先頭に使用行を追加する。
// - 例えば、MyApplication.GameFlow、MyApplication.AIなど。
namespace StyleSheetExample
{

    // 列挙型:
    // - 単数形の型名を使用する。
    // - 接頭辞や接尾辞は付けない。
    public enum Direction
    {
        North,
        South,
        East,
        West,
    }

    // フラグ列挙:
    // - 複数形の型名を使う 
    // - 接頭辞や接尾辞は付けない。
    // - バイナリ値にはカラムアライメントを使用する。
    [Flags]
    public enum AttackModes
    {
        // Decimal                         // Binary
        None = 0,                          // 000000
        Melee = 1,                         // 000001
        Ranged = 2,                        // 000010
        Special = 4,                       // 000100

        MeleeAndSpecial = Melee | Special  // 000101
    }

    // インターフェイス:
    // - インターフェースには形容詞句を付ける。
    // - I' 接頭辞を使用する。
    public interface IDamageable
    {
        string damageTypeName { get; }
        float damageValue { get; }

        // メソッド:
        // メソッド名は、動作を示す動詞または動詞句で始めます。
        // パラメータ名はキャメルケースで指定します。
        bool ApplyDamage(string description, float damage, int numberOfHits);
    }

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

    // クラスまたは構造体:
    // - 名詞または名詞句で名前を付ける。
    // - 接頭辞は避ける。
    // - 1つのファイルに1つのMonobehaviour。ファイル内にMonobehaviourがある場合、ソースファイル名が一致していなければなりません。
    public class StyleExample : MonoBehaviour
    {

        // フィールド: 
        // - 特殊文字(バックスラッシュ、記号、Unicode文字)は避けること。 コマンドラインツールと干渉する可能性がある。
        // - 名前には名詞を使いますが、ブーリアンには動詞を前置します。
        // - 意味のある名前を使う。検索しやすく、発音しやすい名前にする。数学でない限り)省略しない。
        // - パブリック・フィールドにはパスカル・ケースを使用する。プライベート変数にはキャメルケースを使用する。
        // - ローカル変数と区別するために、プライベートフィールドの前にアンダースコア (_) を追加します。
        // - より明示的な接頭辞を使用することもできます。 m_ = メンバ変数, s_ = スタティック, k_ = コンスタント 
        // - デフォルトのアクセス修飾子を指定する(あるいは省略する)。

        private int _elapsedTimeInDays;

        // インスペクタにプライベート・フィールドを表示するには、[SerializeField] 属性を使用します。
        // ブーリアンは、true または false で答えられる質問をします。
        [SerializeField] private bool _isPlayerDead;

        // これは、カスタムPlayerStatsクラスのデータをInspectorにグループ化します。
        [SerializeField] private PlayerStats _stats;

        // これにより、値が範囲に制限され、インスペクタにスライダが作成されます。
        [Range(0f, 1f)][SerializeField] private float _rangedStat;

        // ツールチップは、直列化されたフィールドのコメントを置き換えることができ、二重の役割を果たす
        [Tooltip("This is another statistic for the player.")]
        [SerializeField] private float _anotherStat;


        // プロパティ:
        // - public フィールドが望ましい。
        // - 特殊文字は使用しない。
        // - 短くするために式本体化プロパティを使用するが、好みの形式を選択する。
        // - 例えば、読み取り専用のプロパティには式修飾を使用し、それ以外には { get; set; } を使用します。
        // - バッキング・フィールドのないパブリック・プロパティには、自動実装プロパティを使用してください。

        // プライベートバッキングフィールド
        private int _maxHealth;

        // 読み取り専用、バッキングフィールドを返す
        public int MaxHealthReadOnly => _maxHealth;

        // 次と同等です
        // public int MaxHealth { get; private set; }

        // ゲッターとセッターの明示的な実装
        public int MaxHealth
        {
            get => _maxHealth;
            set => _maxHealth = value;
        }

        // 書き込み専用(バッキングフィールドを使用しない)
        public int Health { private get; set; }

        // 書き込み専用、明示的なセッターなし
        public void SetMaxHealth(int newMaxValue) => _maxHealth = newMaxValue;

        // バッキング・フィールドのない自動実装プロパティ
        public string DescriptionName { get; set; } = "Fireball";


        // EVENTS:
        // - 動詞句で名前を表す。
        // - 現在の行動は "before "を意味し、過去の行動は "after"を意味する。
        // - ほとんどのイベントにはSystem.Actionデリゲートを使用する(0~16個のパラメータを取ることができる)。
        // - 必要な場合のみ、カスタムEventArgを定義する(System.EventArgsまたはカスタム構造体)。
        // - あるいは、System.EventHandlerを使用します。
        // - イベント、イベント処理メソッド(サブスクライバ/オブザーバ)、イベント発生メソッド(パブリッシャ/サ ブジェクト)の命名スキームを選択します。
        // 例えば、イベント/アクション = "OpeningDoor"、イベント発生メソッド = "OnDoorOpened"、イベント処理メソッド = "MySubject_DoorOpened" など。

        // event before
        public event Action OpeningDoor;

        // event after
        public event Action DoorOpened;

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

        // これらは、OnDoorOpenedやOnPointsScoredなどのイベント発生メソッドである。
        public void OnDoorOpened()
        {
            DoorOpened?.Invoke();
        }

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

        // これは構造体から作られたカスタムEventArgです。
        public struct CustomEventArgs
        {
            public int ObjectID { get; }
            public Color Color { get; }

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


        // メソッド:
        // - メソッド名は、動作を示す動詞または動詞句で始める。
        // - パラメータ名はキャメルケースで指定します。

        // メソッドは動詞で始まります。
        public void SetInitialPosition(float x, float y, float z)
        {
            transform.position = new Vector3(x, y, z);
        }

        // メソッドはブールを返すとき、疑問形にする
        public bool IsNewPosition(Vector3 newPosition)
        {
            return (transform.position == newPosition);
        }

        private void FormatExamples(int someExpression)
        {
            // VAR:
            // - 特に長い型名では、可読性を高めるために var を使う。
            // - 型が曖昧になる場合は var を使わない。
            var powerUps = new List<PlayerStats>();
            var dict = new Dictionary<string, List<GameObject>>();


            // switch文:
            // - 書式はさまざまです。あなたのスタイル・ガイドに合ったものを選び、それに従いましょう。
            // - この例では、各ケースとその下のブレークをインデントしています。
            switch (someExpression)
            {
                case 0:
                    // ..
                    break;
                case 1:
                    // ..
                    break;
                case 2:
                    // ..
                    break;
            }

            // 中括弧: 
            // - 単一行ステートメントを使用する場合は、わかりやすくするために中括弧を使用する。
            // - あるいは、デバッグしやすくするために単一行文を完全に避ける。
            // - 入れ子になった複数行のステートメントでは中括弧を保持する。

            // この1行のステートメントでは、中括弧を...
            for (int i = 0; i < 100; i++) { DoSomething(i); }

            // ...しかし、この方がデバッグしやすい。節にブレークポイントを設定できる。
            for (int i = 0; i < 100; i++)
            {
                DoSomething(i);
            }

            // ここで中括弧を外してはいけない。
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    DoSomething(j);
                }
            }
        }

        private void DoSomething(int x)
        {
            // .. 
        }
    }
    // その他のクラス
    // - 必要なだけ、他のヘルパー/Monobehaviourではないクラスを定義します。
    // - これは、Inspector のフィールドをグループ化するシリアライズ可能なクラスです。
    [Serializable]
    public struct PlayerStats
    {
        public int MovementSpeed;
        public int HitPoints;
        public bool HasHealthPotion;
    }

}

C#,Unity

Posted by hidepon