はじめに
こんにちは、Kaito です!
この記事はメソッドを学習する記事です。
メソッドを使う大きな理由は、同じ処理を何度も書かずに済むことと、処理の細かい中身を隠して呼び出し側をシンプルにできることです。
名前を付けてまとめておくと、コードが読みやすくなり、あとから修正しやすくなります。
また、これは私が所属している徳島大学ゲームクリエイトプロジェクトの勉強会で使用するものです。
興味がありましたら、UnityroomとX公式アカウントなども見に行ってください!
この記事の目標
この記事の目標はUnityのメソッドを通じて以下を理解することです。
- メソッドを使う理由を理解する
- メソッドの定義と呼び出し方を理解する
- メソッドの引数と戻り値を理解する
- メソッドを使ってコードを整理する方法を理解する
メソッドの基本構成
C#におけるメソッドは、特定の処理をひとまとめにしたブロックのことです。関数と呼ばれることもあります。
まずは基本の形を見てみましょう。
public class SampleMethod : MonoBehaviour
{
<アクセス修飾子> <戻り値の型> <メソッド名> (<引数1の型> <引数1の名前>...)
{
// ここに実行したい処理を書く
return <戻り値>; // 戻り値の型がvoid以外の場合は必須
}
}
メソッドは、いわば 「材料(引数)を受け取り、加工(処理)して、結果(戻り値)を返す工場」 のようなものです。
この「型」の部分には、非常に幅広いデータ型を指定できます。
-
intやfloatなどの値型 -
GameObjectや自作のclassなどの参照型 -
List<T>や配列などのコレクション型
このように、あらゆる型を組み合わせることで、目的に応じた柔軟な処理を作ることができます。
基礎1:戻り値の自由度
Unityで最もよく目にするメソッドはおそらく Start() や Update() でしょう。
void Start()
{
// 初期化処理
}
この void というのは、「このメソッドは戻り値(結果)を返しません」という特別な型です。処理を実行するだけで完結するタイプですね。
一方で、メソッドは処理の結果を呼び出し元に返すこともできます。値型と参照型の例を見てみましょう。
// 【値型の例】計算結果を int で返すメソッド
public class Player : MonoBehaviour
{
public int CalculateDamage(int attack, int defense)
{
int damage = attack - defense;
if (damage < 0) damage = 0;
return damage; // 計算結果の数値を返す
}
// 【参照型の例】条件に合う GameObject を探して返すメソッド
public GameObject FindClosestEnemy()
{
GameObject closestEnemy = null;
// ... 一番近い敵を探す処理 ...
return closestEnemy; // 見つけたオブジェクトそのもの(参照)を返す
}
}
このように、単なる数値からUnityのコンポーネントまで、あらゆるものを結果として返すことができます。
基礎2:引数の自由度
次に、「材料」となる引数を見てみましょう。引数も戻り値と同様に自由自在に設定できます。
public class PlayerBehavior : MonoBehaviour
{
private int hp = 100;
// ① 引数なし(指示されたら決まった動作をするだけ)
public void Jump()
{
// ジャンプ処理
}
// ② 値型の引数(数値を受け取って処理に使う)
public void TakeDamage(int damageAmount)
{
hp -= damageAmount;
}
// ③ 参照型の引数(オブジェクトを受け取って操作する)
public void EquipWeapon(GameObject weaponModel)
{
// 武器モデルをプレイヤーの手にアタッチする処理
}
// ④ 混合系(複数、かつ別々の型の材料を受け取る)
public void SpawnEffect(GameObject effectPrefab, Vector3 spawnPosition, float duration)
{
// 指定した場所にエフェクトを生成し、一定時間後に消す処理
}
}
引数を適切に設定することで、一つのメソッドで様々な状況に対応できるようになります。
【プチ演習】実際にメソッドを作ってみよう!
基本の形がわかったところで、5分間の簡単なプログラミング演習をしてみましょう!
以下の2つのお題に合わせて、実際にメソッドを書いてみてください。(頭の中でコードを組み立てるだけでもOKです!)
条件:
- メソッドの外に書いた変数は使わず、渡された「引数」の中だけで計算して「戻り値」を返すこと。
お題1:HPの割合計算
現在のHPと最大HPを受け取り、UIのHPバーに使えるような割合(0.0 ~ 1.0の小数)を計算して返すメソッド CalculateHpRatio を作ってください。
-
引数: 現在のHP(
float)、最大HP(float) -
戻り値の型:
float
お題2:アイテム購入の判定
プレイヤーの所持金とアイテムの価格を受け取り、買えるなら true、買えないなら false を返すメソッド CanBuyItem を作ってください。
-
引数: 所持金(
int)、アイテムの価格(int) -
戻り値の型:
bool
💡 解答例(クリックで展開)
どうでしょうか?書けましたか?
解答例は以下のようになります。
public class SampleMethod : MonoBehaviour
{
// お題1の解答例
public float CalculateHpRatio(float currentHp, float maxHp)
{
// 現在のHPを最大HPで割って割合を出す
float ratio = currentHp / maxHp;
return ratio;
// ※ return currentHp / maxHp; と1行で書いてもOKです!
}
// お題2の解答例
public bool CanBuyItem(int playerMoney, int itemPrice)
{
// 所持金が価格以上かどうかを判定する
if (playerMoney >= itemPrice)
{
return true;
}
else
{
return false;
}
// ※ return playerMoney >= itemPrice; と1行でスマートに書いてもOKです!
}
}
このように、**「メソッドの外の変数を見に行かず、渡された引数だけで計算して結果を返す」**ように作ると、どこからでも安全に呼び出せる非常に使い勝手の良いメソッドになります!
発展:メソッドのさらに深い世界へ
💡 発展知識(クリックで展開)
ここでは初心者向けの枠を超えた、少し高度なメソッドの機能を紹介します。今は「そんな便利な機能があるんだな」と頭の片隅に置いておくだけで大丈夫です!興味がある人はぜひ調べてみてください!
-
テンプレート(ジェネリクス)
Unityでよく使うTryGetComponent<T>()の<T>の部分です。これは「型」自体を引数のように後から指定して渡すことができる強力な機能です。 -
可変長引数 (
params)
引数の数を決め打ちせず、「いくつでも受け取れる」ようにする機能です。受け取った側では配列として処理されます。UnityのDebug.LogFormatメソッドは、複数の引数を受け取って一度にログ出力できるようになっています。 -
オーバーロード
UnityのInstantiateメソッドは、引数にPrefabだけを渡すこともできれば、Prefabと位置(Vector3)と回転(Quaternion)を一緒に渡すこともできます。このように「同じ名前のメソッドでも、引数の型や数が違えば複数定義できる」機能をオーバーロードと呼びます。 -
コルーチン(Coroutine)
Unityでは時間制御や連続した処理を簡潔に書くためにコルーチンを利用します。コルーチンはIEnumeratorを返すメソッドとして定義し、StartCoroutineで開始します。内部でyield return null(次フレームまで待つ)やyield return new WaitForSeconds(秒数)(指定秒数待つ)を使い、処理を一時停止できます。簡単な例を示します。コルーチンは便利ですが、停止やライフサイクル管理(`StopCoroutine` や `MonoBehaviour` の有効/無効時の挙動)に注意が必要です。コード例
public class Fade : MonoBehaviour { public IEnumerator FadeOut(CanvasGroup canvasGroup, float duration) { float elapsed = 0f; while (elapsed < duration) { canvasGroup.alpha = 1f - (elapsed / duration); elapsed += Time.deltaTime; yield return null; // 次のフレームまで待つ } canvasGroup.alpha = 0f; } } // 呼び出し例 StartCoroutine(FadeOut(myCanvasGroup, 1.0f));
実践例:メソッドは「自作のパーツ」である
皆さんはUnityを使う中で、rigidbody.AddForce(Vector3) のようなメソッドを当たり前のように使っていると思います。これはUnityの開発者が用意してくれた パーツ です。
実は、自分でメソッドを作るということは、自分のゲーム専用のパーツを作っているのと同じなのです。
例えば、AddForce の中身を想像して、自分だけの簡易的な物理挙動メソッドを実装してみましょう。
public class MyPhysicsObject : MonoBehaviour
{
public Vector3 velocity; // 現在の速度
public float mass = 1.0f; // 質量
// AddForceの簡易版を自作してみる
public void MyAddForce(Vector3 force)
{
// 運動方程式 (F = ma -> a = F / m)
Vector3 acceleration = force / mass;
// 加速度を速度に追加
velocity += acceleration * Time.deltaTime;
}
void Update()
{
// 実際の移動処理
transform.position += velocity * Time.deltaTime;
}
}
このようにメソッドを定義しておけば、他のスクリプトからは myPhysicsObj.MyAddForce(Vector3.up * 10f); と呼び出すだけで済みます。使う側は中の複雑な計算(運動方程式など)を意識しなくても、簡単に機能を利用できます。
これがメソッドの強力な点であり、チーム開発においても「誰でも使いやすい機能を提供する」ための重要な考え方になります。
まとめ
-
メソッドは処理をまとめる道具
同じ処理を何度も書かずに済むようにまとめることで、プログラムが読みやすくなり、呼び出し側も複雑な処理を意識せずにメソッドを呼び出すだけでよくなります。 -
引数と戻り値で柔軟に
値型、参照型、コレクション型など様々なデータを受け取り(引数)、結果を返す(戻り値)ことができます。 -
メソッド作りはパーツ作り
機能ごとにメソッドを分割することで、自分やチームメンバーが使いやすい「パーツ」を作ることができます。内部の複雑な処理を隠蔽し、使い勝手を良くすることが重要です。