Unityにおけるクラス整理と標準化ガイドライン

本資料は、Unity開発におけるクラスの整理方法と標準化の重要性について説明しています。以下のガイドラインは、コードの可読性、保守性、チーム間の共有認識向上を目的としており、Unity公式の推奨事項に基づいています。


1. クラスメンバーのグループ化とその効果

1.1 グループ化するセクション

  • フィールド
  • プロパティ
  • イベント / デリゲート
  • MonoBehaviour メソッド
    (Awake、Start、OnEnable、OnDisable、OnDestroy など)
  • public メソッド
  • private メソッド

1.2 グループ化の意図と効果

  • 可読性の向上: 明確な区分により、クラス内の各メンバーの役割が一目で理解でき、コードレビューや新規参入者の理解が容易になります。
  • 保守性の向上: 機能ごとにメソッドや変数が整理されることで、変更や拡張時の影響範囲を限定し、エラーの発生を抑えます。
  • 責務の分離: クラスが果たすべき役割や責務が明確になり、内部ロジックの整理と再利用性が向上します。

2. 各グループの役割と用途

グループ役割・用途備考・推奨事項
フィールドクラスの状態保持用。通常は private または [SerializeField] を使用。初期値設定やシリアル化のため、コメントを併用すると明確になります。
プロパティ内部状態の安全な外部アクセス手段。外部へのインターフェースとして機能し、publicprotected を利用します。
イベント / デリゲート通知やコールバック機能の実装。イベント駆動設計を明確にし、外部依存を軽減する役割があります。
MonoBehaviour メソッドUnityのライフサイクルに沿った動作(例: Awake、Start、Update 等)。ライフサイクルメソッドを明確に分けることで、各処理のタイミングや役割が把握しやすくなります。
public メソッド外部に公開する機能やインターフェースの実装。クラスが担う責務や機能を外部に示し、他クラスとの連携を実現します。
private メソッドクラス内部の処理ロジック。内部でのみ使用する処理を集約し、複雑な依存関係を避けるために役立ちます。

3. MonoBehaviourの命名規則とファイル構造

3.1 クラス名とファイル名の一致

  • 必須事項: スクリプトファイル名は、ファイル内の MonoBehaviour クラス名と完全に一致する必要があります。
  • 理由: 一致しない場合、Unityエディタ上でエラーや警告が発生する可能性があるため、厳守が求められます。

3.2 1ファイル1 MonoBehaviourの原則

  • 基本方針: 1つのファイルに1つの MonoBehaviour を含める。
  • 補足: 内部クラスが必要な場合でも、補助的な役割として扱い、メインとなる MonoBehaviour は1ファイルに1つのみとする。

3.3 命名規則の具体例

  • 命名規則: PascalCase(UpperCamelCase)を採用し、クラス名は意味が明確になるように命名する。
    例:
  public class PlayerController : MonoBehaviour {}
  public class EnemySpawner : MonoBehaviour {}

4. コーディング例

以下は、上記の整理方法および標準化ルールを適用した具体的なコード例です。

using UnityEngine;
using UnityEngine.Events;

public class PlayerController : MonoBehaviour
{
    // フィールド
    [SerializeField] private float speed = 5f;
    private Rigidbody rb;

    // プロパティ
    public bool IsGrounded { get; private set; }

    // イベント / デリゲート
    public UnityEvent OnJump;

    // MonoBehaviour メソッド
    private void Awake()
    {
        rb = GetComponent<Rigidbody>();
    }

    private void Start()
    {
        IsGrounded = true;
    }

    private void Update()
    {
        HandleMovement();
        if (Input.GetButtonDown("Jump") && IsGrounded)
        {
            Jump();
        }
    }

    private void OnCollisionEnter(Collision collision)
    {
        CheckGrounded(collision, true);
    }

    private void OnCollisionExit(Collision collision)
    {
        CheckGrounded(collision, false);
    }

    // public メソッド
    public void ResetPlayer()
    {
        transform.position = Vector3.zero;
        rb.velocity = Vector3.zero;
        IsGrounded = true;
    }

    // private メソッド
    private void HandleMovement()
    {
        float h = Input.GetAxis("Horizontal");
        float v = Input.GetAxis("Vertical");
        Vector3 movement = new Vector3(h, 0, v) * speed;
        rb.AddForce(movement);
    }

    private void Jump()
    {
        rb.AddForce(Vector3.up * 5f, ForceMode.Impulse);
        OnJump?.Invoke();
        IsGrounded = false;
    }

    private void CheckGrounded(Collision collision, bool groundedState)
    {
        if (collision.gameObject.CompareTag("Ground"))
        {
            IsGrounded = groundedState;
        }
    }
}

5. まとめと注意点

  • 標準化のメリット:
    この整理方法と命名規則は、コードの保守性、再利用性、チーム間の連携向上に直結します。
  • 新規メンバーへの配慮:
    明確なガイドラインにより、プロジェクト参加者全員が一貫したコードスタイルを理解し、迅速に作業を進めることが可能になります。
  • 長期的なプロジェクト管理:
    プロジェクトが拡大しても、標準化されたコード構造は、将来的な機能拡張や変更に柔軟に対応できる基盤を提供します。

以上のガイドラインをプロジェクト開始時から実施することで、効率的で品質の高いUnity開発を実現できます。

Unity

Posted by hidepon