LoginSignup
0
0

FarmRPG Unity Inventory&Item Part11  InventorySlotのハイライト線(赤線)を表示

Posted at

概要

今回はinventorySlotをドラッグ or クリックしたときにハイライトで強調されるようにします。

0606.gif

開発環境

IDE:Rider
Unity:2020.3.42(LTS)
OS:Windows10

UnityEditor上の設定

Slotのプレハブにハイライトをのオブジェクトをあることを確認します。
image.png

実装のポイント

共通

UIInventoryBarクラスについて
ClearHighlightOnInventorySlotsとSetHighlightedInventorySlotsメソッドを加えます。

ClearHighlightOnInventorySlotsメソッドは格InventorySlotクラスのisSelectedをfalseにしハイライト画像をのアルファ値を0(透明)にします。

SetHighlightedInventorySlotsメソッドは、UIInventorySlot.isSelected=trueの時ハイライトのアルファ値を255(不透明)にします。

UIInventorySlotクラスについて
bool型の変数isSelectedを加えます。trueのときはハイライトが表示されます。
SetSelectedItem、OnPointerClickメソッドを加えます。
SetSelectedItemはisSelected=trueをにします。
OnPointerClickはオブジェクトをクリックした時に実行されます。

ハイライトを表示する処理

ドラッグ時の処理

image.png

クリック時の処理

image.png

ハイライトを非表示にする処理

ドラッグを終了した時

image.png

ハイライトされているslotをクリックした場合

image.png

コード部分

UIInventorySlot

UIInventorySlot.cs
using TMPro;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class UIInventorySlot : MonoBehaviour,IBeginDragHandler,IDragHandler,IEndDragHandler,IPointerEnterHandler,IPointerExitHandler,IPointerClickHandler
{
    private Camera mainCamera;
    private Canvas parentCanvas;
    private GameObject draggedItem;
    private Transform parentItem;
    
    public Image inventorySlotHighlight;
    public Image inventorySlotImage;
    public TextMeshProUGUI textMeshProUGUI;
    [SerializeField] private UIInventoryBar inventoryBar = null;
    [SerializeField] private GameObject inventoryTextBoxPrefab = null;
    public ItemDetails itemDetails;
    [SerializeField] private GameObject itemPrefab;
    public int itemQuantity;
    [SerializeField] private int slotNumber = 0;
    [HideInInspector] public bool isSelected;

+    private void SetSelectedItem()
+    {
+        inventoryBar.ClearHighlightOnInventorySlots();
+        isSelected = true;
+        inventoryBar.SetHighlightedInventorySlots();
+    }

+    private void ClearSelectedItem()
+    {
+        inventoryBar.ClearHighlightOnInventorySlots();
+        isSelected = false;        
+    }
    
    private void DropSelectedItemAtMousePosition()
    {
        if (itemDetails != null)
        {
            Vector3 worldPosition = mainCamera.ScreenToWorldPoint(new Vector3(Input.mousePosition.x,
                Input.mousePosition.y, -mainCamera.transform.position.z));
            GameObject itemGameObject = Instantiate(itemPrefab, worldPosition, Quaternion.identity, parentItem);
            Item item = itemGameObject.GetComponent<Item>();
            item.ItemCode = itemDetails.itemCode;
            
            InventoryManager.Instance.RemoveItem(InventoryLocation.player, item.ItemCode);
        }
    }
    public void OnBeginDrag(PointerEventData eventData)
    {
        if (itemDetails != null)
        {
            Player.Instance.DisablePlayerInputAndResetMovement();
            draggedItem = Instantiate(inventoryBar.inventoryBarDraggedItem, inventoryBar.transform);

            Image draggedItemImage = draggedItem.GetComponentInChildren<Image>();
            draggedItemImage.sprite = inventorySlotImage.sprite;
            
+            SetSelectedItem();
        }
    }
    public void OnEndDrag(PointerEventData eventData)
    {
        if (draggedItem != null)
        {
            Destroy(draggedItem);
            if (eventData.pointerCurrentRaycast.gameObject != null && eventData.pointerCurrentRaycast.gameObject.GetComponent<UIInventorySlot>() != null)
            {
                int toSlotNumber = eventData.pointerCurrentRaycast.gameObject.GetComponent<UIInventorySlot>().slotNumber;

                InventoryManager.Instance.SwapInventoryItem(InventoryLocation.player, slotNumber, toSlotNumber);
                
                DestroyInventoryTextBox();
+                ClearSelectedItem();
            }
            else
            {
                if (itemDetails.canBeDropped)
                {
                    DropSelectedItemAtMousePosition();
                }
            }

            Player.Instance.EnablePlayerInput();
        }
    }

+    public void OnPointerClick(PointerEventData eventData)
+    {
+        if (eventData.button == PointerEventData.InputButton.Left)
+        {
+            if (isSelected == true)
+            {
+                ClearSelectedItem();
+            }
+            else
+            {
+                if (itemQuantity > 0)
+                {
+                    SetSelectedItem();
+                }
+            }
+        }
+    }
    
    }



UIInventoryBar

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


public class UIInventoryBar : MonoBehaviour
{
    [SerializeField] private Sprite blank16x16sprite = null;
    [SerializeField] private UIInventorySlot[] inventorySlot = null;
    public GameObject inventoryBarDraggedItem;
    [HideInInspector] public GameObject inventoryTextBoxGameObject;


+    public void ClearHighlightOnInventorySlots()
+    {
+        if (inventorySlot.Length > 0)
+        {
+            for (int i = 0; i < inventorySlot.Length; i++)
+            {
+                inventorySlot[i].isSelected = false;
+                inventorySlot[i].inventorySlotHighlight.color = new Color(0f, 0f, 0f, 0f);
+            }
+        }
+    }
    
    private void ClearInventorySlots()
    {
        if (inventorySlot.Length > 0)
        {
            for (int i = 0; i < inventorySlot.Length; i++)
            {
                inventorySlot[i].inventorySlotImage.sprite = blank16x16sprite;
                inventorySlot[i].textMeshProUGUI.text = "";
                inventorySlot[i].itemDetails = null;
                inventorySlot[i].itemQuantity = 0;  
+                SetHighlightedInventorySlots(i);                
            }
        }
    }
    
    
    private void InventoryUpdated(InventoryLocation inventoryLocation, List<InventoryItem> inventoryList)
    {
        if (inventoryLocation == InventoryLocation.player)
        {
            ClearInventorySlots();
            if (inventorySlot.Length > 0 && inventoryList.Count > 0)
            {
                for (int i = 0; i < inventorySlot.Length; i++)
                {
                    if (i < inventoryList.Count)
                    {
                        int itemCode = inventoryList[i].itemCode;
                        ItemDetails itemDetails = InventoryManager.Instance.GetItemDetails(itemCode);

                        if (itemDetails != null)
                        {
                            inventorySlot[i].inventorySlotImage.sprite = itemDetails.itemSprite;
                            inventorySlot[i].textMeshProUGUI.text = inventoryList[i].itemQuantity.ToString();
                            inventorySlot[i].itemDetails = itemDetails;
                            inventorySlot[i].itemQuantity = inventoryList[i].itemQuantity;
+                            SetHighlightedInventorySlots(i);

                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }
        } 
    }

+    public void SetHighlightedInventorySlots()
+    {
+        if (inventorySlot.Length > 0)
+        {
+            for (int i = 0; i < inventorySlot.Length; i++)
+            {
+                SetHighlightedInventorySlots(i);
+            }
+        }
+    }
+    public void SetHighlightedInventorySlots(int itemPosition)
+    {
+        if (inventorySlot.Length > 0 && inventorySlot[itemPosition].itemDetails != null)
+        {
+            if (inventorySlot[itemPosition].isSelected)
+            {
+                inventorySlot[itemPosition].inventorySlotHighlight.color = new Color(1f, 1f, 1f, 1f);                     
+            }
+        }
+    }
}


参考

C#

Unity Editor コンポーネント

Unity スクリプト

eventData.button

image.png

PointerEventData.InputButton.Left

image.png

OnPointerClick

image.png

Image.color

image.png

その他

Section 32 Select Items On The Inventory Bar

github コミット分(個人確認用 privateなので見れません)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0