プレイヤーが取得できるアイテムのクラスを作ってみました。同じクラスを使って、掴めるアイテムも取得できるようにします。
まずアイテムを取得する処理を書いたクラスを作りました。今回は引数のゲームオブジェクトを非アクティブにして、テキストの表示を変えるだけです。Textオブジェクトは管理クラスにまとめました。
using UnityEngine;
using System;
[Serializable]
public class Obtainable
{
internal void Obtain(GameObject item)
{
item.SetActive(false);
string s = item.name + "を取得した";
TextManager.GetInstance().SetText(s, 2);
}
}
プレイヤーが操作するインターフェースを継承して、掴めなくて取得できるアイテムのクラスを作りました。アイテムを取得するクラスをオブジェクトとして持っていて、取得したい時にそのメソッドを呼びます。
using UnityEngine;
public class ObtainableItem : MonoBehaviour, ITouchable
{
[SerializeField] Obtainable obt;
// アイテムに触った時
public void Touch(GameObject sender, Vector3 point)
{
obt.Obtain(gameObject);
}
public void Release(GameObject sender)
{
}
}
プレイヤーが触った時に、取得メソッドの引数に自分のゲームオブジェクトを渡しています。
そして、掴めるアイテムのクラスを継承して、掴めて取得できるアイテムクラスを作りました。
using UnityEngine;
public class GrabAndObtain : Item
{
Obtainable obt = new Obtainable();
// 掴まれているときの処理
protected override void Hold()
{
rb.velocity = (manipulator.transform.forward * 2f + manipulator.transform.position - transform.TransformPoint(effort)) * 10f;
if(Input.GetKeyDown(KeyCode.E))
obt.Obtain(gameObject);
}
}
はじめの取得する処理を書いたクラスをオブジェクトとして持ち、掴んでいる時にキー入力をすると、そのオブジェクトの取得メソッドを呼んでいます。
掴むメソッドはオーバーライドしています。基底クラスでは、protectedとvirtual修飾子を付けています。また、フィールドもprotected修飾子を付けて宣言しています。
// Itemクラス
protected GameObject manipulator;
protected Vector3 effort;
// ...
// 掴まれているとき
protected virtual void Hold()
{
//...
これで、掴んでいる時にキー入力でそのアイテムを取得できました。
取得方法を変えるときに、取得する処理を書いたクラスのそのメソッドを修正するだけで済みます。
取得するクラスには[Serializable]属性を付けているので、このクラスの変数を[SerializeField]を付けて宣言したクラスでも、インスペクタに表示されます。正しいアイテム名などをインスペクタで入力できます。
// 取得する処理を書いたクラス
using System;
[Serializable]
public class Obtainable
{
[SerializeField] string itemName;
// ---
// 他のクラスで宣言
public class ObtainableItem : MonoBehaviour, ITouchable
{
[SerializeField] Obtainable obt;