英文:
I was doing a drag and drop system and it does not work as I want
问题
以下是代码的翻译部分:
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;
}
}
}
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
}
如果您有其他问题或需要进一步的帮助,请随时提出。
英文:
ok here the script
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
The problem is that I'm wanting to make unity read the UI Planes through the GetClosetSlot() function and I put a debug.log to it to tell me if the position of my mouse matches that of my UI Plane, but I click outside the UI Plane and if it works correctly it says "Null" or nothing, until you click inside them and you realize that it keeps saying the same thing, "Null" and everything is fine.
By the way I am using unity 2021.3.23f1 LTS.
everything is practically the same as the video I'm watching but it doesn't work and I can't prove anything because I don't know
答案1
得分: 1
你没有检查鼠标是否在特定的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。
这还使你可以简单地执行以下操作:
Slots = SlotHandler.GetComponentsInChildren<YourSlotComponent>();
英文:
You are not checking if your mouse is "within" a certain UI item - you are only checking if the
Vector2.Distance(Slots[i].transform.position, Input.mousePosition) < -10
which means your cursor would not be allowed to be more than 10 pixels away from the pivot point of that UI item.
You rather can use
RectTransform[] Slots;
Camera camera;
and initialize it once
camera = Camera.main;
for (int i = 0; i < SlotHandler.transform.childCount; i++)
{
Slots[i] = SlotHandler.transform.GetChild(i).GetComponent<RectTransform>();
}
or alternatively you could also use
using System.Linq;
...
Slots = SlotHandler.transform.Cast<RectTransform>().ToArray();
and then you can check for
for (int i = 0; i < Slots.Length; i++)
{
var slot = Slots[i];
if (RectTransformUtility.RectangleContainsScreenPoint(slot, Input.mousePosition, camera)
{
return items[i];
}
}
Btw to save some resources this
for (int i = 0; i < items.Length; i++)
{
items[i] = new SlotClass();
}
for (int i = 0; i < startItems.Length; i++)
{
items[i] = startItems[i];
}
can be simplified to
for (int i = 0; i < items.Length; i++)
{
items[i] = i < startItems.Length ? startItems[i] : new SlotClass();
}
For the refreshUI
I would also strongly recommend to rather have a dedicated component for your Slots where all the further required ones are referenced.
This would also allow you to above simply do
Slots = SlotHandler.GetComponentsInChildren<YourSlotComponent>();
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论