Вторник, 19 Марта 2024, 12:57

Приветствую Вас Гость

Меню сайта
Категории каталога
Создание игр [354]
Статьи об общих понятиях связанных с созданием игр.
Программирование [82]
Гайды по программированию на разных ЯП.
Движки и Гейммейкеры [144]
Статьи о программах для создания игр, уроки и описания.
Софт [39]
Различные программы, в том числе в помощь игроделам.
2D-графика [14]
Уроки по рисованию, растр, пиксель-арт, создание спрайтов и пр.
3D-графика [16]
Уроки по моделированию, ландшафт, модели, текстурирование и пр.
Моддинг игр [5]
Модификация компьютерных игр, создание дополнений, перевод, хакинг.
Игры [160]
Статьи об играх, в том числе и сделанных на гейммейкерах.
Разное [128]
Статьи, которые не вошли в определённые разделы.
Наш опрос
На какие из этих игровые системы вы разрабатываете игры?
Всего ответов: 1646
Главная » Статьи » Создание игр

Создание drag&drop инвентаря в Unity с использованием UI(C#). Часть 1
Всем привет это снова я и мы снова будем делать инвентарь...
В прошлых мои уроках(раз, два) мы создавали инвентарь на GUI, но до конца я не довел тот цикл статей и продолжать уже не буду поскольку GUI уже не актуальный. В этой статье мы будем создавать drag&drop инвентарь на UI. Статья получилась большой, я постарался учесть все аспекты. Статья разбита на несколько частей:
Первая часть:
-Настройка инвентаря
-Создание инвентаря
-Tooltip

Вторая часть:
-Создание слотов
-Сундук с лутом


1. Настройка инвентаря
Для начала создадим Plane и источник света.


Теперь необходимо создать саму панель инвентаря. Создаем Panel и Text. Настраиваем их, как на скрине.
Переименовываем нашу Panel на "Inventory", а Text на "title".


Далее необходимо создать Button. Это и будет наш слот инвентаря. Настраиваем его, как на скрине. Называем нашу Button "InventorySlot".


Создаем из нашего слота префаб. И далее создаем шесть ячеек и делаем их дочерними к Inventory. Не стоит сейчас заморачиваться с настройкой их расположения, мы это потом исправим через код. Сделайте так, что бы между ячейками было некоторое расстояние.


Создаем из нашего префаба еще одну кнопку и называем ее DragIcon. Делаем ее дочерней к обьекту Canvas.


На этом с настройками все. Далее переходим к созданию кода.

2. Создание инвентаря
Создаем скрипт ItemDataBase. Открываем скрипт ItemDataBase в нашем редакторе кода. У меня это VisualStudio 2013, вам тоже советую ее использовать
Примечание: если кто не знает, как создать файл решения (.sln), тогда заходим в Assets - Sync Monodevelop Project
В этом классе, мы опишим основные данные предметов инвентаря.
Код

using UnityEngine;
using System.Collections;

[System.Serializable]
public class ItemDataBase{

  public string Name;//Имя
  public int Id;//Идентификатор сущности
  public string IconPatch;//путь к иконке
  [Multiline]public string Description;//описание предмета(tooltip)
}

Много данных, я думаю не требуется. Хватит и этого: названия предмета, иконки и его описания.
Примечание: изображение иконки нашего предмета мы будем загружать через Resources.Load() соответственно необходимо создать папку Resources.
Не забываем пометить класс атрибутом [System.Serializable].

Создаем скрипт ItemGenerator. Из названия думаю понятно, что в этом скрипте мы будем генерировать(создавать) наши обьекты инвентаря
Создаем две переменные:
Код

using UnityEngine;
using System.Collections.Generic;

public class ItemGenerator : MonoBehaviour {

  public static ItemGenerator _ItemGenerator;

  public List<ItemDataBase> ItemList = new List<ItemDataBase>();//список предметов

}

_ItemGenerator - экземпляр класса (используем паттерн SingleTon). ItemList - список в котором храним все наши обьекты инвентаря
Далее создаем метод в котором будем генерировать предметы
Код

using UnityEngine;
using System.Collections.Generic;

public class ItemGenerator : MonoBehaviour {

  public static ItemGenerator _ItemGenerator;

  public List<ItemDataBase> ItemList = new List<ItemDataBase>();//список предметов

  void Awake()
  {
  _ItemGenerator = this;//
  }

  //генерация предмета
  public ItemDataBase ItemGen(int win_id)
  {
  ItemDataBase item = new ItemDataBase();

  item.Name = ItemList[win_id].Name;
  item.Id = ItemList[win_id].Id;
  item.IconPatch = ItemList[win_id].IconPatch;
  item.Description = ItemList[win_id].Description;

  return item;
  }

}

Вешаем скрипт на нашу панель Inventory. Создаем папку Resources, если вы этого еще не сделали. Закидываем в нее три изображения с предметами и одно изображение, которое будет отвечать за иконку ячейки без предмета(пустой слот). Настраиваем их (изменяем тип на Sprite). Изображение отвечающее за пустую ячейку назовите "slot".



Далее создаем три предмета. IconPath это изображение(иконка) нашего предмета. В эту строку необходимо прописать путь к нашей иконке (которая лежит в папке Resources). По сути в эту строку мы пишем название нужного изображения без его расширений(.jpg,.png и т.д).


Следующий шаг - добавление тегов.
Панели Inventory добавляем тег "Inventory". Слотам - "InventorySlot". Обьекту Canvas тег "Canvas".

Создаем скрипт Inventory, в котором собственно и будет основная логика нашего инвентаря. Вешаем скрипт на панель Inventory и открываем его. Первым делом создаем константу типа string в которой будет храниться путь к изображению пустой ячейки (помните мы переименовали ее раньше в "slot"). Далее создаем переменную типа GameObject которая необходима нам будет при перемещении предметов. Следующая переменная типа ItemDataBase, в которой будет храниться наш обьект во время перемещения. Ну и последнее, список хранящий в себе все наши ячейки инвентаря.
Код

  const string DEFAULT_SLOT_IMAGE = "slot";//путь к дефолтному изображению ячейки инвентаря (пустая ячейка)

  public GameObject DragObj;
  public List<GameObject> InventorySlotsObj = new List<GameObject>(); //список хранящий в себе все слоты  
  public ItemDataBase DraggedObject;//обьект который мы перемещаем

Далее идут приватные переменные: dragItem - перемещаем ли обьект, mousePosition - позиция курсора(необходимо для отображение иконки при перемещении предметов) и две вспомогательные переменные типа RectTransform.
Код

  /*PrivateVariable*/
  private RectTransform canvasRect;
  private RectTransform dragObjRect;
  private RectTransform tipObjRect;

  private Vector3 mousePosition = Vector3.zero;//позиция курсора
  private Vector3 mouseToolPosition = Vector3.zero;//позиция курсора при отображении tooltip

  private bool dragItem;//возможно ли перемещение обьекта (перетаскивание обьектов)
  private bool tipObj;//видимость tooltip

  private string tooltipText;//tooltip

И последнее инкапсуляция поля dragItem, mousePosition, mouseToolPosition и tipObj.
Код

/*Свойства*/
  public bool DragItem//свойство dragItem
  {
  get { return dragItem; }
  }
  public Vector3 MousePosition//позиция отображения иконки при перетаскивании предмета в инвентаре (инкапсуляция mousePosition)
  {
  get
  {
  return new Vector3(mousePosition.x + 35 , mousePosition.y - 35 , mousePosition.z);
  }
  }

  public bool TipObj//свойство tipObj
  {
  get { return tipObj; }
  set { tipObj = value; }
  }

  public Vector3 MouseToolPosition//свойство mouseToolPosition
  {
  get
  {
  return new Vector3(mousePosition.x + 65 , mousePosition.y - 75 , mousePosition.z); ;
  }
   
  }


Создаем скрипт PlayerGeneralSetting и вешаем его на камеру (в общем нету разницы на какой обьект его вешать). В этом скрипте создаем всего одну переменных и словарь, который будет хранить данные о нашем инвентаре
Код

using UnityEngine;
using System.Collections.Generic;

public class PlayerGeneralSetting : MonoBehaviour {

  public static PlayerGeneralSetting _PlayerGenericSetting;

  public static Dictionary<int , ItemDataBase> _Inventory = new Dictionary<int , ItemDataBase>();//ИНВЕНТАРЬ!!!

  void Awake()
  {
  _PlayerGenericSetting = this;
  }
   
}


Создаем скрипт SlotEvent и вешаем его на префаб слота инвентаря. Открываем скрипт. Создаем три переменные: SlotNumber - номер ячейки, inventory, тут я думаю все понятно, click - находится ли курсор над ячейкой
Код

  public int SlotNumber;//номер ячейки

  private Inventory inventory;
  private Text debugText;//отображение текста при нажатии на пустую ячейку

  private bool click;//находится ли курсор над ячейкой

Далее необходимо для работы с EventSystems реализовать интерфейсы: IPointerClickHandler , IDragHandler , IPointerEnterHandler , IPointerExitHandler , IEndDragHandler , IDropHandler.
Код

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class SlotEvent : MonoBehaviour , IPointerClickHandler , IDragHandler ,
  IPointerEnterHandler , IPointerExitHandler ,
  IEndDragHandler , IDropHandler
{

  public int SlotNumber;//номер ячейки

  private Inventory inventory;
  private Text debugText;//отображение текста при нажатии на пустую ячейку

  private bool click;//находится ли курсор над ячейкой

  void Start()
  {
  inventory = GameObject.FindGameObjectWithTag("Inventory").GetComponent<Inventory>();
  debugText = GetComponentInChildren<Text>();
  }

  void Update()
  {

  }

  //Нажатие мышки по ячейке
  public void OnPointerClick(PointerEventData eventData)
  {
   
  }

  //Начало перемещения ячейки (движение при зажатой ЛКМ)
  public void OnDrag(PointerEventData eventData)
  {
   
  }

  //Курсор над ячейкоц
  public void OnPointerEnter(PointerEventData eventData)
  {
   
  }

  //Курсор НЕ над ячейкой
  public void OnPointerExit(PointerEventData eventData)
  {
   
  }

  //Конец перемещения ячейки
  public void OnEndDrag(PointerEventData eventData)
  {
   
  }

  //Отпуская ЛКМ
  public void OnDrop(PointerEventData eventData)
  {

  }
}


Создаем скрипт LootChest и вешаем его на Canvas. Покаместь так и оставляем его, как вы догадались в этом скрипте будет храниться вся логика сундука с лутом.

Возвращаемся к скрипту Inventory. Ниже будет приведен код скрипта с комментариями, я не буду все подробно описывать(это будет очень долго), там есть комментарии, думаю поймете.
Код

using UnityEngine;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;
using UnityEditor;

public class Inventory : MonoBehaviour {

  const string DEFAULT_SLOT_IMAGE = "slot";//путь к дефолтному изображению ячейки инвентаря (пустая ячейка)

  public GameObject DragObj;
  public List<GameObject> InventorySlotsObj = new List<GameObject>(); //список хранящий в себе все слоты  
  public ItemDataBase DraggedObject;//обьект который мы перемещаем
  //public GameObject EditorSlot;//обьект слота для эдитора

  /*Свойства*/
  public bool DragItem//свойство dragItem
  {
  get { return dragItem; }
  }
  public Vector3 MousePosition//позиция отображения иконки при перетаскивании предмета в инвентаре (инкапсуляция mousePosition)
  {
  get
  {
  return new Vector3(mousePosition.x + 35 , mousePosition.y - 35 , mousePosition.z);
  }
  }

  /*PrivateVariable*/
  private RectTransform canvasRect;
  private RectTransform dragObjRect;
  private RectTransform tipObjRect;

  private Vector3 mousePosition = Vector3.zero;//позиция курсора
  private Vector3 mouseToolPosition = Vector3.zero;//позиция курсора при отображении tooltip

  private bool dragItem;//возможно ли перемещение обьекта (перетаскивание обьектов)
  private bool tipObj;//видимость tooltip

  private string tooltipText;//tooltip

  void Awake()
  {
  canvasRect = GameObject.FindGameObjectWithTag("Canvas").GetComponent<RectTransform>();
  dragObjRect = DragObj.GetComponent<RectTransform>();

  //добавляем в список все обьекты с тегом InventorySlot
  InventorySlotsObj.AddRange(GameObject.FindGameObjectsWithTag("InventorySlot"));
  InventorySlotsObj.Reverse();
  }

  void Start()
  {
  //добавляем предметы в инвентарь
  PlayerGeneralSetting._Inventory.Add(0 , ItemGenerator._ItemGenerator.ItemGen(0));
  PlayerGeneralSetting._Inventory.Add(4 , ItemGenerator._ItemGenerator.ItemGen(1));

  createInventorySlots();
  }

  void Update()
  {
  //отображение иконки перетаскиваемой ячейки
  if (dragItem)
  {
  mousePosition = (Input.mousePosition - canvasRect.localPosition);

  dragObjRect.localPosition = MousePosition;
  }

   
  }

  //Создание ячеек инвентаря
  private void createInventorySlots()
  {
  int numberOfSlot = 0;//вспомогательная переменная для передачи номера ячейки

  for (int i = 0 ; i < InventorySlotsObj.Count ; i++)
  {
  InventorySlotsObj[i].GetComponentInChildren<Text>().text = i.ToString();//нумирация ячеек

  InventorySlotsObj[i].GetComponent<SlotEvent>().SlotNumber = numberOfSlot;//передаем номер ячейки

  numberOfSlot++;

  //отображение иконки ячейки
  if (PlayerGeneralSetting._Inventory.ContainsKey((i)))
  {
  InventorySlotsObj[(i)].GetComponent<Image>().sprite = Resources.Load<Sprite>(PlayerGeneralSetting._Inventory[(i)].IconPatch);
  }
  else
  {
  InventorySlotsObj[(i)].GetComponent<Image>().sprite = Resources.Load<Sprite>(DEFAULT_SLOT_IMAGE);
  }
  }
  }

  /// <summary>
  /// Изменяем свойства ячейки (добавляем и удаляем предметы инвентаря)
  /// </summary>
  /// <param name="key">номер слота</param>
  /// <param name="drag">перемещение ячейки</param>
  /// <param name="type">тип добавления предмета(добавление в инвентарь или в сундук)</param>
  private void slotsProperties(int key , bool drag , string type)
  {
  if (type == "inventory")
  {
  if (!drag)
  {
  dragItem = false;
  DraggedObject = null;
  DragObj.SetActive(false);
  }

  //изменяем изображение иконки ячейки при добавление предмета в нее
  if (PlayerGeneralSetting._Inventory.ContainsKey(key))
  {
  InventorySlotsObj[key].GetComponent<Image>().sprite = Resources.Load<Sprite>(PlayerGeneralSetting._Inventory[key].IconPatch);
  }
  else
  {
  InventorySlotsObj[key].GetComponent<Image>().sprite = Resources.Load<Sprite>(DEFAULT_SLOT_IMAGE);
  }
  }
  else if (type == "chest")
  {
  if (!drag)
  {
  dragItem = false;
  DraggedObject = null;
  DragObj.SetActive(false);
  }

  GameObject.FindGameObjectWithTag("Canvas").GetComponent<LootChest>().ChangeSlotIcon(key);

  }
  else
  {
  Debug.LogError("Не верно передан аргумент (Инвентарь)");
  }
  }

  //Публичный метод для изменения свойст ячеек
  public void ConditionSlots(int key , bool drag , string type)
  {
  slotsProperties(key , drag , type);
  }

  //Включаем возможность перетаскивать предмет
  public void DragObject(ItemDataBase item)
  {
  dragItem = true;
  DraggedObject = item;
  DragObj.SetActive(true);

  DragObj.GetComponent<Image>().sprite = Resources.Load<Sprite>(item.IconPatch);//иконка перетаскиваемого предмета
  }  
}


Переходим в скрипт SlotEvent и создадим возможность перемещать предметы в инвентаре. Опять же есть комментарии и я не буду здесь описывать, что мы делаем.
Код

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class SlotEvent : MonoBehaviour , IPointerClickHandler , IDragHandler ,
  IPointerEnterHandler , IPointerExitHandler ,
  IEndDragHandler , IDropHandler
{

  public int SlotNumber;//номер ячейки

  private Inventory inventory;
  private Text debugText;//отображение текста при нажатии на пустую ячейку

  private bool click;//находится ли курсор над ячейкой

  void Start()
  {
  inventory = GameObject.FindGameObjectWithTag("Inventory").GetComponent<Inventory>();
  debugText = GetComponentInChildren<Text>();
  }

  void Update()
  {

  }

  //Нажатие мышки по ячейке
  public void OnPointerClick(PointerEventData eventData)
  {
  if (PlayerGeneralSetting._Inventory.ContainsKey(SlotNumber) && !inventory.DragItem)
  Debug.Log(PlayerGeneralSetting._Inventory[SlotNumber].Name);
  else
  Debug.Log(debugText.text);
  }

  //Начало перемещения ячейки (движение при зажатой ЛКМ)
  public void OnDrag(PointerEventData eventData)
  {
  if (PlayerGeneralSetting._Inventory.ContainsKey(SlotNumber))
  {
  //перемещаем предмет за курсором
  inventory.DragObject(PlayerGeneralSetting._Inventory[SlotNumber]);
  PlayerGeneralSetting._Inventory.Remove(SlotNumber);
  inventory.ConditionSlots(SlotNumber , true , "inventory");
  }
  }

  //Курсор над ячейкоц
  public void OnPointerEnter(PointerEventData eventData)
  {
  if (!PlayerGeneralSetting._Inventory.ContainsKey(SlotNumber) && inventory.DragItem)
  {
  click = true;  
  }
  }

  //Курсор НЕ над ячейкой
  public void OnPointerExit(PointerEventData eventData)
  {
  if (!PlayerGeneralSetting._Inventory.ContainsKey(SlotNumber) && inventory.DragItem)
  {
  click = false;
  inventory.TipObj = false;
  }
  }

  //Конец перемещения ячейки
  public void OnEndDrag(PointerEventData eventData)
  {
  if (inventory.DraggedObject != null && inventory.DragItem)
  {
  PlayerGeneralSetting._Inventory.Add(SlotNumber , inventory.DraggedObject);
  inventory.ConditionSlots(SlotNumber , false , "inventory");
  }
  }

  //Отпуская ЛКМ
  public void OnDrop(PointerEventData eventData)
  {

  if (!PlayerGeneralSetting._Inventory.ContainsKey(SlotNumber) && inventory.DragItem && click)
  {
  //помещаем предмет в ячейку если она пустая
  PlayerGeneralSetting._Inventory.Add(SlotNumber , inventory.DraggedObject);
  inventory.ConditionSlots(SlotNumber , false , "inventory");
  }
  }
}


3. Tooltip
Переходим к созданию окна с всплывающей подсказкой(tooltip). Создаем Panel и Text. Переименовываем только что созданую Panel в "Tooltip" и делаем ее дочерним к Canvas, а Text дочерним к Tooltip.
Настраиваем их.


Возвращаемся к скрипту Inventory и вводим дополнительные переменные для работы с tooltip, а так же условие отображение tooltip.
Код

using UnityEngine;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;
using UnityEditor;
using System.Text;

public class Inventory : MonoBehaviour {

  const string DEFAULT_SLOT_IMAGE = "slot";//путь к дефолтному изображению ячейки инвентаря (пустая ячейка)

  public GameObject DragObj;
  public GameObject TooltipObj;
  public List<GameObject> InventorySlotsObj = new List<GameObject>(); //список хранящий в себе все слоты  
  public ItemDataBase DraggedObject;//обьект который мы перемещаем
  //public GameObject EditorSlot;//обьект слота для эдитора

  /*Свойства*/
  public bool DragItem//свойство dragItem
  {
  get { return dragItem; }
  }
  public Vector3 MousePosition//позиция отображения иконки при перетаскивании предмета в инвентаре (инкапсуляция mousePosition)
  {
  get
  {
  return new Vector3(mousePosition.x + 35 , mousePosition.y - 35 , mousePosition.z);
  }
  }

  public bool TipObj//свойство tipObj
  {
  get { return tipObj; }
  set { tipObj = value; }
  }

  public Vector3 MouseToolPosition//свойство mouseToolPosition
  {
  get
  {
  return new Vector3(mousePosition.x + 65 , mousePosition.y - 75 , mousePosition.z); ;
  }
   
  }

  /*PrivateVariable*/
  private RectTransform canvasRect;
  private RectTransform dragObjRect;
  private RectTransform tipObjRect;

  private Vector3 mousePosition = Vector3.zero;//позиция курсора
  private Vector3 mouseToolPosition = Vector3.zero;//позиция курсора при отображении tooltip

  private bool dragItem;//возможно ли перемещение обьекта (перетаскивание обьектов)
  private bool tipObj;//видимость tooltip

  private string tooltipText;//tooltip

  void Awake()
  {
  canvasRect = GameObject.FindGameObjectWithTag("Canvas").GetComponent<RectTransform>();
  dragObjRect = DragObj.GetComponent<RectTransform>();
  tipObjRect = TooltipObj.GetComponent<RectTransform>();

  //добавляем в список все обьекты с тегом InventorySlot
  InventorySlotsObj.AddRange(GameObject.FindGameObjectsWithTag("InventorySlot"));
  InventorySlotsObj.Reverse();
  }

  void Start()
  {
  //добавляем предметы в инвентарь
  PlayerGeneralSetting._Inventory.Add(0 , ItemGenerator._ItemGenerator.ItemGen(0));
  PlayerGeneralSetting._Inventory.Add(4 , ItemGenerator._ItemGenerator.ItemGen(1));

  createInventorySlots();
  }

  void Update()
  {
  //отображение иконки перетаскиваемой ячейки
  if (dragItem)
  {
  mousePosition = (Input.mousePosition - canvasRect.localPosition);

  dragObjRect.localPosition = MousePosition;
  }

  //отображение tooltip
  if (tipObj)
  {
  TooltipObj.SetActive(true);

  mousePosition = (Input.mousePosition - canvasRect.localPosition);

  tipObjRect.localPosition = MouseToolPosition;

  TooltipObj.GetComponentInChildren<Text>().text = tooltipText;
  }
  else
  {
  TooltipObj.SetActive(false);
  }
  }

  // присваиваем тексту tooltip значение
  public void TooltipText(int key)
  {
  tooltipText = PlayerGeneralSetting._Inventory[key].Description.ToString();
  }

  //Создание ячеек инвентаря
  private void createInventorySlots()
  {
  int numberOfSlot = 0;//вспомогательная переменная для передачи номера ячейки

  for (int i = 0 ; i < InventorySlotsObj.Count ; i++)
  {
  InventorySlotsObj[i].GetComponentInChildren<Text>().text = i.ToString();//нумирация ячеек

  InventorySlotsObj[i].GetComponent<SlotEvent>().SlotNumber = numberOfSlot;//передаем номер ячейки

  numberOfSlot++;

  //отображение иконки ячейки
  if (PlayerGeneralSetting._Inventory.ContainsKey((i)))
  {
  InventorySlotsObj[(i)].GetComponent<Image>().sprite = Resources.Load<Sprite>(PlayerGeneralSetting._Inventory[(i)].IconPatch);
  }
  else
  {
  InventorySlotsObj[(i)].GetComponent<Image>().sprite = Resources.Load<Sprite>(DEFAULT_SLOT_IMAGE);
  }
  }
  }

  /// <summary>
  /// Изменяем свойства ячейки (добавляем и удаляем предметы инвентаря)
  /// </summary>
  /// <param name="key">номер слота</param>
  /// <param name="drag">перемещение ячейки</param>
  /// <param name="type">тип добавления предмета(добавление в инвентарь или в сундук)</param>
  private void slotsProperties(int key , bool drag , string type)
  {
  if (type == "inventory")
  {
  if (!drag)
  {
  dragItem = false;
  DraggedObject = null;
  DragObj.SetActive(false);
  }

  //изменяем изображение иконки ячейки при добавление предмета в нее
  if (PlayerGeneralSetting._Inventory.ContainsKey(key))
  {
  InventorySlotsObj[key].GetComponent<Image>().sprite = Resources.Load<Sprite>(PlayerGeneralSetting._Inventory[key].IconPatch);
  }
  else
  {
  InventorySlotsObj[key].GetComponent<Image>().sprite = Resources.Load<Sprite>(DEFAULT_SLOT_IMAGE);
  }
  }
  else if (type == "chest")
  {
  if (!drag)
  {
  dragItem = false;
  DraggedObject = null;
  DragObj.SetActive(false);
  }

  GameObject.FindGameObjectWithTag("Canvas").GetComponent<LootChest>().ChangeSlotIcon(key);

  }
  else
  {
  Debug.LogError("Не верно передан аргумент (Инвентарь)");
  }
  }

  //Публичный метод для изменения свойст ячеек
  public void ConditionSlots(int key , bool drag , string type)
  {
  slotsProperties(key , drag , type);
  }

  //Включаем возможность перетаскивать предмет
  public void DragObject(ItemDataBase item)
  {
  dragItem = true;
  DraggedObject = item;
  DragObj.SetActive(true);

  DragObj.GetComponent<Image>().sprite = Resources.Load<Sprite>(item.IconPatch);//иконка перетаскиваемого предмета
  }  
}

Ссылка на полный скрипт Inventory - тык

Так же необходимо кое что изменить в скрипте SloEvent.
Код

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class SlotEvent : MonoBehaviour , IPointerClickHandler , IDragHandler ,
  IPointerEnterHandler , IPointerExitHandler ,
  IEndDragHandler , IDropHandler
{

  public int SlotNumber;//номер ячейки

  private Inventory inventory;
  private Text debugText;//отображение текста при нажатии на пустую ячейку

  private bool click;//находится ли курсор над ячейкой

  void Start()
  {
  inventory = GameObject.FindGameObjectWithTag("Inventory").GetComponent<Inventory>();
  debugText = GetComponentInChildren<Text>();
  }

  void Update()
  {

  }

  //Нажатие мышки по ячейке
  public void OnPointerClick(PointerEventData eventData)
  {
  if (PlayerGeneralSetting._Inventory.ContainsKey(SlotNumber) && !inventory.DragItem)
  Debug.Log(PlayerGeneralSetting._Inventory[SlotNumber].Name);
  else
  Debug.Log(debugText.text);
  }

  //Начало перемещения ячейки (движение при зажатой ЛКМ)
  public void OnDrag(PointerEventData eventData)
  {
  if (PlayerGeneralSetting._Inventory.ContainsKey(SlotNumber))
  {
  //перемещаем предмет за курсором
  inventory.DragObject(PlayerGeneralSetting._Inventory[SlotNumber]);
  PlayerGeneralSetting._Inventory.Remove(SlotNumber);
  inventory.ConditionSlots(SlotNumber , true , "inventory");
  }
  }

  //Курсор над ячейкоц
  public void OnPointerEnter(PointerEventData eventData)
  {
  if (!PlayerGeneralSetting._Inventory.ContainsKey(SlotNumber) && inventory.DragItem)
  {
  click = true;  
  }

  if (PlayerGeneralSetting._Inventory.ContainsKey(SlotNumber))
  {
  inventory.TipObj = true;
  inventory.TooltipText(SlotNumber);
  }
  }

  //Курсор НЕ над ячейкой
  public void OnPointerExit(PointerEventData eventData)
  {
  if (!PlayerGeneralSetting._Inventory.ContainsKey(SlotNumber) && inventory.DragItem)
  {
  click = false;
  inventory.TipObj = false;
  }

  if (PlayerGeneralSetting._Inventory.ContainsKey(SlotNumber))
  {
  inventory.TipObj = false;  
  }
  }

  //Конец перемещения ячейки
  public void OnEndDrag(PointerEventData eventData)
  {
  if (inventory.DraggedObject != null && inventory.DragItem)
  {
  PlayerGeneralSetting._Inventory.Add(SlotNumber , inventory.DraggedObject);
  inventory.ConditionSlots(SlotNumber , false , "inventory");
  }
  }

  //Отпуская ЛКМ
  public void OnDrop(PointerEventData eventData)
  {

  if (!PlayerGeneralSetting._Inventory.ContainsKey(SlotNumber) && inventory.DragItem && click)
  {
  //помещаем предмет в ячейку если она пустая
  PlayerGeneralSetting._Inventory.Add(SlotNumber , inventory.DraggedObject);
  inventory.ConditionSlots(SlotNumber , false , "inventory");
  }
  }
}

Ссылка на полный скрипт SlotEvent - тык
Пробуем навести курсор на предмет и у нас показывается окно с описанием.
Вторая часть статьи
Категория: Создание игр | Добавил: beril (03 Января 2015) | Автор: Шевченко Денис
Просмотров: 36323 | Комментарии: 5 | Рейтинг: 3.2/20 |
Теги: Drag&Drop, RPG, юнити, UI, Разработка игр, инвентарь, юнити уроки, Урок, Unity, C#
Дополнительные опции:
Также если вы считаете, что данный материал мог быть интересен и полезен кому-то из ваших друзей, то вы бы могли посоветовать его, отправив сообщение на e-mail друга:

Игровые объявления и предложения:
Если вас заинтересовал материал «Создание drag&drop инвентаря в Unity с использованием UI(C#). Часть 1», и вы бы хотели прочесть что-то на эту же тему, то вы можете воспользоваться списком схожих материалов ниже. Данный список сформирован автоматически по тематическим меткам раздела. Предлагаются такие схожие материалы: Если вы ведёте свой блог, микроблог, либо участвуете в какой-то популярной социальной сети, то вы можете быстро поделиться данной заметкой со своими друзьями и посетителями.

Всего комментариев: 5
+0-
5 кое-кто   (30 Апреля 2015 18:06) [Материал]
кое-ктоrespect

+1-
4 darkcerber   (09 Февраля 2015 20:03) [Материал]
darkcerberrespect

+0-
3 TLT   (03 Января 2015 21:34) [Материал]
TLTИнвентарь - всегда одна из сложных частей реализации.

+2-
2 beril   (03 Января 2015 21:32) [Материал]
berilЯ же писал, что не следует обращать на расположение ячеек внимание, мы дальше через код их будем все равно создавать

+-5-
1 EchoIT   (03 Января 2015 21:22) [Материал]
EchoITГлядя на расположение ячеек, мне так и хочется сказать что-то типа этого:

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Поиск по сайту
10 случ. движков
  • Sylphis 3D
  • Doom 3
  • Bitsy
  • PlayCanvas
  • GameLooper
  • SecondBASIC
  • OpenBOR
  • Luxe Engine
  • Glint 3d
  • NeoAxis Engine
  • Друзья сайта
    Игровой форум GFAQ.ru Перевод консольных игр
    Все права сохранены. GcUp.ru © 2008-2024 Рейтинг