首页 文章

RPG库存物品堆叠C#Unity 3d

提问于
浏览
0

一般来说,我对编程和团结还很新 . 我确信问题与统一没有任何关系,因为项目中只有脚本没有统一对象 .

据说我无法更新库存中的数量/堆积和项目 . 所以我有一个拖放系统 . 当我拖动和项目到另一个项目,我希望它堆叠 . 据我所知,我正确行事但由于某种原因,它将新堆栈设置为库存中与我想要堆叠的项目相同的所有项目 .

例如,我在库存中有三个相同的药水,但它们都在自己的插槽中 . 我将一种魔药拖到另一种魔药上 . 我现在在插槽2上有一堆两个药水 . 但是插槽3中的药水也有一堆2个药水 . 我不知道这个问题来自哪里 .

首先,我试图让一切工作,然后我会使事情更有效率 . 这意味着一旦我想到这一点,我将把它转换为baseItem类 .

所以这是我的Item类

public class Item{

private string itemName;
private int itemID;

private int itemStack;
private int itemMaxStack;


#region Getters and Setters

public string Name
{
    get { return itemName; }
}

public int ID
{
    get { return itemID; }
}

public int Stack
{
    get { return itemStack; }
    set { itemStack = value; }
}

public int MaxStack
{
    get { return itemMaxStack; }
}


 #region Constructors
public Item ()
{
    itemName = string.Empty;

    itemID = 0;
    itemStack = 0;
    itemMaxStack = 0;

}

public Item (string name, int id,  int stack,
    int maxstack)
{
    itemName = name;
    itemID = id;
    itemStack = stack;
    itemMaxStack = maxstack;

}
#endregion

接下来是我的通用库存类

public class Inventory : MonoBehaviour 
{
    public int slotsX; // Number of slots on the X axis. Total slots in inventory is slotsX * slotsY
    public int slotsY; // Number of slots on the Y axis. Total slots in inventory is slotsX * slotsY
    private int slotWidth, slotHeight; // The Width and Height of the slots.
    private int iconWidth, iconHeight; // The Width and Height of the icons in the slots.
    private int iconPaddingX, iconPaddingY; // Adds padding to icons in the inventory so that it is center on the X and Y.
    public GUISkin skin; // The GUI skin for the inventory
    public List<Item> slots = new List<Item>(); // List Array that holds all the slots as Items
    public List<Item> inventory = new List<Item>(); // List Array that holds all the Items;
    private ItemDatabase database; // The database of all the items in the game

    private bool draggingItem; // Checks to see if the item is being dragged in the Inventory
    private string tooltip; // The string that contains all the content displayed in the tooltip.

    private int prevIndex; // Holds index of previous dragged item used for swapping items

    private Item draggedItem; // Holds the Item thats is being dragged in the inventory.


    // Use this for initialization
    void Start () 
    {
        database = GameObject.FindGameObjectWithTag("Item Database").GetComponent<ItemDatabase>();

        slotWidth = slotHeight = 50;
        iconWidth = iconHeight = 40;
        iconPaddingX = 6;
        iconPaddingY = 6;

        InitializeSlots();

        AddItem(1);
        AddItem(2);
        AddItem(2);
        AddItem(2);

    }


     void InitializeSlots ()
    {
        for (int i = 0; i < (slotsX*slotsY); i++)
        {
            slots.Add(new Item());
            inventory.Add(new Item());
        }
    }

    void OnGUI()
    {
        e = Event.current;
        tooltip = "";
        GUI.skin = skin;
        if (showInventory)
        {
            DrawInventory();
        }



    void DrawInventory ()
    {

        int i = 0;

        for (int y = 0; y < slotsY; y++)
        {
            for (int x = 0; x < slotsX; x++)
            {
                Rect slotRect = new Rect(x * slotWidth, y * slotHeight, slotWidth, slotHeight);
                Rect itemRect = new Rect(x * slotWidth+iconPaddingX, y * slotHeight+iconPaddingY, iconWidth, iconHeight);
                Rect labelRect = new Rect(x * slotWidth, y * slotHeight, iconWidth, iconHeight);
                GUI.Box(slotRect, "", skin.GetStyle("inventory-slot"));

                slots[i] = inventory[i];

                if (slots[i].Stackable && slots[i].Stack > 1)
                {
                    GUI.Label(labelRect, slots[i].Stack.ToString(), skin.GetStyle("stack-label"));
                }

                if (slots[i].Name != string.Empty)
                {
                    GUI.DrawTexture(itemRect, slots[i].Icon);
                    //print(slots[i].itemName + "in slot " + (i+1) + " has a total of " + slots[i].itemStack + " stackes.");

                    if (slots[i].Stackable == true)
                    {
                        //InventoryContains(slots[i].itemID);
                    }

                    // Check to see if mouse is hovering over a slot.
                    if (slotRect.Contains(e.mousePosition))
                    {
                        // Show tooltip
                        GenerateTooltip(slots[i]);

                        // If right mouse click and if not dragging an item and if the item is equal to a consumable 
                        // or key then use item.
                        if (e.button == 1 && e.type == EventType.mouseUp && !draggingItem && (slots[i].Type == Item.ItemType.Consumable || slots[i].Type == Item.ItemType.Key))
                        {
                            //inventory[i] = UseConsumable(inventory[i]); // Check UseConsumable method for definition
                        } 

                        // If left mouse click and if dragging and if not draggingItem = false
                        // Then drag item
                        if (e.button == 0 && e.type == EventType.mouseDrag && !draggingItem)
                        {
                            DragItem(i); // Check DragItem method for definition
                        }

                        if (e.isMouse && e.type == EventType.MouseDown && e.clickCount == 2)
                        {
                            print(inventory[i].Stack + " | " + slots[i].Stack);
                        }

                        // If dragging and item and if left mouse click is in up postion
                        if (e.button == 0 && e.type == EventType.mouseUp && draggingItem)
                        {
                            // Stack Items
                            if (slots[i].ID == draggedItem.ID)
                            {

                                StackItem(i);
                            }
                            //Swap Item locations
                            else
                            {
                                inventory[prevIndex] = inventory[i];
                                inventory[i] = draggedItem;
                                draggingItem = false;
                                draggedItem = null;
                            }
                        }
                        else
                        {

                        }
                    }
                }
                else
                {
                    if (slotRect.Contains(e.mousePosition))
                    {
                        if (e.type == EventType.mouseUp && draggingItem)
                        {
                            inventory[i] = draggedItem;
                            draggingItem = false;
                            draggedItem = null;
                        }
                    }
                }


                i++;
            }
        }
    }

     void StackItem (int index)
    {
        int newStack = 0;
        newStack = slots[index].Stack + draggedItem.Stack;
        draggedItem = null;
        draggingItem = false;
        inventory[index].Stack = newStack;
    }

//Adds item by Item ID from the itemDatabase
void AddItem (int id)
{

    for (int i = 0; i < inventory.Count; i++)
    {
        if (inventory[i].Name == string.Empty)
        {
            for (int j = 0; j < database.items.Count; j++)
            {
                if (database.items[j].ID == id)
                {
                    inventory[i] = database.items[j];
                    return;
                }
            }


        }
    }
}

对不起,只有更重要的事情被评论 .

编辑:

这是Item Database类

public class ItemDatabase : MonoBehaviour {

        public List<Item> items = new List<Item>();


        void Start ()
        {
            items.Add(new Item("Base Potion", 1, 1, 10));
            items.Add(new Item("Magic Potion", 2, 1, 10));

        }
    }

编辑2:问题确实是我引用了这个课程 . 我在该类中添加了一个Clone方法,然后进行了一些其他修改,然后一切正常

public object Clone ()
{
    Item item = new Item(Name, ID,  Quantity, MaxStack);
    return item;
}

1 回答

  • 1

    我对代码有点遗失(不是你的错),但我认为问题是通过引用/值错误传递 . (如果你愿意,你可以谷歌,但我会尝试解释)

    通过引用传递是C#默认执行的操作 . 这意味着这段代码:

    MyClass X = new MyClass();
    MyClass Y = X;
    X.Value = 0;
    Y.Value = 10;
    Console.WriteLine(X.Value);
    Console.WriteLine(Y.Value);
    

    将打印:

    10 
    10
    

    这是因为Y基本上成为访问X的新方法,因此如果Y被更改,X也会改变 . 我认为这是问题,当你尝试堆叠项目时,项目不是单独的对象,而是在某些时候它们最终会引用一个单独的对象,因此,当你去增加一个数量时,另一方的数量也增加了 .

    编辑:根本不确定,但问题可能是从项目数据库中添加新项目时 . 我认为项目数据库中的项目可能是一个值,当您向库存中添加新项目时,它们将成为引用 - 数据库中项目的副本 .

相关问题