床の色が白い状態と赤い状態で、プレイヤーがオブジェクトをクリックしたときの処理を変えてみます。処理の変更はプレイヤーとは別のスクリプトで行います。
using UnityEngine;
using UnityEngine.UI;
public class GameScript : MonoBehaviour
{
[SerializeField] Text text;
[SerializeField] Material[] materials;
[SerializeField] MeshRenderer planeMeshRenderer;
[SerializeField] UnityStandardAssets.Characters.FirstPerson.FirstPersonController sc_fps;
float sec;
int num;
delegate void Method();
Method method;
// Start is called before the first frame update
void Start()
{
text.text = "";
sc_fps.method += Method1;
}
// Update is called once per frame
void Update()
{
sec += Time.deltaTime;
if (sec >= 3)
{
sec = 0f;
planeMeshRenderer.material = materials[++num];
// 床が白いとき
if (num == 0)
{
sc_fps.method -= Method2;
sc_fps.method += Method1;
}
// 赤いとき
else
{
sc_fps.method -= Method1;
sc_fps.method += Method2;
num = -1;
}
}
}
void Method1(GameObject obj)
{
text.text = obj.name;
}
void Method2(GameObject obj)
{
text.text = obj.transform.position + "";
}
}
クリックしたオブジェクトの名前を表示するものと、位置を表示するものの2つのメソッドを用意して、プレイヤーのスクリプトのデリゲートの中身を状態によって入れ替えています。
状態は3秒毎に切り替わります。床のマテリアルも変えています。
void Update()
{
sec += Time.deltaTime;
if (sec >= 3)
{
sec = 0f;
planeMeshRenderer.material = materials[++num];
// 床が白いとき
if (num == 0)
{
sc_fps.method -= Method2;
sc_fps.method += Method1;
}
// 赤いとき
else
{
sc_fps.method -= Method1;
sc_fps.method += Method2;
num = -1;
}
}
}
プレイヤーのスクリプトでは、クリックしたときに短いレイを飛ばして、タグでCubeを見分けて、デリゲートを実行します。
public delegate void Method(GameObject obj);
public event Method method;
// Update is called once per frame
private void Update()
{
RaycastHit hit;
if (Input.GetMouseButtonDown(0) && Physics.Raycast(m_Camera.transform.position, m_Camera.transform.forward, out hit, Mathf.Infinity, ~(1 << 9)))
{
if (hit.distance <= 2f)
{
if (hit.collider.tag == "Item")
{
method(hit.collider.gameObject);
}
}
}
event修飾子を付けているので、外部からは加算/減算代入演算子しか使えません。引数にレイが当たったオブジェクトを渡すようにしています。
OnTriggerEnterでも使ってみました。
private void OnTriggerEnter(Collider other)
{
if (other.tag == "Collider")
{
method(other.gameObject);
}
}