我正在做一个拖放系统,但它没有像我想要的那样工作

问题描述 投票:0回答:1

确定这里的脚本

using System.Collections.Generic;
using System.Collections;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class InventoryManager : MonoBehaviour
{
    [SerializeField] private GameObject SlotHandler;
    [SerializeField] private ItemClass itemToAdd;
    [SerializeField] private ItemClass itemToRemove;

    [SerializeField] SlotClass[] startItems;
    SlotClass[] items;

    private GameObject[] Slots;

    private void Start()
    {
        Slots = new GameObject[SlotHandler.transform.childCount];
        items = new SlotClass[Slots.Length];

        for (int i = 0; i < items.Length; i++)
        {
            items[i] = new SlotClass();
        }
        for (int i = 0; i < startItems.Length; i++)
        {
            items[i] = startItems[i];
        }



        for (int i = 0; i < SlotHandler.transform.childCount; i++)
        {
            Slots[i] = SlotHandler.transform.GetChild(i).gameObject;
        }

        refreshUI();

        addItem(itemToAdd);
       removeItem(itemToRemove);
    }

    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Debug.Log(GetClosetSlot());
        }
    }

    #region Inventory Utils
    public void refreshUI()
    {
        for (int i = 0; i < Slots.Length; i++)
        {
           
            try
            {
               Slots[i].transform.GetChild(0).GetComponent<Image>().sprite = items[i].GetItem().itemSprite;
               Slots[i].transform.GetChild(0).GetComponent<Image>().enabled = true;
               Slots[i].transform.GetChild(1).GetComponent<TextMeshProUGUI>().text = items[i]._GetCantidad() + "";
               if (Slots[i].transform.GetChild(1).GetComponent<TextMeshProUGUI>().text == "1")
               {
                   Slots[i].transform.GetChild(1).GetComponent<TextMeshProUGUI>().text = string.Empty;
               }
            }
            catch
            {
               Slots[i].transform.GetChild(0).GetComponent<Image>().sprite = null;
               Slots[i].transform.GetChild(0).GetComponent<Image>().enabled = false;
               Slots[i].transform.GetChild(1).GetComponent<TextMeshProUGUI>().text = string.Empty;
            }
        }
    }
    public bool addItem(ItemClass item)
    {
        SlotClass slot = Contains(item);

        if (slot != null && slot.GetItem()._isStackable)
        {
            slot.MasCantidad(1);
        }
        else
        {
            for (int i = 0; i < items.Length; i++)
            {
                if (items[i].GetItem() == null)
                {
                    items[i].Addition(item, 1);
                    break;
                }
            }

   /*         if (items.Count < Slots.Length)
                items.Add(new SlotClass(item, 1));
            else
                return false;*/
        }

        refreshUI();
        return true;
    }
    public bool removeItem(ItemClass item)
    {
        SlotClass Temp = Contains(item);

        if (Temp != null)
        {
            if (Temp._GetCantidad() > 1)
            {
               Temp.menosCantidad(1);
            }
            else
            {
                int slotToRemoveIndex = 0;

                for (int i = 0; i < items.Length; i++)
                {
                    if (items[i].GetItem() == item)
                    {
                        slotToRemoveIndex = i;
                        break;
                    }
                }
                items[slotToRemoveIndex].clear();
            }

        }
        else
        { 
            return false; 
        }

        refreshUI();
        return true;
    } 
    public SlotClass Contains(ItemClass item)
    {
        for (int i = 0; i < items.Length; i++)
        {
            if (items[i].GetItem() == item)
            {
                return items[i];
            }
        }

        return null;
    }
    #endregion Invetory Utils

    #region Moving Stuff
    private SlotClass GetClosetSlot()
    {

        for (int i = 0; i < Slots.Length; i++)
        {
            if (Vector2.Distance(Slots[i].transform.position, Input.mousePosition) < -10)
                return items[i];
        }

        return null;
    }
    #endregion

问题是我想让 Unity 通过 GetClosetSlot() 函数读取 UI Planes,然后我将 debug.log 放入其中以告诉我鼠标的位置是否与我的 UI Plane 匹配,但我单击在 UI 平面之外,如果它正常工作,它会显示“Null”或什么都没有,直到你在它们内部单击并且你意识到它一直在说同样的话,“Null”并且一切都很好。

顺便说一句,我正在使用 unity 2021.3.23f1 LTS。

一切都和我正在看的视频几乎一样,但它不起作用,我无法证明任何事情,因为我不知道

c# unity3d
1个回答
1
投票

你不是在检查你的鼠标是否在某个 UI 项目的“内部”——你只是在检查

Vector2.Distance(Slots[i].transform.position, Input.mousePosition) < -10

这意味着您的光标距离该 UI 项目的pivot point 不能超过 10 个像素。

你宁愿使用

RectTransform[] Slots;
Camera camera;

并初始化一次

camera = Camera.main;

for (int i = 0; i < SlotHandler.transform.childCount; i++)
{
    Slots[i] = SlotHandler.transform.GetChild(i).GetComponent<RectTransform>();
}

或者您也可以使用

using System.Linq;

...

Slots = SlotHandler.transform.Cast<RectTransform>().ToArray();

然后你可以检查

for (int i = 0; i < Slots.Length; i++)
{
    var slot = Slots[i];
    
    if (RectTransformUtility.RectangleContainsScreenPoint(slot, Input.mousePosition, camera)
    {
        return items[i];
    }
}

顺便说一句,这样可以节省一些资源

for (int i = 0; i < items.Length; i++)
{
    items[i] = new SlotClass();
}
for (int i = 0; i < startItems.Length; i++)
{
    items[i] = startItems[i];
}

可以简化为

for (int i = 0; i < items.Length; i++)
{
    items[i] = i < startItems.Length ? startItems[i] : new SlotClass();
}

对于

refreshUI
,我还强烈建议为您的插槽设置一个专用组件,其中引用了所有进一步需要的组件。

这也可以让你在上面简单地做

Slots = SlotHandler.GetComponentsInChildren<YourSlotComponent>();
© www.soinside.com 2019 - 2024. All rights reserved.