👋

【7ルール】Unity C#による柔軟なロジック分離テクニック

2025/03/02に公開

閲覧いただきありがとうございます。はじめまして、ゲーム開発所RYURYUの「りゅうや」と申します。

❏ ゲーム開発ランキング【 1位 】実績多数 (ココナラ)
❏ ココナラ総販売【 220件超 】
❏ GC甲子園2022・東京ゲームショウ2023など出展経験あり

■ まずはこの教材でUnity開発の第一歩を体験してください! 今すぐ購入する
https://zenn.dev/ryuryu_game/books/fd28de9d8e963a/viewer/0570af

■ 記事に関するご質問やご意見は、Discordサーバーまでお寄せください。
https://discord.gg/5FwuKCacNy

【7ルール】Unity C#による柔軟なロジック分離テクニック

Unityでのゲーム開発において、コードの可読性や保守性を高めるためには、ロジックの分離が不可欠です。適切にロジックを分離することで、開発効率の向上やバグの減少、チーム開発時の協働作業がスムーズになります。本記事では、Unity C#における柔軟なロジック分離テクニックを7つのルールに分けて解説します。各ルールには具体的な実装例や注意点も含まれているため、初心者から中級者まで幅広く活用できます。

1. シングルトンパターンの適切な使用

シングルトンパターンとは

シングルトンパターンは、クラスのインスタンスを1つだけ作成し、グローバルにアクセス可能にするデザインパターンです。Unityでは、ゲーム全体で共有するデータや管理者クラスに適用されることが多いです。

実装例

Singleton.cs
using UnityEngine;

public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
    private static T instance;

    public static T Instance
    {
        get
        {
            if (instance == null)
            {
                // シーン内に存在しない場合、新たに作成
                GameObject singletonObject = new GameObject(typeof(T).Name);
                instance = singletonObject.AddComponent<T>();
                DontDestroyOnLoad(singletonObject);
            }
            return instance;
        }
    }
}

使用方法

GameManager.cs
public class GameManager : Singleton<GameManager>
{
    public int score;

    public void AddScore(int value)
    {
        score += value;
        Debug.Log("スコア: " + score);
    }
}

メリット・デメリット

  • メリット

    • 汎用的にインスタンスを管理できる
    • グローバルアクセスが容易
  • デメリット

    • 過度な使用は依存関係を増やし、テストが困難に
    • 複数のシーンで管理が複雑化する可能性

2. イベントシステムの活用

イベントシステムとは

イベントシステムを活用することで、オブジェクト間の通信を疎結合に保つことができます。これにより、コンポーネント間の依存関係を減らし、コードの再利用性が向上します。

実装例

EventManager.cs
using System;
using UnityEngine;

public class EventManager : MonoBehaviour
{
    public static EventManager Instance;

    private void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
    }

    public event Action OnGameStart;

    public void GameStart()
    {
        OnGameStart?.Invoke();
    }
}

イベントの登録と呼び出し

Player.cs
using UnityEngine;

public class Player : MonoBehaviour
{
    private void OnEnable()
    {
        EventManager.Instance.OnGameStart += HandleGameStart;
    }

    private void OnDisable()
    {
        EventManager.Instance.OnGameStart -= HandleGameStart;
    }

    private void HandleGameStart()
    {
        // ゲーム開始時の処理
        Debug.Log("ゲームが開始されました!");
    }
}

メリット・デメリット

  • メリット

    • コンポーネント間の結びつきを緩められる
    • イベント駆動型の柔軟な設計が可能
  • デメリット

    • イベントの管理が煩雑になりがち
    • デバッグが難しくなる場合も

イベントシステムの活用図解

コンポーネント 役割
EventManager イベントの発行元
Player イベントを受け取る側
UIManager イベントを受け取る側

3. インターフェースによる依存性の注入

インターフェースとは

インターフェースを使用することで、具体的な実装に依存せずに機能を利用できるようになります。これにより、コンポーネント間の独立性が高まり、テストや拡張が容易になります。

実装例

IEnemy.cs
public interface IEnemy
{
    void TakeDamage(int amount);
}
Enemy.cs
using UnityEngine;

public class Enemy : MonoBehaviour, IEnemy
{
    public int health = 100;

    public void TakeDamage(int amount)
    {
        health -= amount;
        Debug.Log("ダメージを受けた。現在の体力: " + health);
        if (health <= 0)
        {
            Die();
        }
    }

    private void Die()
    {
        Debug.Log("敵が倒れた!");
        Destroy(gameObject);
    }
}
PlayerAttack.cs
using UnityEngine;

public class PlayerAttack : MonoBehaviour
{
    public IEnemy enemy;

    private void Start()
    {
        enemy = FindObjectOfType<Enemy>();
    }

    public void Attack()
    {
        enemy.TakeDamage(25);
    }
}

メリット・デメリット

  • メリット

    • コンポーネントの交換や拡張が容易
    • テスト時にモックを使用しやすい
  • デメリット

    • インターフェースの設計が複雑になる場合も
    • 過度な使用はコードの可読性を損なう可能性

インターフェースの依存性注入図解

4. ScriptableObjectを利用したデータ管理

ScriptableObjectとは

ScriptableObjectは、Unityにおけるデータ管理のための軽量なオブジェクトです。データをアセットとして保存できるため、データ駆動型の開発が可能になります。

実装例

WeaponData.cs
using UnityEngine;

[CreateAssetMenu(fileName = "WeaponData", menuName = "ScriptableObjects/WeaponData", order = 1)]
public class WeaponData : ScriptableObject
{
    public string weaponName;
    public int damage;
    public float range;
}

ScriptableObjectの利用方法

WeaponDataアセット

Weapon.cs
using UnityEngine;

public class Weapon : MonoBehaviour
{
    public WeaponData weaponData;

    public void Attack()
    {
        Debug.Log($"{weaponData.weaponName}で攻撃! ダメージ: {weaponData.damage}");
    }
}

メリット・デメリット

  • メリット

    • データの再利用性が高い
    • デザイナーとの協働が容易
  • デメリット

    • データの可視化が複雑になる場合も
    • 適切な管理が求められる

ScriptableObjectの利点テーブル

利点 説明
データの再利用性 複数のオブジェクトで同じデータを使用可能
データ駆動型の開発 データ中心の設計が容易
デザイナーとの協働効率 データの編集がアセット経由で可能

5. MVP/MVVMパターンの導入

MVP/MVVMパターンとは

MVP(Model-View-Presenter)やMVVM(Model-View-ViewModel)パターンは、UIロジックとビジネスロジックを分離するための設計パターンです。これにより、各コンポーネントの責任範囲が明確になり、テストや保守が容易になります。

実装例

IView.cs
public interface IView
{
    void SetPresenter(Presenter presenter);
}
Presenter.cs
public class Presenter
{
    private IView view;
    private Model model;

    public Presenter(IView view, Model model)
    {
        this.view = view;
        this.model = model;
        this.view.SetPresenter(this);
    }

    public void UpdateData(string data)
    {
        model.Data = data;
        view.DisplayData(model.Data);
    }
}
Model.cs
public class Model
{
    public string Data { get; set; }
}
UIView.cs
using UnityEngine;
using UnityEngine.UI;

public class UIView : MonoBehaviour, IView
{
    public Text displayText;
    private Presenter presenter;

    public void SetPresenter(Presenter presenter)
    {
        this.presenter = presenter;
    }

    public void OnButtonClick()
    {
        presenter.UpdateData("新しいデータ");
    }

    public void DisplayData(string data)
    {
        displayText.text = data;
    }
}

メリット・デメリット

  • メリット

    • UIとロジックの分離で再利用性向上
    • テストが容易になる
  • デメリット

    • 設計が複雑化する可能性
    • 初期設定に手間がかかる

6. レイヤードアーキテクチャの採用

レイヤードアーキテクチャとは

レイヤードアーキテクチャは、アプリケーションを複数の層(レイヤー)に分割し、それぞれの層が特定の責任を持つ設計手法です。一般的には、プレゼンテーション層、ビジネスロジック層、データアクセス層などに分かれます。

レイヤー構成例

レイヤー 役割
プレゼンテーション層 ユーザーインターフェースの管理
ビジネスロジック層 アプリケーションのビジネスロジックを処理
データアクセス層 データの取得・保存・管理を担当
インフラ層 外部サービスやハードウェアとの通信を管理

メリット・デメリット

  • メリット

    • 各レイヤーの役割が明確になる
    • 再利用性や拡張性が向上
  • デメリット

    • レイヤー間の通信が複雑になることがある
    • オーバーヘッドが増加する可能性

レイヤードアーキテクチャの実装例テーブル

レイヤー 使用するクラス・コンポーネント
プレゼンテーション層 UIView, PlayerController
ビジネスロジック層 GameManager, InventorySystem
データアクセス層 DatabaseManager, APIClient
インフラ層 NetworkManager, HardwareInterface

7. 単一責任原則の徹底

単一責任原則とは

単一責任原則(Single Responsibility Principle, SRP)は、クラスやモジュールが一つの責任のみを持つべきであるという原則です。これにより、クラスの変更点が少なくなり、再利用性や保守性が向上します。

実装例

PlayerController.cs
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public float moveSpeed = 5f;
    private Rigidbody rb;

    private void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    private void Update()
    {
        Move();
    }

    private void Move()
    {
        float moveX = Input.GetAxis("Horizontal");
        float moveZ = Input.GetAxis("Vertical");
        Vector3 movement = new Vector3(moveX, 0, moveZ) * moveSpeed * Time.deltaTime;
        rb.MovePosition(transform.position + movement);
    }
}
PlayerHealth.cs
using UnityEngine;

public class PlayerHealth : MonoBehaviour
{
    public int maxHealth = 100;
    private int currentHealth;

    private void Start()
    {
        currentHealth = maxHealth;
    }

    public void TakeDamage(int amount)
    {
        currentHealth -= amount;
        Debug.Log("プレイヤーの体力: " + currentHealth);
        if (currentHealth <= 0)
        {
            Die();
        }
    }

    private void Die()
    {
        Debug.Log("プレイヤーが死亡しました。");
        // 死亡処理
    }
}

メリット・デメリット

  • メリット

    • クラスがシンプルで理解しやすくなる
    • 変更が容易になり、影響範囲が限定される
  • デメリット

    • クラス数が増加し、管理が煩雑になる場合も
    • 過度な分割は逆に可読性を損なうことも

クラスの単一責任原則図解

まとめ

Unity C#における柔軟なロジック分離は、プロジェクトの成長とともにコードの保守性や拡張性を高めるために不可欠です。本記事で紹介した7つのルールを適用することで、効率的な開発と高品質なゲーム制作が実現できます。

  • シングルトンパターンでインスタンス管理を一元化
  • イベントシステムでコンポーネント間の疎結合を実現
  • インターフェースで依存性を注入し、テスト性を向上
  • ScriptableObjectでデータ駆動型の開発を促進
  • MVP/MVVMパターンでUIとロジックの分離を徹底
  • レイヤードアーキテクチャで責任範囲を明確化
  • 単一責任原則でクラスのシンプル化

これらのテクニックを駆使し、堅牢で拡張性の高いUnityプロジェクトを構築しましょう。

Unityをもっと極めたい"あなた"へ ― 今すぐスキルアップのチャンス!

1. どこでもUnity教室「無料プラン」

❏ 毎日の質問で即解決|Unityに関する疑問や悩みは、専用Discordでプロの仲間とシェア!

  • 月額0円 で、テキストで気軽に質問・進捗共有が可能
  • 実績多数のコミュニティで、参加するだけで具体的な課題解決のヒントが手に入る

まずは無料で参加して、あなたのUnity学習を加速させましょう! 無料でDiscordに参加する]
https://discord.gg/5FwuKCacNy

2. Unity超入門書【1,000円】

Unityスキルを5日間でマスター|「実践×即戦力」を手に入れる!

  • 130,000文字超の詳細な解説と実例で、初心者でもすぐにUnityの基礎が身につく
  • 実際の成果例:5日間でシンプルな3D FPSゲームを完成
  • 専属講師サポートのオプション付きで、疑問を即解消しながら学習を進められる

まずはこの教材でUnity開発の第一歩を体験してください! 教材を今すぐ購入する
https://zenn.dev/ryuryu_game/books/fd28de9d8e963a/viewer/0570af

3.「 Unity超入門」完全支援プラン

Unityの全てをプロがバックアップ|教材で学んだ内容を実践サポート!

  • 専属講師による24時間テキスト質問サポート(毎日17:00~21:00の回答)
  • 月2回×60分 または 月1回×120分のビデオチャットで、学習進捗やプロジェクトの具体的な課題を徹底サポート
  • 教材と連携し、実践の現場での疑問や課題をそのまま解決!
  • 限定:1度に最大10名様のみ受付!早期申込で安心のサポート体制を

教材で学んだ知識をさらに深め、実践に活かすならこのプランがおすすめです! 今すぐ詳細を確認する
https://ryuryu.memberpay.jp/service/item/yjo1sst

4. Unityプロジェクト完全支援プラン

Unityプロジェクトを本格サポート|個人の趣味からプロの現場まで幅広く対応!

  • 専属講師による24時間テキスト質問サポート(毎日17:00~21:00の回答)
  • 月2回×60分のビデオチャットで、プロジェクトの進行状況を細かくサポート
  • Unity開発の一部を代行するサービスが常に20%割引で利用可能
  • 基本操作からエラー対応、プロジェクト設計のアドバイスまで幅広くサポート
  • 専用Discordサーバーでのサポート体制(ご購入後に招待リンクを送付)

個人プロジェクトを着実に進め、より高い成果を求めるあなたに最適なプランです! 今すぐプロジェクト支援プランを確認する
https://ryuryu.memberpay.jp/plan/item/epeiywt

Discussion