Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 统一库存系统堆栈系统_C#_Json_Unity3d_Stack_Inventory - Fatal编程技术网

C# 统一库存系统堆栈系统

C# 统一库存系统堆栈系统,c#,json,unity3d,stack,inventory,C#,Json,Unity3d,Stack,Inventory,我已经使用C在Unity中创建了一个库存系统。目前,我的库存中有一个简单的堆栈系统,如果一个项目大于堆栈,它将停止将其添加到当前库存槽中。但我想知道如何设置它,以便在另一个插槽已满时将同一项目的实例添加到另一个插槽 这是我的代码,如果你们需要我分享更多的课程,请告诉我,任何帮助都将不胜感激 /** * Controller class used to handle the logic and functionality of the inventory system **/ using

我已经使用C在Unity中创建了一个库存系统。目前,我的库存中有一个简单的堆栈系统,如果一个项目大于堆栈,它将停止将其添加到当前库存槽中。但我想知道如何设置它,以便在另一个插槽已满时将同一项目的实例添加到另一个插槽

这是我的代码,如果你们需要我分享更多的课程,请告诉我,任何帮助都将不胜感激

/**
 * Controller class used to handle the logic and functionality of the 
inventory system
 **/

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

public class InventoryController : MonoBehaviour
{

Inventory inv;
ItemDatabase database;
public int maxSize = 3;

private void Awake()
{
    database = GetComponent<ItemDatabase>();
    inv = GetComponent<Inventory>();

    inv.slotAmount = 25;
    inv.background = GameObject.Find("SlotBackgroundPanel");
    inv.slotPanel = inv.background.transform.Find("SlotPanel").gameObject;
    for (int i = 0; i < inv.slotAmount; i++)
    {
        inv.items.Add(new InventoryModel());
        inv.slots.Add(Instantiate(inv.inventorySlot));
        inv.slots[i].GetComponent<ItemSlot>().id = i;
        inv.slots[i].transform.SetParent(inv.slotPanel.transform);
    }
}

public void AddItem(int id)
{
    InventoryModel itemToAdd = database.FetchItemByID(id);
    if (itemToAdd.Stackable && CheckItemInInventory(itemToAdd))
    {
        for (int i = 0; i < inv.items.Count; i++)
        {
            if (inv.items[i].ID == id)
            {

                ItemData data = inv.slots[i].transform.GetChild(0).GetComponent<ItemData>();
                data.amount++;
                data.transform.GetChild(0).GetComponent<Text>().text = data.amount.ToString();
                break;
            }
        }
    }

    else
    {
        for (int i = 0; i < inv.items.Count; i++)
        {
            if (inv.items[i].ID == -1)
            {
                inv.items[i] = itemToAdd;
                GameObject itemObj = Instantiate(inv.inventoryItem);
                itemObj.GetComponent<ItemData>().inventoryModel = itemToAdd;
                itemObj.GetComponent<ItemData>().amount = 1;
                itemObj.GetComponent<ItemData>().slot = i;
                itemObj.transform.SetParent(inv.slots[i].transform);
                itemObj.transform.position = Vector2.zero;
                itemObj.GetComponent<Image>().sprite = itemToAdd.Sprite;
                itemObj.name = itemToAdd.Title;
                break;
            }
        }
    }
}

public void RemoveItem(int id)
{
    InventoryModel itemToRemove = database.FetchItemByID(id);
    if (itemToRemove.Stackable && CheckItemInInventory(itemToRemove))
    {

        for (int j = 0; j < inv.items.Count; j++)
        {
            if (inv.items[j].ID == id)
            {
                ItemData data = inv.slots[j].transform.GetChild(0).GetComponent<ItemData>();
                data.amount--;
                data.transform.GetChild(0).GetComponent<Text>().text = data.amount.ToString();
                if (data.amount == 0)
                {
                    Destroy(inv.slots[j].transform.GetChild(0).gameObject);
                    inv.items[j] = new InventoryModel();
                    break;
                }
                if (data.amount == 1)
                {
                    inv.slots[j].transform.GetChild(0).transform.GetChild(0).GetComponent<Text>().text = "";
                    break;
                }
                break;
            }
        }
    }
    else
    {
        for (int i = 0; i < inv.items.Count; i++)
        {
            if (inv.items[i].Title == null && inv.items[i].ID == id)
            {
                Destroy(inv.slots[i].transform.GetChild(0).gameObject); inv.items[i] = new InventoryModel();
                break;
            }
        }

    }
}

public void FullItem(int id)
{
    InventoryModel itemIsFull = database.FetchItemByID(id);
    if (itemIsFull.Stackable && CheckItemInInventory(itemIsFull))
    {
        for (int y = 0; y < inv.items.Count; y++)
        {
            if (inv.items[y].ID == id)
            {
                ItemData data = inv.slots[y].transform.GetChild(0).GetComponent<ItemData>();
                data.transform.GetChild(0).GetComponent<Text>().text = data.amount.ToString();

                if (data.amount >= maxSize)
                {
                    inv.slots[y].transform.GetChild(0).transform.GetChild(0).GetComponent<Text>().text = "3";
                    data.amount = 3;
                    Debug.Log(data.amount);
                    break;
                }
            }
        }
    }
}

public bool CheckItemInInventory(InventoryModel inventoryModel)
{
    for (int i = 0; i < inv.items.Count; i++)
        if (inv.items[i].Title == inventoryModel.Title)
            return true;
    return false;
}
}

啊,我记得我在制作库存系统时遇到过这个问题。我做了一个类似于Minecraft的,基于槽的拖放。。等任何人丢失了源代码华。 我真的,真的很无聊,所以我决定复制您的代码,并添加一个函数来检查项目的数量是否小于最大堆栈大小。看一看:

InventoryModel itemToAdd = database.FetchItemByID(id);

    // First check if the item is in the inventory
    // This check can be discarded. See below...
    // You might be able to use this check in some form of anti-cheat system, so I've left it there.

    if (CheckItemInInventory(itemToAdd))
    {
        // Iterate through the inventory and check items against their ID/Name
        for (int i = 0; i < inv.items.Count; i++)
        {
            // If the item in the slot has the same ID as the item we want to add...

            if (inv.items[i].ID == id)
            {
                // Check if the item is actually stackable and the slot is not full
                // I.E the stack size (amount) is less than the max stack size.

                // You'll need to add a new variable to your InventoryModel class
                // int maxStackSize

                if (inv.items[i].amount < inv.items[i].maxStackSize && itemToAdd.Stackable)
                {
                    ItemData data = inv.slots[i].transform.GetChild(0).GetComponent<ItemData>();
                    data.amount++;
                    data.transform.GetChild(0).GetComponent<Text>().text = data.amount.ToString();
                    break;
                }
                // If not, then we skip adding a new item because this slot is already occupied and it's stack size is full
            }
            else if (inv.items[i].id == -1)
            {
                // If we encounter an empty slot, add a new item.
                inv.items[i] = itemToAdd;
                GameObject itemObj = Instantiate(inv.inventoryItem);
                itemObj.GetComponent<ItemData>().inventoryModel = itemToAdd;
                itemObj.GetComponent<ItemData>().amount = 1;
                itemObj.GetComponent<ItemData>().slot = i;
                itemObj.transform.SetParent(inv.slots[i].transform);
                itemObj.transform.position = Vector2.zero;
                itemObj.GetComponent<Image>().sprite = itemToAdd.Sprite;
                itemObj.name = itemToAdd.Title;
            }
        }
        // If the code's execution reaches this point, then we are essentially skipping action on the slot.
        // This means that we were not able to find an item that matched the ID OR the stack size was full...
        // So we keep scanning the other slots next in line...
    }
    else
    {
        // do something if the player tried to add an item but it does not exist in their inventory
        // or something doesn't quite add up... Good for anti-cheat systems.
    }
如您所见,我对您的代码进行了一些调整和优化,包括删除了一些冗余检查。你检查了玩家的库存两次。一次验证他们是否拥有该项目,然后再次将该项目添加到库存中。你可以一下子完成这两项任务。
我还应该提到,我是在VisualStudio中编写代码的,所以它应该适合复制粘贴。享受吧

您不能在库存模型中设置一个可变金额,并检查inv.items[i].ID==ID&&inv.items[i].amount时的位置吗
    /**
 * Model class used to handle and store variables
 **/

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class InventoryModel
{
public int ID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public bool Stackable { get; set; }
public string Slug { get; set; }
public Sprite Sprite { get; set; }

public InventoryModel(int id, string title, string description,
    bool stackable, string slug)
{
    this.ID = id;
    this.Title = title;
    this.Description = description;
    this.Stackable = stackable;
    this.Slug = slug;

    this.Sprite = Resources.Load<Sprite>("Sprites/Items/" + slug);
}

public InventoryModel()
{
    this.ID = -1;
}
}
[
{
"id" : 0,
"title" : "Diamond",
"value" : 5,
"stats":{
    "defence": 9,
    "power" : 8,
    "weight" : 5
    },
"description": "Mined Diamond is stronger than metal",
"stackable" : true,
"rarity" : 10,
"slug": "Diamond"
},

{
"id" : 1,
"title" : "Iron",
"value" : 2,
"stats":{
    "defence" : 5,
    "power" : 6,
    "weight" : 7
},
"description" : "Mined Iron is stronger than bronze",
"stackable" : false,
"rarity" : 6,
"slug" : "Metal"
},

{
"id" : 2,
"title" : "Gold",
"value" : 2,
"stats":{
    "defence" : 0,
    "power" : 0,
    "weight" : 0
},
"description" : "Gold is valuable",
"stackable" : false,
"rarity" : 10,
"slug" : "Gold"
},

{
"id" : 3,
"title" : "Fuel2",
"value" : 2,
"stats":{
    "defence" : 0,
    "power" : 0,
    "weight" : 0
    },
"description" : "Fuel is needed for ship engines",
"stackable" : true,
"rarity" : 2,
"slug" : "Fuel2"
}


]
InventoryModel itemToAdd = database.FetchItemByID(id);

    // First check if the item is in the inventory
    // This check can be discarded. See below...
    // You might be able to use this check in some form of anti-cheat system, so I've left it there.

    if (CheckItemInInventory(itemToAdd))
    {
        // Iterate through the inventory and check items against their ID/Name
        for (int i = 0; i < inv.items.Count; i++)
        {
            // If the item in the slot has the same ID as the item we want to add...

            if (inv.items[i].ID == id)
            {
                // Check if the item is actually stackable and the slot is not full
                // I.E the stack size (amount) is less than the max stack size.

                // You'll need to add a new variable to your InventoryModel class
                // int maxStackSize

                if (inv.items[i].amount < inv.items[i].maxStackSize && itemToAdd.Stackable)
                {
                    ItemData data = inv.slots[i].transform.GetChild(0).GetComponent<ItemData>();
                    data.amount++;
                    data.transform.GetChild(0).GetComponent<Text>().text = data.amount.ToString();
                    break;
                }
                // If not, then we skip adding a new item because this slot is already occupied and it's stack size is full
            }
            else if (inv.items[i].id == -1)
            {
                // If we encounter an empty slot, add a new item.
                inv.items[i] = itemToAdd;
                GameObject itemObj = Instantiate(inv.inventoryItem);
                itemObj.GetComponent<ItemData>().inventoryModel = itemToAdd;
                itemObj.GetComponent<ItemData>().amount = 1;
                itemObj.GetComponent<ItemData>().slot = i;
                itemObj.transform.SetParent(inv.slots[i].transform);
                itemObj.transform.position = Vector2.zero;
                itemObj.GetComponent<Image>().sprite = itemToAdd.Sprite;
                itemObj.name = itemToAdd.Title;
            }
        }
        // If the code's execution reaches this point, then we are essentially skipping action on the slot.
        // This means that we were not able to find an item that matched the ID OR the stack size was full...
        // So we keep scanning the other slots next in line...
    }
    else
    {
        // do something if the player tried to add an item but it does not exist in their inventory
        // or something doesn't quite add up... Good for anti-cheat systems.
    }