Как узнать, какой двигают объект мышкой (по событию OnDrag), не зная о самом объекте ничего кроме скрипта на нем?
У меня есть объекты в инвентаре, которые я могу перетаскивать. У них есть события OnBeginDrag, OnDrag, OnEndDrag. Также есть скрипт ячейки инвентаря, у которой есть событие OnPointerEnter, и в этом событии я хочу реализовать вот такой код:
public class MainCell : MonoBehaviour, IDropHandler, IPointerEnterHandler
{
public void OnPointerEnter(PointerEventData eventData)
{
InventoryItem item = eventData.pointerEnter.GetComponent<InventoryItem>() ? eventData.pointerDrag.GetComponent<InventoryItem>() : null;
if (item)
{
Color colorCell = CheckCellFree(this, item.size) ? Color.green : Color.red;
for (int y1 = y; y1 <= x + item.size.y; y1++)
for (int x1 = x; x1 <= x + item.size.x; x1++)
if (inventory.cells[x, y])
inventory.cells[x, y].image.color = colorCell;
}
}
}
Но это не работает потому, что в третьей строчке постоянно null, т.к. при перемещении объекта мышкой он к самой мышке не присоединяется! Короче говоря, в eventData, если я правильно понял, ничего не передается.
Я не хочу создавать ещё один лишний статический скрипт, в него передавать Item, и из него этот item отправлять в скрипт ячейки, хочется сделать это без стороннего вмешательства.
Я пробовал создать свой Action для решения проблемы, однако понял, что это не совсем то, что нужно.
По сути говоря, все, что нужно - переправить переменную item из скрипта ниже в такую же переменную скрипта выше, не создавая лишние классы, которые будут их связывать. Причем сама ячейка (MainCell) не должна знать о существовании объекта вовсе (имею ввиду через инспектор).
public abstract class InventoryItem : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler, IDropHandler
{
public InventoryItem item;
public virtual void OnBeginDrag(PointerEventData eventData)
{
item = this;
...
}
public void OnDrag(PointerEventData eventData)
{
...
}
public virtual void OnEndDrag(PointerEventData eventData)
{
item = null;
...
}
}
Помогите плиз, и не ставьте дизы вопросу, хотя бы не пояснив, почему) Буду очень благодарен.
(Дополнение для наглядности - фото ниже. Белые клетки с номерами - ячейки инвентаря. Объекты (оружия и квадраты) сверху - Item-ы. При перетаскивании объекта над определённой клеткой в эту самую клетку должен отрпавиться размер Item-а.)
Ответы (2 шт):
Как простой вариант - перенеси логику работы в класс самой кнопки (кажется это InventoryItem), пусть сама кнопка красит клетки, ищет их по необходимости.
Хотя по уму логикой перемещения предметов должна управлять более высоко стоящая сущность нежели кнопка или клетка инвентаря. Например, ею может быть сам инвентарь - он знает и о кнопках, и о клетках - они лежат ниже его по иерархии. Кнопки и клетки должны просто информировать инвентарь через события "меня тащат", "меня кликнули", "меня отпустили" и так далее, а уже инвентарь делать всю работу.
(Новые ответы до сих пор принимаются! Это - лишь один из кривых вариантов)
Вот какой вариант решения есть (Не совсем точный, но все же) - передать определённые значения в клетку под Item-ом, а не весь класс. PlayerPrefs или же сериализация в XML (Что более глупо, но до сих пор все ещё возможно) - не важно.
- Например, мне нужно отправить размер объекта (пускай 3-4 (x = 3, y = 4))
Я просто сохраняю в PlayerPrefs либо 34 (В методе OnBeginDrag), и потом разбиваю на разные числа ( 3 и 4 ), и делаю по ним последующие нужные вещи, либо создаю две переменные, и по отдельности закидываю x и y.
Далее в методе OnEndDrag я сохраняют в те же самые переменные PlayerPrefs 0, что означает отсутствие переносимого предмета вовсе. Костыль, однако работает.