参照戻り値と参照ローカル変数を利用することで、利用しない場合には1つのメソッド内で実装していた処理を2つのメソッドを分けて作成しています。
参照している値の更新を行う UpdateRecoveryItemCount メソッドと、どの値を参照するかを決定する GetRecoveryItemCountRef メソッドに分けているので、
修正する場合には、GetRecoveryItemCountRef メソッドのみ修正する形式になっています。
今回の場合、参照戻り値の機能を利用することにより、戻り値の値を
メンバ変数の参照値とすることができますので、
その値を増減した場合には、
メンバ変数の値そのものが変更されることになります。
PlayerHealth.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerHealth : MonoBehaviour
{
//Playerの体力とプロパティ
private int playerHp = 100;
private int maxHp = 1000;
public int PlayerHp
{
get => playerHp;
set => playerHp = Mathf.Min(playerHp += value, maxHp);
}
//包帯の数とプロパティ
private int bandageCount;
public int BandageCount { get => bandageCount; }
//薬草の数とプロパティ
private int medicinalPlantscount;
public int MedicinalPlantsCount { get => medicinalPlantscount; }
//注射器の数とプロパティ
private int syringeCount;
public int SyringeCount { get => syringeCount; }
// 回復アイテムの最大数(全アイテム共通の場合)
private const int maxCount = 100;
////* ここから変更 *////
// 参照戻り値の switch 文内の default 判定時用の変数
private int x = 0;
/// <summary>
/// 回復アイテムの所持数を更新する
/// この処理があれば、複数の回復アイテムがあっても、アイテムごとに同じようなメソッドを用意しなくてよい
/// よってゲーム内に登場するアイテムの種類が増減しても、所持数を更新するこのメソッド部分のプログラムは一切変更が不要になる
/// </summary>
/// <param name="itemName">アイテムの名前</param>
/// <param name="updateValue">所持数の更新量</param>
public void UpdateRecoveryItemCount(ItemName itemName, int updateValue)
{
// ItemNameから更新する回復アイテムの個数と最大値を GetRecoveryItemCountRef メソッドに参照渡しをして処理し、戻り値を参照戻り値でもらって取得
// 参照した値を戻り値として変数に代入しているので、それは新しい値ではなく、メンバ変数に用意している変数の情報を参照した値が取得できる
ref int recoveryItemCount = ref GetRecoveryItemCountRef(itemName); // ローカル変数の前と引数に値を渡すメソッドの前に ref を記述する
// TODO 回復アイテムの最大所持数がアイテムごとに異なる場合には、ここで用意する
// 回復アイテムの所持数を、最大値と最小値に収まるように制限して更新する
recoveryItemCount = Mathf.Clamp(recoveryItemCount + updateValue, 0, maxCount); // ☆ 参照値を更新するので、メンバ変数自体が変わる
// 参照している値が更新されているかを確認
Debug.Log($"{ itemName } : { recoveryItemCount }");
}
/// <summary>
/// 指定した回復アイテムの所持数を参照戻り値で取得する
/// アイテムが増えたり減ったりした場合には、 case の部分を追加・削除すれば、上記の所持数の更新の処理自体は何も変更しなくてよい。
/// </summary>
/// <param name="itemName">回復アイテムの名前</param>
/// <returns>その回復アイテムの所持数</returns>
private ref int GetRecoveryItemCountRef(ItemName itemName) // 戻り値の前に ref を記述する
{
//アイテムの名前に応じて処理を変更
switch(itemName)
{
// 各メンバ変数の値を参照して戻す
case ItemName.Bandage: return ref bandageCount; // 戻す値の前にも ref を記述する
case ItemName.MedicinalPlants: return ref medicinalPlantscount;
case ItemName.Syringe: return ref syringeCount;
default: return ref x; // 参照戻り値に利用できる値はローカル変数を指定するとエラーとなるため、メンバ変数で定義している変数を指定している。
}
}
}
こちらのケースの場合、UpdateRecoveryItemCount メソッド内で参照した値の更新を行う機能が備わっているので、
今後、アイテムの種類が増減しても、このメソッド内への修正は必要ありません。
代わりに、GetRecoveryItemCountRef メソッド内の switch 文の分岐のみ修正すれば済みます。
private int x = 0; の宣言は、GetRecoveryItemCountRef メソッド内の switch 文の default で利用するために宣言しています。
理由は、
参照戻り値として指定できる変数にはローカル変数は利用できないというルールがあるためです。
例えば、GetRecoveryItemCountRef メソッド内で int x = 0; を宣言した場合、x は上記のルールにより、指定するとエラーになります。
なお戻り値のある switch 文の場合には式での書式の switch 文が利用できますが、
参照戻り値の場合には、式での書式は利用できません。
(通常の switch 文で記述する必要があります)
参照利用しているポイントは、以下の部分に効果的に利用されています。
UpdateRecoveryItemCount メソッド内
// 回復アイテムの所持数を、最大値と最小値に収まるように制限して更新する
recoveryItemCount = Mathf.Clamp(recoveryItemCount + updateValue, 0, maxCount); // ☆ 参照値を更新するので、メンバ変数自体が変わる
この recoveryItemCount の値が、その前の処理で参照して取得した、いずれかのメンバ変数の値になっています。
メンバ変数の値の
コピー値ではないので、この値を変更すると、
メンバ変数の値が参照されて変化します。
そのため、アイテムの所持数を更新する処理はこの1つだけですが、更新を行う値がその都度、参照先を変えるようなロジックになっているので
いずれのメンバ変数の値であっても対応出来るようになっています。