先ほど利用している Physics.OverlapSphere メソッドの引数には第3引数と第4引数があり、こちらには初期値が代入されています。
そのため、第2引数まで指定すれば利用できるようになっています。
第3引数にはレイヤーの指定ができるため、その場合、Physics.OverlapSphere メソッドを実行すると、メソッドの範囲内にある、指定したレイヤーのみを配列として取得出来ます。
そのため、if 文による判定を省略できます。
<= クリックすると開きます。
using UnityEngine;
public class ItemCollector : MonoBehaviour
{
[SerializeField] private int itemsToCollect = 5; // アイテムの取得目標数
[SerializeField] private float radius = 1.0f; // アイテムの取得範囲の半径値
[SerializeField] private LayerMask targetLayer; // 判定したいレイヤー(インスペクターで指定する)
private int collectedItems = 0; // 現在取得したアイテムの数
void Update()
{
// 任意のキーを設定します。ここでは C を利用しています
if (Input.GetKeyDown(KeyCode.C))
{
// アイテムの取得有無判定
TryCollectItem();
}
}
/// <summary>
/// アイテムの取得有無判定
/// </summary>
private void TryCollectItem()
{
// キャラクターを中心に、radius を半径とした球体形のコライダーを作成し、その範囲内にある、指定したレイヤーを持つ、すべてのコライダーを検出して配列にする
Collider[] hitColliders = Physics.OverlapSphere(transform.position, radius, targetLayer);
// アイテムが見つからない場合には、早期リターンしてここで処理を停止する
if (hitColliders.Length == 0) return;
// 配列内の要素を1つずつ取り出す。この要素はすべて指定したレイヤーのものだけになっている
foreach (Collider collider in hitColliders) {
// アイテムの取得数加算
collectedItems++;
// TODO 各アイテムごとの処理。そのためには、GetComponent メソッドが必要
// アイテムの破棄
Destroy(collider.gameObject);
// アイテムの取得数が目標値を超えたら
if (collectedItems >= itemsToCollect) {
// ログの表示
Debug.Log("Clear!");
}
// 1フレーム内で複数のアイテムが取得されないようにする
// まとめて取りたい場合には、この部分は不要
break;
}
}
}
事前にレイヤーを作成し、インスペクターで検出したいレイヤーを指定します。
また、検出される側(アイテム側)にレイヤーを設定しておく必要があります。
利点としては、Physics.OverlapSphere メソッドで検出されるコライダーをふるいにかけて、指定したレイヤーの情報のみで戻り値を作成できることです。
そのため、配列の中身はすべて指定したレイヤーのコライダーのみであることが保証されるため、タグとは異なり、if 文による判定が不要になっています。