private 修飾子の int 型の point 変数を宣言し、この値を
「宝石の持つ得点」という情報として役割を持たせます。
そのため、その役割に沿った使い方をスクリプト内で記述していく必要があります。
private 修飾子のままですとスクリプト内でしか値の編集が出来ないため、値を変えてデバッグしたい場合には不便です。
こういったケースでは SerializeField 属性を付けて変数を宣言しておくことで、インスペクターから任意の得点の設定を可能にしておくと便利です。
int 型を利用しているのは、得点を管理している ScoreManager スクリプトにある totalPoint 変数の型が int 型であるためです。
同じ型同士であれば簡単に加算処理が作れます。
新しい情報を用意する場合には、その変数がどの部分で利用されるのかを考えて、必要な形で設計をします。
重要な変更点として、OnTriggerEnter メソッド内の処理を修正し、ゲームオブジェクトがコライダーに侵入したら、そのゲームオブジェクトのタグによって判定を行う処理から、
侵入したゲームオブジェクトにアタッチされている指定されたスクリプト(ここでは ScoreManager)を取得できるかを判定する処理に変更します。
得点の情報を管理しているのは、プレイヤーのゲームオブジェクトではなく、そこにアタッチされている ScoreManager が管理を行っています。
そのため、例えばタグによってゲームオブジェクトの判別が出来たとしても、その後に再度、そのタグによって判別されたゲームオブジェクトに対して、
指定されたスクリプト(ScoreManager)を取得することができるかを判定する必要があります。
つまり、
タグによる処理の場合、そのあとの処理につなげていく際に、再度、スクリプトの有無の判定の処理を行うことになるため、
同じゲームオブジェクトに対して重複判定をすることになります。タグの判定後に、さらに GetComponent メソッドの処理が必要になるためです。
それは
無駄な処理になってしまうため、今回はタグの処理を止め、代わりに、スクリプトを取得できるかを判定し、
スクリプトを取得できた場合にのみ、次の処理へとつながるようなロジックを作って処理を組み上げています。
これには新しい TryGetComponent メソッドを活用しています。
この新しい処理に変更することにより、
スクリプトのアタッチの有無の確認をしながらゲームオブジェクトの判定を行い、
かつ、
必要なスクリプトの取得の処理を1回の処理で行うことができるため、処理の正確性を高め効率化も測れます。
結果として、
現在用意しているタグによる判定処理の代わりにもなりますので、タグの判定部分を削除することが出来ます。
ScoreManager が取得出来た場合には変数に代入して、ScoreManager スクリプトを参照したり、命令を出せるようにします。
そして、ScoreManager スクリプト内の public 修飾子で宣言している AddScore メソッドを実行(呼び出)します。
AddScore メソッドを実行するには int 型の引数を用意する必要がありますので、今回宣言を追加した int 型の point 変数を渡します。
この処理によって、スコアの加算処理とともに、どの値を加算するのか、という情報も一緒に ScoreManager 側に届くようになります。
Gem.cs
<= クリックすると開きます。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Gem : MonoBehaviour
{
private string playerTag = "Player";
////* 変数の宣言を追加 *////
[SerializeField]
private int point; // 宝石にプレイヤーが侵入した際に獲得できる得点値。インスペクターより設定する
////* ここまで *////
private void OnTriggerEnter(Collider col) {
////* いままでの処理を削除するか、コメントアウト *////
//if (col.CompareTag(playerTag)) { // この処理を削除するか、コメントアウトします
// TODO プレイヤーが侵入した際の処理を書く。実際に処理を書きこんでいるので、この部分はコメントアウトするか、削除してもらって構いません
//Debug.Log("プレイヤー侵入"); // <= 確認が終了した Debug.Log はコメントアウトするか、削除してもらって構いません
//Destroy(gameObject, 1.0f); // この処理は新しい処理内に移動します
//}
////* ここまで *////
////* ここから処理を追加 *////
// col.gameObject(つまり、プレイヤーのゲームオブジェクト)に対して、TryGetComponent メソッドを実行し、ScoreManager クラスの情報を取得できるか判定する
// ScoreManager スクリプトがアタッチされているゲームオブジェクトはプレイヤーのゲームオブジェクトしかない。
// よってこの判定処理を行うことにより、タグを使わずにプレイヤーのゲームオブジェクトであるか判定できる。
// また、ScoreManager スクリプトを取得できた場合のみ、if 文内の処理が実行されるため、処理を安全に実行していくことにも一役買っている
if (col.gameObject.TryGetComponent(out ScoreManager scoreManager)) {
Debug.Log("プレイヤー侵入"); // <= 確認が終了した Debug.Log はコメントアウトするか、削除してもらって構いません
// ScoreManager クラスが取得出来ている場合、scoreManager 変数を通じて ScoreManager クラスに記述されている public 修飾子の AddScore メソッドを呼び出す命令をする
// 引数には point 変数の値を渡す
scoreManager.AddScore(point);
Destroy(gameObject, 1.0f);
}
////* ここまで *////
}
}
スクリプトの修正が終了したら、セーブします。
つづけて、宝石のゲームオブジェクトのインスペクターを確認します。
新しく SerializeField 属性をつけた private 修飾子で宣言した point 変数が表示されていれば問題ありません。
Gem ゲームオブジェクト インスペクター画像(初期値時)
こちらの
point 変数の初期値は 0 ですので、任意の値を設定してください。
この値がプレイヤーが宝石に侵入した際に獲得できる得点になります。
Gem ゲームオブジェクト インスペクター画像(値設定時)