スクリプトが長くなってくると、「どこで何をしているのか」が分かりにくくなってきます。そんなときは、処理のまとまりに名前を付けて分けましょう。それがメソッド(関数)です!今回は自分でメソッドを作って呼び出す方法と、引数・戻り値の使い方をご紹介します。
目次
この記事で学べること
- メソッド(関数)とは何か
- メソッドの作り方と呼び出し方
- 引数(ひきすう)でメソッドに値を渡す方法
- 戻り値でメソッドから結果を受け取る方法
前提知識
メソッドとは?
実はもう使っている
これまで書いてきた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:何も返さないメソッド
次のステップ
いよいよ、キーボードやゲームパッドの入力を受け取って、ゲームを操作できるようにしていきます:
コメント
コメント一覧 (2件)
[…] メソッドを作ろう:処理に名前を付けてまとめる […]
[…] メソッドを作ろう:処理に名前を付けてまとめる […]