メソッドを作ろう:処理に名前を付けてまとめる【Unityスタートガイド6-6】

スクリプトが長くなってくると、「どこで何をしているのか」が分かりにくくなってきます。そんなときは、処理のまとまりに名前を付けて分けましょう。それがメソッド(関数)です!今回は自分でメソッドを作って呼び出す方法と、引数・戻り値の使い方をご紹介します。

目次

この記事で学べること

  • メソッド(関数)とは何か
  • メソッドの作り方と呼び出し方
  • 引数(ひきすう)でメソッドに値を渡す方法
  • 戻り値でメソッドから結果を受け取る方法

前提知識

メソッドとは?

実はもう使っている

これまで書いてきたStart()やUpdate()も、実はメソッドです。Unityが決まったタイミングで呼んでくれる、特別なメソッドでした。

  • Start():Unityが最初に1回呼んでくれる
  • Update():Unityが毎フレーム呼んでくれる
  • Debug.Log():Unityが用意してくれているメソッドを、自分で呼んでいる

今回は、自分でメソッドを作って、自分で呼ぶ方法を覚えます。

メソッドを作るメリット

  • 名前で内容が分かる:TakeDamage()と書いてあれば「ダメージを受ける処理」だと分かる
  • 何度でも使える:同じ処理を何か所にも書かなくてよい
  • 直すのが楽:処理を変えたいときは、メソッドの中を1か所直すだけ

メソッドの作り方と呼び出し方

一番シンプルなメソッド

using UnityEngine;

public class MethodExample : MonoBehaviour
{
    void Start()
    {
        SayHello();   // メソッドを呼び出す
        SayHello();   // 何度でも呼べる
    }

    // メソッドを作る
    void SayHello()
    {
        Debug.Log("こんにちは!");
    }
}

実行結果:

こんにちは!
こんにちは!

メソッドの書き方:

戻り値の型 メソッド名()
{
    まとめたい処理
}
  • void:「何も返さない」という意味(戻り値は後で説明します)
  • メソッド名は、大文字から始めて何をするか分かる名前にするのがC#の習慣です(SayHello、TakeDamage)
  • 呼び出すときはメソッド名();と書きます

引数:メソッドに値を渡す

「10ダメージ」「25ダメージ」のように、呼ぶたびに少し違う値で処理したいことがあります。そんなときは引数(ひきすう)を使います。

using UnityEngine;

public class DamageExample : MonoBehaviour
{
    [SerializeField] private int hp = 100;

    void Start()
    {
        TakeDamage(10);   // 10を渡す
        TakeDamage(25);   // 25を渡す
    }

    // int型の値を1つ受け取るメソッド
    void TakeDamage(int damage)
    {
        hp -= damage;
        Debug.Log(damage + "のダメージ!残りHP " + hp);
    }
}

実行結果:

10のダメージ!残りHP 90
25のダメージ!残りHP 65
  • (int damage)の部分が引数。呼び出したときに渡した値が、damageという変数に入ります
  • 引数は、カンマで区切って複数にできます
void ShowStatus(string playerName, int level)
{
    Debug.Log(playerName + " レベル" + level);
}

// 呼び出し
ShowStatus("勇者", 5);

戻り値:メソッドから結果を受け取る

計算した結果を、呼び出した側で使いたいこともあります。そのときは戻り値を使います。

using UnityEngine;

public class ReturnExample : MonoBehaviour
{
    void Start()
    {
        int damage = CalculateDamage(20, 5);
        Debug.Log("ダメージは " + damage);

        if (IsCritical(95))
        {
            Debug.Log("クリティカルヒット!");
        }
    }

    // 攻撃力と防御力から、ダメージを計算して返す
    int CalculateDamage(int attack, int defense)
    {
        int result = attack - defense;

        if (result < 1)
        {
            result = 1;   // 最低でも1ダメージ
        }

        return result;   // 結果を返す
    }

    // 90以上ならクリティカル(trueを返す)
    bool IsCritical(int roll)
    {
        return roll >= 90;
    }
}

実行結果:

ダメージは 15
クリティカルヒット!
  • メソッド名の前のintやboolが、返す値の型
  • return 値;で結果を返します。returnした時点で、メソッドの処理は終わります
  • 返ってきた値は、変数に入れたり、ifの条件にそのまま使ったりできます
書き方意味
void Attack()何も受け取らず、何も返さない
void TakeDamage(int damage)intを受け取り、何も返さない
int CalculateDamage(int attack, int defense)intを2つ受け取り、intを返す
bool IsCritical(int roll)intを受け取り、true/falseを返す

実践サンプル:HPの管理をメソッドに分ける

ダメージと回復を、それぞれメソッドにまとめてみましょう。

using UnityEngine;

public class HealthExample : MonoBehaviour
{
    [SerializeField] private int maxHp = 100;
    private int hp;

    void Start()
    {
        hp = maxHp;

        TakeDamage(30);
        TakeDamage(50);
        Heal(40);
        TakeDamage(200);
    }

    void TakeDamage(int damage)
    {
        hp -= damage;

        if (hp < 0)
        {
            hp = 0;
        }

        Debug.Log(damage + "のダメージ!残りHP " + hp);

        if (IsDead())
        {
            Debug.Log("ゲームオーバー");
        }
    }

    void Heal(int amount)
    {
        hp += amount;

        if (hp > maxHp)
        {
            hp = maxHp;   // 最大HPは超えない
        }

        Debug.Log(amount + "回復した!HP " + hp);
    }

    bool IsDead()
    {
        return hp <= 0;
    }
}

実行結果:

30のダメージ!残りHP 70
50のダメージ!残りHP 20
40回復した!HP 60
200のダメージ!残りHP 0
ゲームオーバー

Startの中は「ダメージを受ける」「回復する」と読むだけで流れが分かります。細かい計算は、それぞれのメソッドの中にしまっておけるのがポイントです。

スライム

メソッドの名前、いつも何にするか悩む・・・

フェアリー

「動詞+何を」にすると分かりやすいよ!TakeDamage、PlaySound、SpawnEnemyみたいにね

よくあるエラーと対処法

エラー:The name ‘メソッド名’ does not exist in the current context

  • 原因:メソッド名のつづり間違い(大文字・小文字も区別されます)、またはメソッドを作っていない
  • 対処法:呼び出している名前と、作ったメソッドの名前が完全に同じか確認する

エラー:not all code paths return a value

  • 原因:戻り値のあるメソッド(intなど)で、returnしていない道がある
  • 対処法:ifで分かれたどの道を通っても、最後に必ずreturnするようにする

エラー:Argument 1: cannot convert from ‘string’ to ‘int’

  • 原因:引数の型と違う値を渡した(intを受け取るメソッドに文字列を渡したなど)
  • 対処法:メソッドの( )の中の型と、渡している値の型をそろえる

エラー:メソッドを作ったのに何も起きない

  • 原因:メソッドを作っただけで、どこからも呼び出していない
  • 対処法:StartやUpdateの中からメソッド名();で呼び出す(Start・Update以外のメソッドは、自分で呼ばないと動きません)

まとめ

  • メソッド:処理のまとまりに名前を付けたもの。Start・Updateもメソッド
  • 呼び出し:メソッド名();
  • 引数:メソッドに値を渡す(TakeDamage(10))
  • 戻り値:メソッドから結果を受け取る(int damage = CalculateDamage(20, 5);)
  • void:何も返さないメソッド

次のステップ

いよいよ、キーボードやゲームパッドの入力を受け取って、ゲームを操作できるようにしていきます:

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメント一覧 (2件)

コメントする

目次