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

news2024/11/26 10:31:09

效果演示

在这里插入图片描述

文章目录

  • 效果演示
  • 系列目录
  • 前言
  • 制作系统
    • 定义制作配方
  • 源码
  • 完结

系列目录

前言

欢迎来到【制作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;
    }
}

绑定配方参数
在这里插入图片描述

绘制简单的制作界面,并并绑定点击制作事件
在这里插入图片描述

在这里插入图片描述
效果,制作出一个石斧
在这里插入图片描述

源码

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

完结

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,以便我第一时间收到反馈,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

好了,我是向宇,https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,出于兴趣爱好,最近开始自学unity,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!php是工作,unity是生活!如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1449088.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(四)【Jmeter】 JMeter的界面布局与组件概述

JMeter的界面布局 中文版&#xff1a; 英文版&#xff1a; JMeter的主界面包括菜单栏、工具栏、树形结构面板、视图面板等部分。 菜单栏&#xff1a;菜单栏包含了文件(File)、编辑(Edit)、查找(Search)、选项(Options)、工具(Tools)、帮助(Help)等菜单项&#xff0c;用于对…

Compose高级别API动画指南

前文讲了Compose中的低级别API动画&#xff0c;与之对应的&#xff0c;还有高级别API动画&#xff0c;同样也符合Material-Design规范。所有高级别动画 API 都是在低级别动画 API 的基础上构建而成&#xff0c;其对应关系如图&#xff1a; 接下来就对其高级别API逐个分析&…

2024LeetCode分类刷题

一、数组 88. 合并两个有序数组 public void merge(int[] nums1, int m, int[] nums2, int n) {int p1 0, p2 0;int[] sorted new int[m n];while (p1 < m || p2 < n) {int current;if (p1 m) {current nums2[p2];} else if (p2 n) {current nums1[p1];} else i…

单体工程结构

本文主要说明下单体项目的工程结构如何设计&#xff0c;目前业界存在两种主流的应用工程结构&#xff1a;一种是阿里推出的《Java开发手册》中推荐的&#xff0c;另外一种是基于DDD(领域驱动设计)推荐的。下面我们来看下两种工程结构是怎样的。 一、 基于阿里《Java开发手册》…

基于FPGA的UDP实现(包含源工程文件)

1、概括 前文通过FPGA实现了ARP和ICMP协议&#xff0c;ARP协议一般用来获取目的IP地址主机的MAC地址&#xff0c;ICMP通过回显请求和回显应答来判断以太网链路是否通畅&#xff0c;这两个协议都不是用来传输用户数据的。如果用户需要向PC端传输大量数据&#xff0c;那么就必须使…

Swift Combine 通过用户输入更新声明式 UI 从入门到精通十五

Combine 系列 Swift Combine 从入门到精通一Swift Combine 发布者订阅者操作者 从入门到精通二Swift Combine 管道 从入门到精通三Swift Combine 发布者publisher的生命周期 从入门到精通四Swift Combine 操作符operations和Subjects发布者的生命周期 从入门到精通五Swift Com…

证明之缺角正方形网格的铺地砖问题

缺角正方形网格的铺地砖问题 “挑战难题&#xff1a;多米诺骨牌与无法覆盖的方格” 这里有个著名的难题。画八横八纵正方形网格&#xff0c;去掉相对的两个角。你能用多米诺骨牌形状的地砖——每一块正好覆盖两个相邻方格&#xff0c;把剩余部分覆盖吗&#xff1f;我在下图中…

bert-vits2本地部署报错疑难问题汇总

环境&#xff1a; bert-vits2.3 win 和wsl 问题描述&#xff1a; bert-vits2本地部署报错疑难问题汇总 解决方案&#xff1a; 问题1: Conda安装requirements里面依赖出现ERROR: No matching distribution found for opencc1.1.6 解决方法 需要在 Python 3.11 上使用 Op…

Springboot加载bootstrap和application原理

Springboot加载bootstrap和application原理 bootstrap.yml能被springboot加载导入依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.4.6</version><rel…

StringBuilder

StringBuilder代表可变字符串&#xff0c;相当于一个容器&#xff0c;里面的字符串可以改变&#xff0c;用来操作字符串。此类设计用作StringBuffer替代品。 构造方法&#xff1a; StringBuilder() StringBuilder(String str) 操作方法&#xff1a; 1. append()&#xff1…

【Spring】定义过滤器Filter和拦截器Interceptor

# 定义过滤器 package com.holen.filter;import jakarta.servlet.Filter; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.ServletRequest; import jakarta.servlet.ServletResponse; import java.io.IOException;pub…

2048游戏C++板来啦!

个人主页&#xff1a;PingdiGuo_guo 收录专栏&#xff1a;C干货专栏 大家好呀&#xff0c;我是PingdiGuo_guo&#xff0c;今天我们来学习如何用C编写一个2048小游戏。 文章目录 1.2048的规则 2.步骤实现 2.1: 初始化游戏界面 2.1.1知识点 2.1.2: 创建游戏界面 2.2: 随机…

【开源】基于JAVA+Vue+SpringBoot的班级考勤管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统基础支持模块2.2 班级学生教师支持模块2.3 考勤签到管理2.4 学生请假管理 三、系统设计3.1 功能设计3.1.1 系统基础支持模块3.1.2 班级学生教师档案模块3.1.3 考勤签到管理模块3.1.4 学生请假管理模块 3.2 数据库设…

VS Code主题设置(美化VS Code)(主题+背景+图标+特效+字体)

目录 切换整体主题&#xff08;整体主题&#xff09; 切换文件图标主题 设置VS Code背景图案 字体特效 连击特效 字体设置 主题的具体效果放在了文章末尾&#xff0c;这篇文章后续也会进行更新 ————————————————————————————…

Vulnhub靶机:DC3

一、介绍 运行环境&#xff1a;Virtualbox 攻击机&#xff1a;kali&#xff08;10.0.2.15&#xff09; 靶机&#xff1a;DC3&#xff08;10.0.2.56&#xff09; 目标&#xff1a;获取靶机root权限和flag 靶机下载地址&#xff1a;https://www.vulnhub.com/entry/dc-32,312…

get和set方法太多太臃肿?快使用 lombok

目录 0. lombok 介绍 1. lombok 使用 1.1 创建一个 maven 项目 1.2 在项目中引用依赖 1.3 在 idea 中添加 lombok 插件 1.4 使用 lombok 注解 1.5 Idea 运行报 Lombok requires enables annotation process 错误解决办法 0. lombok 介绍 当我们写一个类时&#xff0c;为了…

EsayExcel文件导入导出

目录 准备工作 监听器类 导入测试 导出测试 上传Excel 下载Excel 混合导出模板导出 headRowNumber(1)&#xff1a;从第几行开始读 准备工作 导入依赖 <!--easyexcel--> <dependency><groupId>com.alibaba</groupId>x<artifactId>easye…

微服务—ES数据同步

目录 数据同步 问题分析 方案1. 同步调用 方案2. 异步通知 方案3. 监听binlog​编辑 各方案对比 案例——利用MQ实现数据同步 步骤1. 导入hotel-admin项目 步骤2. 声明交换机、队列 步骤3. 发送MQ消息 步骤4. 接收MQ消息 步骤5. 测试同步功能 数据同步 elasticsea…

小白学Halcon100例:如何获取物品中心坐标并展示

文章目录 *读入彩色图片*分解彩色图片为三通道*阈值分割*链接*选择特征*提取目标中心*绘制目标中心--*设置线宽为1*创建十字轮廓*清空窗体*设置绘制模式为绘制边缘*显示目标*显示目标中心*读入彩色图片

算法学习——LeetCode力扣回溯篇4

算法学习——LeetCode力扣回溯篇4 332. 重新安排行程 332. 重新安排行程 - 力扣&#xff08;LeetCode&#xff09; 描述 给你一份航线列表 tickets &#xff0c;其中 tickets[i] [fromi, toi] 表示飞机出发和降落的机场地点。请你对该行程进行重新规划排序。 所有这些机票…