【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱5(附带项目源码)

简介: 【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱5(附带项目源码)

前言

欢迎来到【制作100个Unity游戏】系列!本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第25篇中,我们将探索如何用unity制作一个3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱等功能,我会附带项目源码,以便你更好理解它。

制作系统

定义制作配方

// 制作配方
[CreateAssetMenu(fileName = "NewRecipe", menuName = "Inventory/Recipe")]
public class Recipe : ScriptableObject
{
    // 生成的物品预制体
    public GameObject createdItemPrefab;

    // 生产数量
    public int quantityProduced = 1;

    // 所需的原料列表
    public List<RequiredIngredient> requiredIngredients = new List<RequiredIngredient>();

    // 所需的原料
    [System.Serializable]
    public class RequiredIngredient
    {
        // 原料的名称
        public string itemName;

        // 所需的数量
        public int requiredQuantity;
    }
}

简单配置一个制作配方

新增Crafting,实现制作功能,注意修改Inventory为单例

using System.Collections.Generic;
using UnityEngine;

public class Crafting : MonoBehaviour
{
    public List<Slot> allInventorySlots;
    [Header("制作")]
    public List<Recipe> itemRecipes = new List<Recipe>();//制作配方列表

    private void Start() {
        allInventorySlots = Inventory.Instance.allInventorySlots;
    }

    //合成制作物品
    public void craftItem(string itemName)
    {
        // 遍历所有配方
        foreach (Recipe recipe in itemRecipes)
        {
            // 找到与指定物品名称匹配的配方
            if (recipe.createdItemPrefab.GetComponent<Item>().name == itemName)
            {
                bool haveAllIngredients = true;//是否有足够的原料

                for (int i = 0; i < recipe.requiredIngredients.Count; i++)
                {
                    if (!haveIngredient(recipe.requiredIngredients[i].itemName, recipe.requiredIngredients[i].requiredQuantity))
                    {
                        Debug.Log(recipe.requiredIngredients[i].itemName + "不够,制作失败");
                        haveAllIngredients = false;
                        break;
                    }
                }

                if (haveAllIngredients)
                {
                    // 移除所需的原料
                    for (int i = 0; i < recipe.requiredIngredients.Count; i++)
                    {
                        removeIngredient(recipe.requiredIngredients[i].itemName, recipe.requiredIngredients[i].requiredQuantity);
                    }

                    // 创建物品
                    GameObject craftedItem = Instantiate(recipe.createdItemPrefab, Inventory.Instance.dropLocation.position, Quaternion.identity);
                    craftedItem.GetComponent<Item>().currentQuantity = recipe.quantityProduced;

                    // 将物品添加到库存中
                    Inventory.Instance.addItemToInventory(craftedItem.GetComponent<Item>());
                    break;
                }
            }
        }
    }

    //从库存中移除指定数量的原料
    private void removeIngredient(string itemName, int quantity)
    {
        // 如果没有足够的原料,则直接返回
        if (!haveIngredient(itemName, quantity))
        {
            Debug.Log("没有足够的原料");
            return;
        }

        int remainingQuantity = quantity;

        // 遍历所有库存槽位
        foreach (Slot curSlot in allInventorySlots)
        {
            Item item = curSlot.getItem();

            // 找到匹配的原料
            if (item != null && item.name == itemName)
            {
                // 如果库存中的数量大于所需数量,则减去所需数量
                if (item.currentQuantity >= remainingQuantity)
                {
                    item.currentQuantity -= remainingQuantity;
                    // 如果库存中的数量等于所需数量,则将槽位置空
                    if (item.currentQuantity == 0)
                    {
                        curSlot.setItem(null);
                    }
                    return;
                }
                else
                {
                    Debug.Log("没有足够的原料");
                    // 更新剩余数量
                    // remainingQuantity -= item.currentQuantity;
                    // curSlot.setItem(null);
                }
            }
        }
    }

    //检查库存中是否有足够的指定原料
    private bool haveIngredient(string itemName, int quantity)
    {
        int foundQuantity = 0;

        // 遍历所有库存槽位
        foreach (Slot curSlot in allInventorySlots)
        {
            // 如果槽位存在物品且名称匹配
            if (curSlot.hasItem() && curSlot.getItem().name == itemName)
            {
                foundQuantity += curSlot.getItem().currentQuantity;
                // 如果找到的数量大于所需数量,则返回true,否则返回false
                if (foundQuantity >= quantity)
                {
                    return true;
                }
            }
        }
        return false;
    }
}

绑定配方参数

绘制简单的制作界面,并并绑定点击制作事件

效果,制作出一个石斧

源码

源码不出意外的话我会放在最后一节

目录
相关文章
|
3月前
|
图形学 索引
【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱4(附带项目源码)
【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱4(附带项目源码)
35 2
|
3月前
|
图形学
【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱8(附带项目源码)
【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱8(附带项目源码)
24 1
|
3月前
|
图形学
【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱9(附带项目源码)
【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱9(附带项目源码)
17 1
|
3月前
|
图形学
【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱10(附带项目源码)
【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱10(附带项目源码)
22 1
|
3月前
|
图形学
【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱2(附带项目源码)
【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱2(附带项目源码)
27 0
|
3月前
|
图形学
【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱7(附带项目源码)
【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱7(附带项目源码)
19 0
|
3月前
|
图形学
【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱1(附带项目源码)
【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱1(附带项目源码)
45 0
|
3月前
|
图形学
【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱11(附带项目源码)
【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱11(附带项目源码)
20 0
|
3月前
|
存储 图形学
【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱6(附带项目源码)
【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱6(附带项目源码)
22 0
|
3月前
|
图形学
【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱3(附带项目源码)
【制作100个unity游戏之25】3D背包、库存、制作、快捷栏、存储系统、砍伐树木获取资源、随机战利品宝箱3(附带项目源码)
15 0