アイテムを取得する処理

Unityでステージに落ちているアイテムを拾う処理を実装します。動作環境はUnity2022.3.10fです。
ゲームではステージに色々なアイテムが落ちています。ステージに落ちているアイテムを拾う方法は色々あると思われますが、この記事では次の取得方法を実現します。
・プレイヤーがアイテムに近づく。
・メッセージが表示される。
・ボタンを押すとアイテムを拾う。
・ボタンを押さずにアイテムから離れるとメッセージは消える。
・アイテムを拾った場合はステージから対象のアイテムを消す。

# ステージの準備
Hierarchyウィンドウで右クリックして、3D Object→Planeを選択します。このPlaneがキャラクターの移動するステージになります。
次にプレイヤーとして操作するキャラクターを用意します。例では無料AssetのLevel 1 Monster Packを使いました。わかりやすくするためにプレイヤーオブジェクトの名前を「Player」に変更しておきます。キャラクターをステージに置いたらColliderを忘れずアタッチしておきます。
ステージの上にアイテムも置きます。アイテムの代わりとなるものなら何でもいいですが、雰囲気を出すために、例では無料AssetのLow Poly Survival modular Kit VR and Mobileを使いました。アイテムの方にもColliderをアタッチしておきます。さらにアイテムのオブジェクトは、InspectorウィンドウでTagの名前を「Item」に設定しておきます。
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3644510/0f54347e-1b65-7f2f-1467-fd8b7b0631b7.png)
上の図はプレイヤーキャラとキノコ型のアイテムオブジェクトを設置した見本です。
# プレイヤー側の処理
プレイヤーの移動とアイテム取得のための以下のスクリプトを作成してプレイヤーキャラクターにアタッチします。
```C#:PlayerController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

[RequireComponent(typeof(Rigidbody))]
public class PlayerController : MonoBehaviour
{
    public float moveSpeed; //移動速度
    public float dashSpeed; //ダッシュ時の速度
    private Rigidbody rigidbody;
    private Vector3 moveVelocity;
    internal string text; //表示するテキストを入れる変数

    void Start()
    {
        rigidbody = GetComponent<Rigidbody>();
        rigidbody.constraints = RigidbodyConstraints.FreezeRotation; //回転を防止
        text = string.Empty; //テキストを空の文字列で初期化
    }

    void Update()
    {
        if (Input.GetKey(KeyCode.Z)) //Zキーを押している時はダッシュする
        {
            moveVelocity.x = Input.GetAxis("Horizontal") * dashSpeed; 
            moveVelocity.z = Input.GetAxis("Vertical") * dashSpeed;
        }
        else
        {
            moveVelocity.x = Input.GetAxis("Horizontal") * moveSpeed;
            moveVelocity.z = Input.GetAxis("Vertical") * moveSpeed; 
        }

        transform.LookAt(this.transform.position + new Vector3(moveVelocity.x, 0, moveVelocity.z)); //プレイヤーの向きを移動方向と同じにする
        rigidbody.velocity = moveVelocity;
    }

    //アイテムに触れた時の処理
    void OnCollisionStay(Collision collision)
    {
        if (collision.gameObject.tag == "Item")
        {
            text = "B 拾う";

            if (Input.GetKeyDown(KeyCode.B)) //Bキーを押すとアイテムを拾う
            {
                text = collision.gameObject.name + "を取得した";
                Destroy(collision.gameObject); //拾ったらそのアイテムを消す
                Invoke(new Action(() => { text = string.Empty; }).Method.Name, 2); //取得後2秒経過でメッセージを消す
            }
        }
    }

    //アイテムから離れるとメッセージを空の文字列に戻す
    void OnCollisionExit(Collision collision)
    {
        if (collision.gameObject.tag == "Item")
        {
            text = string.Empty;
        }
    }
}
```
アイテムの取得はBキーで実行します。Bキーを押してアイテムを拾ったら「◯◯◯を取得した」というメッセージを表示させます。◯◯◯の中にはアイテムオブジェクトの名前が入ります。このメッセージはアイテム取得後から2秒後に消えます。その処理はInvokeを使って実装しました。短い処理なので新しく関数を定義せずにラムダ式で実装しました。
また、必要だと思ったら、カメラワークのスクリプトを、以前書いた記事(以下のURL)から取ってきてMain Cameraにアタッチしてください。
https://qiita.com/holy_r_e9620202/items/dd4a21031295d7b88c08
# テキストの表示
Hierarchyウィンドウで右クリックして、UI→Legacy→Textを選択します。CanvasとTextが生成されるので、自分にとって見えやすい位置にテキストの位置を調整します。作成したTextに以下のスクリプトをアタッチします。
```C#:TextManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class TextManager : MonoBehaviour
{
    Text text;
    PlayerController playerController;
    
    void Start()
    {
        text = GetComponent<Text>();
        text.text = string.Empty; //テキストを空の文字列で初期化
        text.color = Color.green; //文字の色を緑に設定
        text.fontSize = 20; //フォントサイズを20に設定
        playerController = GameObject.Find("Player").GetComponent<PlayerController>();
    }

    void Update()
    {
        text.text = playerController.text; //PlayerController.csのtextを反映させる
    }
}
```
TextManager.csではフォントサイズやテキストの文字の色などの設定を行い、表示テキストの制御はPlayerController.csで行っています。
これを実行するとプレイヤーを動かしてアイテムに触れた時に、以下の画像のようにメッセージが表示されます。
![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3644510/55ce8a89-7171-b431-170d-cf8880a895bc.png)
メッセージに従いBキーを押して拾うと、以下の画像のようにアイテムが消えて、取得したことと取得したアイテム名が表示されます。
![image3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3644510/9a11be45-8cd1-8b50-522b-194f37916010.png)
# 参考
https://docs.unity3d.com/ja/2018.4/ScriptReference/UI.Text.html
https://www.karvan1230.com/entry/2023/01/24/170004