Работа с инвентарём в C#
Создал инвентарь. Два скрипта под него. Сделал UI инвентаря, то есть слоты. К объекту Inventory прикреплён код Inventory. Ну классический инвентарь
Так же сделал вещь, к ней прикрепил код Item
Но никак не могу сделать так, что если бы инвентарь был полным (все два слота заняты), то брать больше нельзя. По разному писал и делал, готов удариться об стенку уже.
Игрок берет первую вещь - всё ок, но на вторую (для этого выводится лог) пишет "Инвентарь полный". Что при второй пустой ячейке - бред. для удобства нейронкой ввёл документацию
Даю два класса, Первый Inventory
using UnityEngine;
using UnityEngine.UI;
public class Inventory : MonoBehaviour
{
public bool[] isFull;
public GameObject[] slots;
public bool AddItem(Item item)
{
for (int i = 0; i < slots.Length; i++)
{
if (!isFull[i])
{
isFull[i] = true;
GameObject itemGO = Instantiate(item.itemPrefab, slots[i].transform);
// Настройка RectTransform для центрирования иконки
RectTransform rectTransform = itemGO.GetComponent<RectTransform>();
if (rectTransform == null)
{
rectTransform = itemGO.AddComponent<RectTransform>();
}
// Центрирование
rectTransform.anchorMin = new Vector2(0.5f, 0.5f);
rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
rectTransform.anchoredPosition = Vector2.zero;
// Установка размера иконки
rectTransform.sizeDelta = new Vector2(50, 50); // Измените размер по необходимости
// Убедимся, что масштаб равен 1
rectTransform.localScale = Vector3.one;
// Если у префаба есть Image компонент, убедимся, что он заполняет родительский объект
Image image = itemGO.GetComponent<Image>();
if (image != null)
{
image.preserveAspect = true;
}
return true; // Предмет успешно добавлен
}
}
return false; // Все слоты заполнены, предмет не добавлен
}
public bool IsInventoryFull()
{
foreach (bool slotFull in isFull)
{
if (!slotFull)
{
return false; // Найден пустой слот
}
}
return true; // Все слоты заполнены
}
}
Второй Item:
using UnityEngine;
public class Item : MonoBehaviour
{
public string itemName;
public float dropChance = 0.5f;
public int damageBonus = 5;
public GameObject itemPrefab;
public GameObject hintPrefab; // Префаб подсказки E
public float displayDistance = 2f;
public float itemHeight = 1f;
private GameObject itemInstance;
private GameObject hintInstance; // Экземпляр подсказки E
private Transform playerTransform;
private Camera mainCamera;
private void Start()
{
playerTransform = GameObject.FindGameObjectWithTag("Player").transform;
mainCamera = Camera.main;
itemInstance = Instantiate(itemPrefab, CalculateItemPosition(), Quaternion.identity);
itemInstance.SetActive(false);
// Создаем экземпляр подсказки E
hintInstance = Instantiate(hintPrefab, CalculateHintPosition(), Quaternion.identity);
hintInstance.SetActive(false);
}
private void Update()
{
float distanceToPlayer = Vector3.Distance(transform.position, playerTransform.position);
if (distanceToPlayer <= displayDistance)
{
ShowItem();
ShowHint();
CheckPickup();
}
else
{
HideItem();
HideHint();
}
if (itemInstance != null && itemInstance.activeSelf)
{
UpdateItemPosition();
}
if (hintInstance != null && hintInstance.activeSelf)
{
UpdateHintPosition();
}
}
private void ShowItem()
{
if (itemInstance != null && !itemInstance.activeSelf)
{
itemInstance.SetActive(true);
}
}
private void HideItem()
{
if (itemInstance != null && itemInstance.activeSelf)
{
itemInstance.SetActive(false);
}
}
private void ShowHint()
{
if (hintInstance != null && !hintInstance.activeSelf)
{
hintInstance.SetActive(true);
}
}
private void HideHint()
{
if (hintInstance != null && hintInstance.activeSelf)
{
hintInstance.SetActive(false);
}
}
private Vector3 CalculateItemPosition()
{
return transform.position + Vector3.up * itemHeight;
}
private Vector3 CalculateHintPosition()
{
return transform.position + Vector3.up * (itemHeight + 0.5f); // Подсказка немного выше предмета
}
private void UpdateItemPosition()
{
itemInstance.transform.position = CalculateItemPosition();
}
private void UpdateHintPosition()
{
hintInstance.transform.position = CalculateHintPosition();
hintInstance.transform.LookAt(hintInstance.transform.position + mainCamera.transform.rotation * Vector3.forward,
mainCamera.transform.rotation * Vector3.up);
}
private void CheckPickup()
{
if (Input.GetKeyDown(KeyCode.E))
{
PlayerController player = playerTransform.GetComponent<PlayerController>();
if (player != null)
{
Inventory inventory = player.GetComponent<Inventory>();
if (inventory != null)
{
if (!inventory.IsInventoryFull())
{
if (inventory.AddItem(this))
{
DestroyItemAndInstance();
}
}
else
{
Debug.Log("Инвентарь полон! Нельзя подобрать предмет.");
}
}
else
{
Debug.LogError("Компонент Inventory не найден на игроке!");
}
}
}
}
private void DestroyItemAndInstance()
{
if (itemInstance != null)
{
Destroy(itemInstance);
}
if (hintInstance != null)
{
Destroy(hintInstance);
}
Destroy(gameObject);
}
private void OnDestroy()
{
if (itemInstance != null)
{
Destroy(itemInstance);
}
if (hintInstance != null)
{
Destroy(hintInstance);
}
}
}
Ответы (1 шт):
Вопрос был решён путем обновления класса подбора вещи.
В инвентарь внес новый метод HasFreeSlot()
, а в самой вещи изменился немного метод проверки подбора.