麦田物语学习笔记:实现拖拽物品交换数据和在地图上生成物品
基本流程
1.代码思路
(1)InventoryUI的PlayerSlots与PlayerBag里一一对应,所以想要实现交换数据实际上是,先拿到被拖拽的物体所对的Slot的序号和目标的Slot序号,然后将这两个序号对调一下
(2)物品交换的数据逻辑应该在InventoryManager里去调用,因为InventoryManager里管理了playerBag所有的数据
(3)交换数据时需要考虑库存的类型以及交换的目的,现有三个类型(slotType),有Bag,Box,Shop,依次对应的是同背包转换,跨库存数据进行转换,买卖交易;
(4)对于在地图上生成物品,首先要在SlotUI中获取拖拽结束时的世界坐标(因为Slot_Bag和已经创建好的背景不在一个层级上)
(5)新建一个ItemManager.cs,这个脚本用于管理场景中的所有物品,在切换场景的时候,保存场景当中现在有的物品,在切换回来的时候可以再次读取
(6)基于已经制作好的ItemBase的预制体,拿到这个预制体,在指定的位置进行生成,那么就需要让StotUI告诉ItemManager在哪生成,这时候就需要通过EventHandler来执行
(7)因为对事件这个知识点不是很熟,所以我会详写,在EventHandler里去实现在场景中生成物品的事件定义以及调用事件的方法,然后就可以去SlotUI里去调用了
(8)事件的详细描述:
先在事件中心EventHandler里实现对事件的定义
//在场景中生成物品的事件
//需要的参数有(ItemID,position)
public static event Action<int, Vector3> instantiateItemInScene;
再写事件的调用方法
public static void CallInstantiateItemInScene(int ID, Vector3 pos)
{InstantiateItemInScene?.Invoke(ID, pos);
}
去SlotUI中调用事件
//调用事件
EventHandler.CallInstantiateItemInScene(itemDetails.itemID,pos);
然后去ItemManager里接收数据,就需要添加注册的函数方法
private void OnEnable()
{EventHandler.InstantiateItemInScene += OnInstantiateItemInScene;
}private void OnDisable()
{EventHandler.InstantiateItemInScene -= OnInstantiateItemInScene;
}
编写方法的实现
private void OnInstantiateItemInScene(int ID, Vector3 pos)
{var item = Instantiate(itemPrefab,pos, Quaternion.identity, itemParent);item.itemID = ID;
}
2.代码实现
SlotUI中的
public void OnEndDrag(PointerEventData eventData)
{inventoryUI.dragItem.enabled = false;//Debug.Log(eventData.pointerCurrentRaycast.gameObject);//判断非空,只有非空才代表最后碰撞到的是UI物体//再判断碰撞的是否为SlotUI,不是就返回//为真就拿到双方的序号if (eventData.pointerCurrentRaycast.gameObject != null){if (eventData.pointerCurrentRaycast.gameObject.GetComponent<SlotUI>() != null){//目标点的SlotUIvar targetSlot = eventData.pointerCurrentRaycast.gameObject.GetComponent<SlotUI>();int targetIndex = targetSlot.slotIndex;//在Player自身背包范围内转换(同库存转换)if (targetSlot.slotType == SlotType.Bag && slotType == SlotType.Bag){InventoryManager.Instance.SwapItem(slotIndex, targetIndex);}//清空所有高亮 inventoryUI.UpdateSlotHightlight(-1);}}else {if (itemDetails.canDropped){//鼠标对应的世界地图坐标var pos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, -Camera.main.transform.position.z));//调用事件EventHandler.CallInstantiateItemInScene(itemDetails.itemID, pos);}}
}
InventoryManager中的
/// <summary>
/// Player背包范围内的交换物品
/// </summary>
/// <param name="fromIndex">起始序号</param>
/// <param name="toIndex">目标数据序号</param>
public void SwapItem(int fromIndex,int toIndex)
{ //需要考虑的是,当前的格子一定是非空的,但是目标格子不一定是空InventoryItem currentItem = playerBag.itemList[fromIndex];InventoryItem targetItem = playerBag.itemList[ toIndex ];if (targetItem.itemID != 0){playerBag.itemList[fromIndex] = targetItem;playerBag.itemList[toIndex] = currentItem;}else{playerBag.itemList[fromIndex] = new InventoryItem();//这里new一个其实就是给它置空playerBag.itemList[toIndex] = currentItem;}EventHandler.CallUpdateInventoryUI(InventoryLocation.Player,playerBag.itemList);
}
EventHandler中的
//在场景中生成物品的事件
//需要的参数有(ItemID,position)
public static event Action<int, Vector3> InstantiateItemInScene;
public static void CallInstantiateItemInScene(int ID, Vector3 pos)
{InstantiateItemInScene?.Invoke(ID, pos);
}
ItemManager中的
namespace FuliFarm.Inventory
{public class ItemManager : MonoBehaviour{public Item itemPrefab;private Transform itemParent;private void OnEnable(){EventHandler.InstantiateItemInScene += OnInstantiateItemInScene;}private void OnDisable(){EventHandler.InstantiateItemInScene -= OnInstantiateItemInScene;}private void Start(){itemParent = GameObject.FindWithTag("ItemParent").transform;}private void OnInstantiateItemInScene(int ID, Vector3 pos){var item = Instantiate(itemPrefab, pos, Quaternion.identity, itemParent);item.itemID = ID;}}
}
最终效果
同库存交换
地图上拾取(就不多展示了,字面意思)
出现的问题
物品丢在地上后捡不起来,检查canPickUp没有问题,最后发现在生成itemBase的prefab时,碰撞盒的offset的y值不为零,导致碰撞盒与图片不在同一位置
相关代码是Item.cs中的这一句
将coll.offset = new Vector2(0,spriteRenderer.bounds.center.y);改为
coll.offset = new Vector2(0, spriteRenderer.transform.localPosition.y);就行了
但我实在不明白coll.offset = new Vector2(0,spriteRenderer.bounds.center.y);有什么错误,我觉得思路上是没错的
相关文章:
麦田物语学习笔记:实现拖拽物品交换数据和在地图上生成物品
基本流程 1.代码思路 (1)InventoryUI的PlayerSlots与PlayerBag里一一对应,所以想要实现交换数据实际上是,先拿到被拖拽的物体所对的Slot的序号和目标的Slot序号,然后将这两个序号对调一下 (2)物品交换的数据逻辑应该在InventoryManager里去调用,因为InventoryManager里管理了p…...
一些计算机零碎知识随写(25年1月)-1
我原以为世界上有技术的那批人不会那么闲,我错了,被脚本真实了。 今天正隔着画画呢,手机突然弹出几条安全告警通知。 急忙打开服务器,发现问题不简单,直接关服务器重装系统..... 首先,不要认为小网站&…...
Qt学习笔记第81到90讲
第81讲 串口调试助手实现自动发送 为这个名叫“定时发送”的QCheckBox编写槽函数。 想要做出定时发送的效果,必须引入QT框架下的毫秒级定时器QTimer,查阅手册了解详情。 在widget.h内添加新的私有成员变量: QTimer *timer; 在widget类的构造…...
Centos9 + Docker 安装 MySQL8.4.0 + 定时备份数据库到本地
Centos9 Docker 安装 MySQL8.4.0 定时备份数据库到本地 创建目录,创建配置文件启动容器命令定时备份MySQL执行脚本Linux每日定时任务命令文件内参数其他时间参数 AT一次性定时任务 创建目录,创建配置文件 $ mkdir -p /opt/mysql/conf$ vim /opt/mysql/…...
网络原理一>UDP协议详解
UDP和TCP都是应用层中的重要协议,如果做基础架构开发,会用得多一些。 这一篇我们先简单聊一下的UDP TCP格式呈现: 我们知道UDP是一种无连接,面向数据报,全双工,不可靠传输特性的网络协议。 基本格式如图…...
MySQL的小问题
编码问题 不管官方使用什么编码:latin1、gbk、utf8、utfmb4。统一使用utfmb4 MySQL中的utf8并不是utf-8,它省略了一个字节,只是用三个字节存储所有的符号,utfmb4才是utf-8 远程登录问题: MySQL官方默认没有启动远程…...
Mac——Docker desktop安装与使用教程
摘要 本文是一篇关于Mac系统下Docker Desktop安装与使用教程的博文。首先介绍连接WiFi网络,然后详细阐述了如何在Mac上安装Docker,包括下载地址以及不同芯片版本的选择。接着讲解了如何下载基础镜像和指定版本镜像,旨在帮助用户在Mac上高效使…...
FastApi Swagger 序列化问题
问题 错误现象: fastapi的 swagger 界面无法正常打开控制台报错:raise PydanticInvalidForJsonSchema(fCannot generate a JsonSchema for {error_info}) 详细报错: File "d:\Envs\miniconda3\envs\xdagent\lib\site-packages\pydan…...
《机器学习》——sklearn库中CountVectorizer方法(词频矩阵)
CountVectorizer方法介绍 CountVectorizer 是 scikit-learn 库中的一个工具,它主要用于将文本数据转换为词频矩阵,而不是传统意义上的词向量转换,但可以作为词向量转换的一种基础形式。用于将文本数据转换为词频矩阵,它是文本特征…...
UML系列之Rational Rose笔记三:活动图(泳道图)
一、新建活动图(泳道图) 依旧在用例视图里面,新建一个activity diagram;新建好之后,就可以绘制活动图了: 正常每个活动需要一个开始,点击黑点,然后在图中某个位置安放,接…...
Java面向对象面经总结
目录 面向对象基础 面向对象与面向过程的区别 创建一个对象用什么运算符,对象实体与对象引用的区别 对象相等和引用相等的区别 构造方法的特点,是否可被重写? 面向对象三大特征 封装 继承 多态 接口和抽象类的共同点和区别 深拷贝…...
红队工具使用全解析:揭开网络安全神秘面纱一角
红队工具使用全解析:揭开网络安全神秘面纱一角 B站红队公益课:https://space.bilibili.com/350329294 学习网盘资源链接:https://pan.quark.cn/s/4079487939e8 嘿,各位网络安全爱好者们!在风云变幻的网络安全战场上&am…...
OpenLinkSaas 2025年第一季度开发计划
OpenLinkSaas在2025的发展方向是强化基础设施和研发协作,弱化管理相关的功能。 为了根据参与到软件研发的整个流程,OpenLinkSaas会增加一系列的基础设施项目,并和OpenLinksaas进行深度整合。 目前计划中的基础设施: 链路追踪系统(OpenDragonF…...
【python小工具】怎么获取视频的关键帧频率?
使用 FFmpeg 提取 MP4 视频的关键帧并计算关键帧频率可以按以下步骤进行: 提取关键帧: 使用 FFmpeg 提取视频中的关键帧可以通过以下命令实现: ffmpeg -i input.mp4 -vf "selecteq(pict_type,I)" -vsync vfr keyframes_%03d.jpg…...
数字孪生可视化在各个行业的应用场景
数字孪生技术,作为新一代信息技术的集大成者,正在深刻改变着我们对物理世界的认知和管理方式。本文将探讨数字孪生可视化在不同行业的应用场景,以及它们如何赋能行业数字化转型。 1. 智慧城市与交通 在智慧城市领域,数字孪生技术…...
Python实现windows自动关机
python <shut.py> import ntplib from datetime import datetime, timezoneimport time import osimport easygui# net time def get_network_time():time.sleep(3)"""从网络时间服务器获取时间"""client ntplib.NTPClient()response c…...
Go可以使用设计模式,但绝不是《设计模式》中的那样
文章精选推荐 1 JetBrains Ai assistant 编程工具让你的工作效率翻倍 2 Extra Icons:JetBrains IDE的图标增强神器 3 IDEA插件推荐-SequenceDiagram,自动生成时序图 4 BashSupport Pro 这个ides插件主要是用来干嘛的 ? 5 IDEA必装的插件&…...
【C语言】_使用冒泡排序模拟实现qsort函数
目录 1. 排序函数的参数 2. 排序函数函数体 2.1 比较元素的表示 2.2 交换函数Swap的实现 2.3 排序函数bubble_sort的实现 3. 测试整型数据排序 3.1 整型数据比较函数cmp_int的实现 3.2 整型数据排序后输出函数print_int的实现 3.3 整型数据测试函数test_int的实现 3…...
openCvSharp 计算机视觉图片找茬
一、安装包 <PackageReference Include"OpenCvSharp4" Version"4.10.0.20241108" /> <PackageReference Include"OpenCvSharp4.runtime.win" Version"4.10.0.20241108" /> 二、准备两张图片 三、编写代码 using OpenCv…...
从零开始开发纯血鸿蒙应用之处理外部文件
从零开始开发纯血鸿蒙应用 一、外部文件二、外部文件的访问形式1、主动访问2、被动访问 三、代码实现1、DocumentViewPicker2、Ability Skills3、onNewWant 函数4、冷启动时处理外部文件 一、外部文件 对于移动端app来说,什么是外部文件呢?是那些存储在…...
Spring中三级缓存详细讲解
1、Spring三级缓存是什么,过程是怎么样的? Spring 中的三级缓存主要用于单例 Bean 的生命周期管理,特别是在循环依赖时,它通过不同阶段暴露 Bean 实例来确保依赖注入的顺利完成。缓存的内容如下: 一级缓存 (singleton…...
论文阅读:《Whole-animal connectomes of both Caenorhabditis elegans sexes》
一 论文整体概述 论文下载链接:《Whole-animal connectomes of both Caenorhabditis elegans sexes》 补充信息和额外数据:https://www.nature.com/articles/s41586-019-1352-7 1. 作者期刊背景 该论文由Scott W. Emmons,David H. Hall等…...
嵌入式开发之STM32学习笔记day03
STM32之ADC(模拟数字转换器) 1 ADC简述2 ADC转换时间3 ADC转化结果存放机制4 ADC转化结果存放机制5 ADC电压转换 1 ADC简述 ADC(Analog-Digital Converter)模拟—数字转换器;ADC可以将引脚上连续变化的模拟电压转换为…...
windows10 安装 Golang 版本控制工具g与使用
下载包:https://github.com/voidint/g/releases 解压, 并添加到环境变量 g 常用命令 查询当前可供安装的stable状态及所有的 go 版本 # stable 版本 g ls-remote stable# 所有版本 g ls-remote安装目标 go 版本1.23.4g install 1.23.4切换到已安装的…...
SpringBoot 使用 Cache 集成 Redis做缓存保姆教程
1. 项目背景 Spring Cache是Spring框架提供的一个缓存抽象层,它简化了缓存的使用和管理。Spring Cache默认使用服务器内存,并无法控制缓存时长,查找缓存中的数据比较麻烦。 因此Spring Cache支持将缓存数据集成到各种缓存中间件中。本文已常…...
R数据分析:多分类问题预测模型的ROC做法及解释
有同学做了个多分类的预测模型,结局有三个类别,做的模型包括多分类逻辑回归、随机森林和决策树,多分类逻辑回归是用ROC曲线并报告AUC作为模型评估的,后面两种模型报告了混淆矩阵,审稿人就提出要统一模型评估指标。那么肯定是统一成ROC了,刚好借这个机会给大家讲讲ROC在多…...
数据结构与算法之二叉树: LeetCode 654. 最大二叉树 (Ts版)
最大二叉树 https://leetcode.cn/problems/maximum-binary-tree/ 描述 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点,其值为 nums 中的最大值递归地在最大值 左边 的 子数组前缀上 构建左子树递归地在最大值…...
Linux 容器漏洞
定义:Linux 容器漏洞是指在容器技术(如 Docker、LXC 等)运行环境中存在的安全弱点。这些漏洞可能存在于容器镜像本身、容器运行时(如 runc)、容器编排工具(如 Kubernetes)或者容器与主机之间的交…...
file与io流(1)
-1- java.io.File类的使用 (1) 概述 File类及本章下的各种流,都定义在java.io包下。一个File对象代表硬盘或网络中可能存在的一个文件或者文件目录(俗称文件夹),与平台无关。(体会万事万物皆…...
忘记了PDF文件的密码,怎么办?
PDF文件可以加密,大家都不陌生,并且大家应该也都知道PDF文件有两种密码,一个打开密码、一个限制编辑密码,因为PDF文件设置了密码,那么打开、编辑PDF文件就会受到限制。忘记了PDF密码该如何解密? PDF和offi…...
1000学习做网站贵吗/观看b站的广告网站平台
2019独角兽企业重金招聘Python工程师标准>>> binSort.cpp /** 这里是主函数的执行文件 * binSort.cpp */ #include<iostream> #include"studentrecord1.h" #include"chainwithiterator.h" #include"myexceptions.h"void…...
电子商务网站建设的目的/长沙网站制作公司哪家好
我想这几天大多数开发人员都在使用某种框架来开发应用程序。 框架可以帮助我们构建复杂的应用程序并节省时间。 每天,我们都会看到有关哪个框架是最好的框架,应该首先学习哪个框架的讨论,等等。所以今天,我想分享我的经验…...
宣传网站怎么做的/北京seo营销培训
方法一:第一步:打开 查询分析器 输入 sp_password null,sa,sa的密码 并运行 运行的结果是把sa帐户的密码修改了。第二步:然后打开 企业管理器 找到你的SQL注册组(就是SQl Server组下面那个),右击找到 安全性 - 安全性 -身份验证 选…...
单页的网站怎么做的/线上广告推广
SOA到底是什么? SOA到底是什么? 当大家对 SOA开始有所了解后,往往有种雾里看花的感觉,看上去很美,可就很难摸透和落地。业界有些人把SOA说成是解决业务问题而不是技术问题,也有些人把 SOA看成是解决IT资产的复用和管理问题&…...
集团门户网站建设策划/哪里可以接广告
本指南将向您展示如何轻松只需几个简单的步骤即可实现Spring Boot应用的国际化 我们将讨论如何在现有的Spring Boot项目中添加国际化。当您处理应该为来自不同国家/地区的用户提供不同语言服务的项目时,app国际化的问题变得很常见。比如,你需要向中国用…...
wordpress now 1.5/网站快速排名优化价格
转载于:https://www.cnblogs.com/gw2010/p/7892372.html...