unity3d 我正在做一个拖放系统,它不工作,因为我想

vmdwslir  于 2023-04-21  发布在  其他
关注(0)|答案(1)|浏览(156)

好的,这里是脚本

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平面,我给它放了一个debug.log来告诉我鼠标的位置是否与UI平面的位置匹配,但是我在UI平面之外单击,如果它正常工作,它会显示“Null”或什么都没有,直到你在它们内部单击,你意识到它一直在说同样的事情,“Null”,一切都很好。
使用Unity 2021.3.23f1 LTS。
一切都是几乎一样的视频我看,但它不工作,我不能证明任何事情,因为我不知道

zsohkypk

zsohkypk1#

您不是在检查鼠标是否“在”某个UI项中-您只是在检查

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

这意味着您的光标与该UI项的枢轴点之间的距离不允许超过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>();

相关问题