今回は持ち物画面で装備品スロットに持ち物から装備をドラッグ&ドロップ出来るようにします。
ただし、今のところ一度武器をセットしたら他の武器に変更する事は出来ますが、空にする事は出来ません。
またスロットに同じ武器を複数セットする事も可能ですが、同じ武器なので意味はありません。
正直なところ細かい所に手を入れる必要があります。
持ち物画面は、
で作成しました。
今回の機能を作成すると、
↑のような感じのものが作成出来ます。
まずは前回作った持ち物画面を修正します。
前回作った持ち物画面を修正
Panelの子要素にUI→Panelでパネルを作成し名前をEquipに変更します。
パネルの配置は上のような感じになります。
持ち物画面の概要
持っているアイテムを持ち物画面のMainパネルの子要素に表示するのは前回やりました。
今回はMainパネルの子要素に表示されたアイテムスロットをドラッグし、それを装備スロットにドロップする事で装備を変更するようにしていきます。
またドラッグ中にどのアイテムをドラッグしているかわかるようにドラッグ中のアイテムアイコンを表示するようにします。
装備品をドロップする装備スロットを作成
Equipの子要素にはスクリプトから装備品をドロップする為のスロットを4つ作成します。
Equipにはスロットを4つ縦に並べたいので、Add ComponentからLayout→Vertical Layout Groupを追加します。
設定値は上の画像のように設定します。
スロットEquipSlotを作成していきます。
Equipの子要素にUI→Panelでパネルを作成し、名前をEquipSlot1にしてその子要素にPanel、その子要素にTextを作成します。
PanelのAnchor Presetsからstretch stretchを選択します。
TextのAlignmentで右下になるように選択します。
EquipSlot1を選択した状態でCtrl+Dキーを押してコピーし名前の最後の番号を2~4に変更します。
それぞれの装備スロットの子要素のTextには1~4のそれぞれの番号を入れておきます。
↑のような感じに作成しました。
ドラッグ中に表示するゲームオブジェクトの作成
次にドラッグ中に表示するアイテムアイコン表示のゲームオブジェクトを作成していきます。
PropertyUI→Panelの子要素にPanelを作成し、名前をDragItemUIとします。
↑のような位置になります。
Imageの色を緑色にし、Raycast Targetのチェックを外し、このゲームオブジェクトではマウスイベントを発生させないようにします。
ここまで出来たらDragItemをAssetsフォルダにドラッグ&ドロップしプレハブにします。
プレハブにしたらヒエラルキー上のDragItemUIゲームオブジェクトは削除します。
DragItemDataスクリプト
DragItemDataスクリプトはドラッグしているアイテムが何のアイテムであるか?を保持しておく為のスクリプトです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | using UnityEngine; using System.Collections; using UnityEngine.UI; public class DragItemData : MonoBehaviour { // ドラッグしているアイテム private ItemData dragItemData; // ドラッグするアイテムデータをセット public void SetDragItem(ItemData dragItemData) { this.dragItemData = dragItemData; transform.GetComponent <Image>().sprite = dragItemData.GetItemSprite (); } // ドラッグしているアイテムデータの取得 public ItemData GetItem() { return dragItemData; } // ドラッグしているアイテムの消去 public void DeleteDragItem() { dragItemData = null; } // ドラッグアイテムが設定されている場合はマウスを追従 void Update() { if (dragItemData != null) { transform.position = Input.mousePosition; } } } |
ドラッグしているアイテムはdragItemDataに保持します。
SetDragItemメソッドはPropertySlotでドラッグが開始された時に呼び出すメソッドでここでアイテムを設定します。
DragItemDataスクリプトはDragItemゲームオブジェクトに設定するのでImageコンポーネントを取得し、そのスプライトにドラッグするアイテムのスプライトを設定します。
ドラッグするアイテムデータがある時はドラッグゲームオブジェクトをマウスポインタに追従するようにします。
ProcessingSlotプレハブの修正
ProcessingSlotの設定や取り付けたスクリプトの修正を行います。
ProcessingSlotスクリプトの修正
前回アイテムスロットのマウス処理を記述したProcessingSlotスクリプトを修正します。
1 2 3 4 5 6 7 | // ドラッグするUIプレハブ [SerializeField] private GameObject dragItemUI; // ドラッグしているUIインスタンス private GameObject dragItemUIInstance; |
dragItemUIは先ほど作成したDragItemUIプレハブを設定します。
dragItemUIInstanceはDragItemUIをインスタンス化したものを入れます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public void MouseBeginDrag() { if (myItemData.GetItemType() == ItemDataBase.ItemType.Sword || myItemData.GetItemType() == ItemDataBase.ItemType.Gun ) { dragItemUIInstance = Instantiate<GameObject>(dragItemUI, Input.mousePosition, Quaternion.identity, transform.parent.parent); dragItemUIInstance.GetComponent<DragItemData>().SetDragItem(myItemData); } } public void MouseEndDrag() { Destroy(dragItemUIInstance); } |
マウスドラッグが開始されたらMouseBeginDragメソッドを呼び出すようにします。
装備スロットにドラッグ出来るアイテムは打撃や射撃が出来るアイテムに限定する為、条件を設定します。
条件に合致した場合はdragItemUIをマウスの位置にインスタンス化し、dragItemUIInstanceの親をPropertyUI→Panelにします。
DragItemUIをインスタンス化したらDragItemUIに設定しているDragItemDataスクリプトのSetDragItemメソッドを呼び出しアイテム情報をセットします。
マウスドラッグが終了した時にMouseEndDragメソッドを呼び出すようにし、そこではdragItemUIInstanceを削除しています。
ProcessingSlotプレハブの設定の修正
ProcessingSlotプレハブにマウスドラッグの設定等を施します。
dragItemUIにDragItemUIプレハブを設定し、Event TriggerにBegin DragとEnd Dragのイベントを追加し、先ほど作成したそれぞれに対応するメソッドを指定します。
これでアイテムスロットでドラッグするとDragItemUIがインスタンス化され、アイコンにそのアイテムのアイコンが表示されます。
EquipSlotのマウス処理スクリプトの作成
EquipSlot1~4を作成しましたが、アイテムスロットでドラッグしたアイテムをEquipSlot(装備スロット)でドロップした時にそのアイテムをEquipSlotに設定する処理を作成してきます。
EquipSlot1~4にProcessingEquipSlotスクリプトを作成し取り付けます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | using UnityEngine; using System.Collections; using UnityEngine.UI; public class ProcessingEquipSlot : MonoBehaviour { private ItemData myItemData; [SerializeField] private Text informationText; public void MouseOver() { if (myItemData != null) { ShowInformation(); } } public void MouseExit() { if (myItemData != null) { informationText.text = ""; } } // スロットの上にアイテムがドロップされた時に実行 public void MouseDrop() { if (FindObjectOfType<DragItemData>() == null) { return; } // DragItemUIに設定しているDragItemDataスクリプトからアイテムデータを取得 var dragItemData = FindObjectOfType<DragItemData>(); myItemData = dragItemData.GetItem(); // ドラッグしているアイテムデータの削除 dragItemData.DeleteDragItem(); ShowInformation(); } void ShowInformation() { // アイテムイメージを設定 transform.GetChild(0).GetComponent<Image>().sprite = myItemData.GetItemSprite(); // スロットのTextを取得し名前を設定 var nameUI = GetComponentInChildren<Text>(); nameUI.text = myItemData.GetItemName(); // アイテム情報を表示する var text = "<Color=white>" + myItemData.GetItemName() + "</Color>\n"; text += myItemData.GetItemInformation(); informationText.text = text; } } |
myItemDataにはこの装備スロットに設定されているアイテムの情報を保持します。
informationTextはアイテム情報を表示するテキストUIを設定します。
MouseOver、MouseExitは装備スロットにマウスポインタが入ったり出ていったりした時にmyItemData(装備スロットにアイテムがあれば)情報を表示したり消したりします。
MouseDropは装備スロットでマウスボタンを離した時に実行させます。
DragItemDataスクリプトはゲームシーンに1つしか存在しないのでFindObjectOfTypeで全体から検索します。
存在しなければ何もしません。
DragItemDataがあればそこからアイテム情報を取得し、DragItemDataのアイテム情報を削除します。
ShowInformationメソッドではアイテム情報からスプライトや名前、情報を取得し、それを装備スロットのスプライトやテキストUIにアイテム名を表示します。
EquipSlot1~4のAdd ComponentからEvent→Event Triggerを取り付けます。
マウスイベントに合わせて先ほど作成したスクリプトのメソッドを呼び出します。
ここで注意しなければいけないのはEquipSlot1~4それぞれ自身に設定したProcessingEquipSlotスクリプトのメソッドを呼び出すようにしないといけません。
最終的なPropertyUIは
↑のような階層になり、最初は非アクティブにしておきます。
終わりに
今回は持ち物画面のアイテムスロットから攻撃出来るアイテムをドラッグし、持ち物画面内の装備スロットを変更するという機能を作成しました。
後は装備スロットに設定した武器を管理するようにし、ゲームシーン内に装備スロットを表示するようにしてゲーム内で特定のキーを押してその中から武器を選ぶようにすれば、新しい武器切り替えシステムが完成します。
そうなると装備スロットの装備武器を切り替える度に、ItemDataに対応する武器のプレハブをインスタンス化するという処理が必要になってきますね。
これまた面倒臭そうです・・・・・(;一_一)