Skip to content

15. マジックナンバーを消す

ロジックの中に直接書き込まれている数値をマジックナンバーといいます。マジックナンバーはこれが何を意味した数値であるか解読が難しく、可読性が低下します。また、もし同じマジックナンバーを複数箇所に実装すると、仕様変更時に漏れなく修正するのが難しくなります。

数値や文字列の意味を明確にするために、マジックナンバーを定数かenumとして定義しましょう。そうすれば意味が分かりやすく、変更も一括で済みます。

csharp
// ❌ Bad: マジックナンバー
void TakeDamage(int amount)
{
    hitPoint -= amount;
    if (hitPoint <= 0)
    {
        hitPoint = 0;
        Invoke("Respawn", 3);  // 3って何? 秒? フレーム?
    }

    transform.position += knockbackDirection * 0.5f;  // 0.5って何…?
}

// ✅ Good: 定数として定義
const float RespawnDelay = 3f;
const float KnockbackDistance = 0.5f;

void TakeDamage(int amount)
{
    hitPoint -= amount;
    if (hitPoint <= 0)
    {
        hitPoint = 0;
        Invoke("Respawn", RespawnDelay);
    }

    transform.position += knockbackDirection * KnockbackDistance;
}

Unityであれば、インスペクターから値を設定できるようにしておくのもよいでしょう。

csharp
// インスペクターから設定する場合
[SerializeField] float respawnDelay = 3f;
[SerializeField] float knockbackDistance = 0.5f;

複数のクラスで使われるのであれば、関連する設定値をまとめたScriptableObjectを作成し、インスペクターから注入するという方法もあります。

csharp
// ScriptableObjectで設定値をまとめる場合
[CreateAssetMenu(fileName = "PlayerSettings", menuName = "Settings/Player")]
public class PlayerSettings : ScriptableObject
{
    public float RespawnDelay = 3f;
    public float KnockbackDistance = 0.5f;
}

public class Player : MonoBehaviour
{
    [SerializeField] PlayerSettings settings;

    void TakeDamage(int amount)
    {
        // ...
        Invoke("Respawn", settings.RespawnDelay);
        transform.position += knockbackDirection * settings.KnockbackDistance;
    }
}

Unity設計講習会 資料公開ページ