Unity+PhotonでFPSを作成しているのですが、アイテムを拾ったらインベントリに取得できるという機能を実装したいと思いました。そこでチュートリアル動画を探してみると、カードゲームのカードの置き方を説明している物がありまして、それのギミックをそのまま流用することにしました。
まずは、Canvasを用意し、そのうえでTutorial(全3回)の一回目のファイルが動くことを確認しました。ソースコードはこちら。
ゲームをしながら、「あ」のイメージをドラッグアンドドロップできます。最終的には「あ」の形をした敵を撃つと「あ」のアイテムを落とし、それを拾うと、インベントリに収納される機能をがあれば理想的です。
画面の右半分部分をインベントリ―に改造しようとしています。「あ」のImageにはDraggable.csを付けて、ドラッグアンドドロップを検出できるようにしています。
Tutorialの第一回目のソースコードは以下のようになっています。これが元のドラッグアンドドロップを可能にしているという事になりそうです。
using UnityEngine; using System.Collections; using UnityEngine.EventSystems; public class Draggable : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler { public void OnBeginDrag(PointerEventData eventData) { Debug.Log("OnBeginDrag"); } public void OnDrag(PointerEventData eventData) { Debug.Log("OnDrag"); this.transform.position = eventData.position; } public void OnEndDrag(PointerEventData eventData) { Debug.Log("OnEndDrag"); } }
次にInventoryのパネルを作成します。パネル側の処理について書く前に、HorizontalLayoutGroupというコンポーネントを付けます。これによって横方向にきれいに並んだ状態でパネル上に乗ったものを拘束できるようになります。真ん中に揃えるためにMiddleCenterを選んでいます。
その次に並ぶ「あ」のイメージ側にLayoutElementというコンポーネントを付けます。「あ」のイメージをそのままの形で使用したいので、FlexibleWidthとFlexibleHightを0にしています。これによってイメージの形が変わることを防止していると理解しています。
これで、Tutorial2回目のDraggable.csを使用してあげると、以下のように奇麗に「あ」のイメージが並ぶという事になります。よく見ると「あ」はダサいデザインですね。今後のアップデートに期待してください。
それから最後に、CanvasGroupを「あ」のImageにコンポーネントとして付けて上げます。そして、パネルにはDropZone.csをソースファイルよりダウンロードしてくっつけます。
これをいくつかコピーすることで、ドロップできるパネルを複数個用意することが出来ました。お互いのパネルから別のパネルへとアイテムの移動が可能となっているのが分かります。
次はアイテムの取得です。アイテム側のboxColliderのisTriggerをオンにしてあげて、void OnTriggerEnter(Collider other)の関数で呼んであげています。(詳しくはアイテムを拾うスクリプト編をご覧ください。)タグによってelse ifで処理を分けていて、”A"というタグを「あ」のアイテムにはつけています。ぶつかった時のアイテムが消える処理と、自分のInventoryの子オブジェクトとしてアイテムをInstantiateする処理を書いています。
Canvas内でImageをInstantiateする備忘録(自動生成)
上のリンクを私は参考にしましたが、Prefabを親にしてInstantiateしてしまったので、下記のエラーが出てしまいました。
Setting the parent of a transform which resides in a prefab is disabled to prevent data corruption.
これはInstance化されていないPrefabを親にしてしまっている時に出るエラーの様で、私はFindを使う事でインスタンス化されているゲームオブジェクトを探してあげました。これによってエラーは解決されました。
else if (other.gameObject.CompareTag("A")) { PhotonNetwork.Destroy(other.gameObject); //ぶつかった相手をディアクティベート(消える if (photonView.isMine) { GameObject Inventory1 =GameObject.Find("inventory1"); GameObject prefab = (GameObject)Instantiate(A); prefab.transform.SetParent(Inventory1.transform, false); } }
これによって落ちたアイテムをインベントリに取り込む事に成功しました。