🐡

[Unity] 宝箱から取得したアイテム情報画面に表示させる。part1

2022/04/01に公開

[Unity] 宝箱から取得したアイテム情報を画面に表示させる。part1

やりたいこと

・宝箱をあけたらアイテムを取得したい
・ScriptableObjectからアイテムを取得したい。
・取得したアイテムをゲーム画面に表示したい。
・モンハンライズのように画面外右から左へ移動しながら表示したい。
・一定時間が経過するとアイテム表示を消去したい。
・表示されたアイテムをタッチすると、取得したアイテムの詳細がわかる画面に移動させたい。
 (今後実装予定。)

事前準備

・Playerをゲームに配置する。(スクリプトをアタッチできればなんでもいいです。)
・宝箱をゲームに配置する。(コライダーをアタッチできればなんでもいいです。)
・DoTweenをimportする。(DOTween (HOTween v2))

取得アイテムを表示するTextの用意

  1. Hierarchy > UI > Canvas をクリック
  2. Canvasを右クリック ⇒ UI > Imageをクリック(アイテム表示の台紙)
  3. Imageを右クリック ⇒ UI > Textをクリック(アイテム名を表示)
  4. Imageを右クリック ⇒ UI > Imageをクリック(アイテムのアイコンを設定)
  5. Imageを右クリック ⇒ UI > Buttonをクリック(Button > Textは削除)
    各UIの名前を任意のものに変更し、オブジェクトが以下のように構成されていることを確認してください。

UIのInspector設定

  1. Canvasの設定
    ・Canvas Scaler > UI Scale ModeをScale Eith Screen Sizeに変更。
    ・Reference Resolutionを任意の値に設定(画面サイズと同じもの)

  2. ItemAcquisitionImageの設定
    ・Rect TransformのPosを任意の値に変更する。
     位置はキャンバスの範囲外(ゲーム画面外)であればOKです。

    私の場合は、以下のものです。

  3. Textの設定
    ・任意の文字列を設定。(私の場合は「さいだい12文字であります」と入力)
    (スクリプトから取得したアイテム名を記載する場所。)
    ・Font Size等任意の値を設定。

  4. ItemImageの設定
    Imageは任意のものを設定(私は面倒くさかったので色を赤にしただけです。。)
    (本来ならば、取得したアイテム画像が妥当です。)

  5. Buttonの設定
    取得アイテム表示を押下すると、アイテム画面に移動します(未実装です。)
    ・Canvas Renderer > Cull Transparent Meshにチェック
    ・各ColorのAを0にする(透明にする)

ソースコード


ScriptableObjectを作成するためのソースファイルです。

ItemAttScriObj.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[CreateAssetMenu(menuName = "MyScriptable/Create ItemScrObj")]
public class ItemAttScriObj : ScriptableObject
{
    public List<ItemAtt> list = new List<ItemAtt>();

    [System.Serializable]
    public class ItemAtt
    {
        public string name;
        public int num;
        public string description;
    }
}

作成が終了したら、Assets > Create > MyScriptable > Create ItemScrObjをクリック
Assets配下に「New Item SCR Obj Scriptable Object.asset」が作成されたかと思います。
「New Item SCR Obj Scriptable Object.asset」をクリックして以下のように、Inspectorに値を追加してください。


宝箱にPlayerが近づき、「O」キーをクリックしたら、アイテムをランダムに取得する。
アイテムはScriptableObjectより取得して、画面に表示する。

ItemAttScriObj.cs
using DG.Tweening;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;

public class TreasureAcquisition : MonoBehaviour
{
    string filePath = "Assets/New Item Att Scri Obj.asset";
    public GameObject itemText;              // Textオブジェクトをアタッチ
    private GameObject treasurePrefab;       // 宝箱prefab
    public GameObject itemImage;             // Imageオブジェクトをアタッチ
    string itemName;
    int num;
    bool collisionTouchFlag = false;

    void Start()
    {
        treasurePrefab = this.gameObject;
    }

    private void Update()
    {
        onClickTreasureBox();
    }


    // Oが押下されたときに、ontrrigerenter状態である。
    public void onClickTreasureBox()
    {
        if (Input.GetKeyDown(KeyCode.O))
        {
            if (collisionTouchFlag)
            {
                openTreasureBox();
		
                Destroy(treasurePrefab);
            }
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.CompareTag("Player"))
        {
            Debug.Log("enter");
            collisionTouchFlag = true;
        }
    }

    private void OnTriggerExit(Collider other)
    {
        if (other.gameObject.CompareTag("Player"))
        {
            Debug.Log("exit");
            collisionTouchFlag = false;
        }
    }

    // 開けるボタンを押下されたらアイテムをランダムで取得する
    public void openTreasureBox()
    {
        // Itemをランダムで取得する
        setItem();

        // 取得したItemの名前を表示する(画面上部に表示)
        Text itemText = this.itemText.GetComponent<Text>();
        itemText.text = itemName;

        Image itemImage = this.itemImage.GetComponent<Image>();

        // テキストを表示・移動・削除
        StartCoroutine("DisplayText", itemImage);
    }
    
        private void setItem()
    {
        // ScriptableObjectのパスを指定して、EnemyStatusScriptableObjectを取得する。
        ItemAttScriObj itemScriptableObj = AssetDatabase.LoadAssetAtPath<ItemAttScriObj>(filePath);

        // 乱数にするため、シードを初期化
        UnityEngine.Random.InitState(DateTime.Now.Millisecond);


        // 0以上4未満のint型の値を返す(アイテム数に合わせる)
        num = UnityEngine.Random.Range(0, 4);

        itemName = itemScriptableObj.list[num].name;


        Debug.Log("item name:" + itemName);
    }

    // 画面のImageを移動させる
    // threadで呼び出す
    IEnumerator DisplayText(Image itemImage)
    {
        
        Vector3 destination;    // imageの移動先

        // 0.15秒かけて所定の位置まで移動
        destination = itemImage.rectTransform.position + new Vector3(-600f, 0f, 0f);
        itemImage.transform.DOMove(destination, 0.15f);

        // 所定の位置で2秒間固定(image移動時間を含めて計3秒)
        yield return new WaitForSeconds(2.7f);

        // 0.15秒かけて元の位置に移動
        destination = itemImage.rectTransform.position + new Vector3(600f, 0f, 0f);
        itemImage.transform.DOMove(destination, 0.15f);
    }
}

最終準備

  1. Playerにrigidbodyをアタッチする。
  2. Playerにcolliderをアタッチする。
  3. PlayerにItemAttScriObj.csをアタッチする。

  1. 宝箱にrigidbodyをアタッチする。
  2. 宝箱にcolliderをアタッチする。
  3. 宝箱にcolliderをアタッチし、「Is Trigger」にチェックを入れる。
    Edit Colliderを押下して、colliderの範囲を広げる(Radius = 2.72)
    PlayerをRadius=2.72の範囲に収まるように移動させる。
  4. 宝箱にItemAttScriObj.csをアタッチする。
    「ItemText」「ItemImage」にそれぞれ「Text」と「ItemAcquisitionImage」を入れる。

実行

「O」キーをクリックすると、宝箱が消滅し、アイテムがランダムで取得されたのち、ゲーム画面に表示されると思います。

デバッグ等行っていないので、バグが内在していると思いますが、その点に関してはご了承ください。

Discussion