项目02《游戏-08-开发》Unity3D
基于 项目02《游戏-07-开发》Unity3D ,
本次任务做物品相互与详情的功能,
首先要做 点击相应,
接下来用接口实现点击相应事件,具体到代码中,我们找到需要响应鼠标事件的对象,
双击PackageCell.cs脚本修改代码:添加鼠标响应接口,
三个接口分别对鼠标的点击,进入,退出事件,
Alt + Enter 实现这三个接口,
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class PackageCell : MonoBehaviour,IPointerClickHandler,IPointerEnterHandler,IPointerExitHandler{
Transform UIIcon;
Transform UIHead;
Transform UINew;
Transform UISelect;
Transform UILevel;
Transform UIStars;
Transform UIDeleteSelect;
//动态数据
PackageLocalItem packageLocalData;
//静态数据
PackageTableItem packageTableItem;
//父物体也就是PackagePanel本身
PackagePanel uiParent;
void Awake(){
InitUIName();
}
void InitUIName(){
UIIcon = transform.Find("Top/Icon");
UIHead = transform.Find("Top/Head");
UINew = transform.Find("Top/New");
UILevel = transform.Find("Bottom/LevelText");
UIStars = transform.Find("Bottom/Stars");
UISelect = transform.Find("Select");
UIDeleteSelect = transform.Find("DeleteSelect");
UIDeleteSelect.gameObject.SetActive(false);
}
//刷新
public void Refresh(PackageLocalItem packageLocalData, PackagePanel uiParent){
//数据初始化
this.packageLocalData = packageLocalData;
this.packageTableItem = MainGame.Instance.GetPackageItemById(packageLocalData.id);
this.uiParent = uiParent;
//等级信息
UILevel.GetComponent<Text>().text = "Lv." + this.packageLocalData.level.ToString();
//是否是新获得?
UINew.gameObject.SetActive(this.packageLocalData.isNew);
Debug.Log("ImagePath: " + this.packageTableItem.imagePath);
//物品的图片
Texture2D t = (Texture2D)Resources.Load(this.packageTableItem.imagePath);
if (t != null){
Sprite temp = Sprite.Create(t, new Rect(0, 0, t.width, t.height), new Vector2(0, 0));
// 继续处理 Sprite 对象
UIIcon.GetComponent<Image>().sprite = temp;
}
else{
// 处理纹理加载失败的情况
Debug.LogError("Failed to load texture.");
}
//刷新星级
RefreshStars();
}
//刷新星级
public void RefreshStars(){
for (int i = 0; i < UIStars.childCount; i++){
Transform star = UIStars.GetChild(i);
if (this.packageTableItem.star > i)
star.gameObject.SetActive(true);
else
star.gameObject.SetActive(false);
}
}
public void OnPointerClick(PointerEventData eventData){
Debug.Log($"OnPointerClick {eventData.ToString()}");
}
public void OnPointerEnter(PointerEventData eventData){
Debug.Log($"OnPointerEnter {eventData.ToString()}");
}
public void OnPointerExit(PointerEventData eventData){
Debug.Log($"OnPointerExit {eventData.ToString()}");
}
}
回到unity编辑器中,
运行项目当我们鼠标悬停在武器Icon上就会有输出显示,
下一步是处理点击事件具体响应逻辑,
当鼠标点击物品时,右侧的详情界面会根据物品的信息进行刷新,
DetailPanel是PackagePanel下的子物体,也是我们要处理的对象,我们要对DetailPanel详情界面进行更新,
所以我们在Scripts脚本文件夹中添加一个脚本PackageDetail.cs用来更新详情界面DetailPanel对象,
然后将PackageDetail.cs脚本绑定在DetailPanel对象身上,
类似于上集的PackageCell逻辑,我们可以把DetailPanel也当作一个独立的对象进行处理,
双击PackagDetail.cs脚本修改代码:
using UnityEngine;
using UnityEngine.UI;
public class PackageDetail : MonoBehaviour{
Transform UIStars;
Transform UIDescription;
Transform UIIcon;
Transform UITitle;
Transform UILevelText;
Transform UISkillDescription;
PackageLocalItem packageLocalData;
PackageTableItem packageTableItem;
PackagePanel uiParent;
void Awake(){
InitUIName();
Test();
}
void Test() {
Refresh(MainGame.Instance.GetPackageLocalData()[1], null);
}
void InitUIName(){
UIStars = transform.Find("Center/Stars");
UIDescription = transform.Find("Center/Description");
UIIcon = transform.Find("Center/Icon");
UITitle = transform.Find("Top/Title");
UILevelText = transform.Find("Bottom/LevelPnl/LevelText");
UISkillDescription = transform.Find("Bottom/Description");
}
public void Refresh(PackageLocalItem packageLocalData, PackagePanel uiParent) {
//初始化:动态数据,静态数据,父物品逻辑
this.packageLocalData = packageLocalData;
this.packageTableItem = MainGame.Instance.GetPackageItemById(packageLocalData.id);
this.uiParent = uiParent;
//等级
UILevelText.GetComponent<Text>().text = string.Format($"Lv.{this.packageLocalData.level.ToString()}");
//简短描述
UIDescription.GetComponent<Text>().text = this.packageTableItem.description;
//详细描述
UISkillDescription.GetComponent<Text>().text = this.packageTableItem.skillDescription;
//物品名称
UITitle.GetComponent<Text>().name = this.packageTableItem.name;
//图片加载
Texture2D t = (Texture2D)Resources.Load(this.packageTableItem.imagePath);
Sprite temp = Sprite.Create(t, new Rect(0, 0, t.width, t.height), new Vector2(0, 0));
UIIcon.GetComponent<Image>().sprite = temp;
//星级处理
RefreshStars();
}
public void RefreshStars(){
for (int i = 0; i < UIStars.childCount; i++) {
Transform star = UIStars.GetChild(i);
if(this.packageTableItem.star > i)
star.gameObject.SetActive(true);
else
star.gameObject.SetActive(false);
}
}
}
回到unity编辑器中,运行项目可见详情页面被替换成
测试方法的第二张图片,
下一步要做的事情是当点击某个物品时,详情界面会根据鼠标点击的物品进行展示,
打开PackagePanel.cs脚本修改代码: 这是背包的主题逻辑部分
当前选中的物品总要被记录,把记录的地方放在PackagePanel中,
using UnityEngine;
using UnityEngine.UI;
public class PackagePanel : BasePanel{
Transform UIMenu;
Transform UIMenuWeapon;
Transform UIMenuFood;
Transform UITabName;
Transform UICloseBtn;
Transform UICenter;
Transform UIScrollView;
Transform UIDetailPanel;
Transform UILeftBtn;
Transform UIRightBtn;
Transform UIDeletePanel;
Transform UIDeleteBackBtn;
Transform UIDeleteInfoText;
Transform UIDeleteConfirmBtn;
Transform UIBottomMenus;
Transform UIDeleteBtn;
Transform UIDetailBtn;
//添加
public GameObject PackageUIItemPrefab;
//添加 表示当前选中的物品时哪一个uid
string _chooseUid;
public string ChooseUid {
get { return _chooseUid; }
set {
_chooseUid = value;
RefreshDetail();
}
}
void RefreshDetail() {
//找到uid对应的动态数据
PackageLocalItem localItem = MainGame.Instance.GetPackageLocalItemByUId(ChooseUid);
//刷新详情界面
UIDetailPanel.GetComponent<PackageDetail>().Refresh(localItem, this);
}
override protected void Awake(){
base.Awake();
InitUI();
}
//添加1
void Start(){
RefreshUI();
}
//添加1
void RefreshUI(){
RefreshScroll();
}
//添加1
void RefreshScroll(){
//清理滚动容器中原本的物品
RectTransform scrollContent = UIScrollView.GetComponent<ScrollRect>().content;
for (int i = 0; i < scrollContent.childCount; i++)
Destroy(scrollContent.GetChild(i).gameObject);
//获取本地数据的方法拿到自己身上背包数据 并且根据背包数据初始化滚动容器
foreach (PackageLocalItem localData in MainGame.Instance.GetSortPackageLocalData()){
Transform PackageUIItem = Instantiate(PackageUIItemPrefab.transform, scrollContent) as Transform;
PackageCell packageCell = PackageUIItem.GetComponent<PackageCell>();
//添加2
packageCell.Refresh(localData, this);
}
}
void InitUI(){
InitUIName();
InitClick();
}
void InitUIName(){
UIMenu = transform.Find("TopCenter/Menu");
UIMenuWeapon = transform.Find("TopCenter/Menus/Weapon");
UIMenuFood = transform.Find("TopCenter/Menus/Food");
UITabName = transform.Find("LeftTop/TabName");
UICloseBtn = transform.Find("RightTop/Close");
UICenter = transform.Find("Center");
UIScrollView = transform.Find("Center/Scroll View");
UIDetailPanel = transform.Find("Center/DetailPanel");
UILeftBtn = transform.Find("Left/Button");
UIRightBtn = transform.Find("Right/Button");
UIDeletePanel = transform.Find("Bottom/DeletePanel");
UIDeleteBackBtn = transform.Find("Bottom/DeletePanel/Back");
UIDeleteInfoText = transform.Find("Bottom/DeletePanel/InfoText");
UIDeleteConfirmBtn = transform.Find("Bottom/DeletePanel/ConfirmBtn");
UIBottomMenus = transform.Find("Bottom/BottomMenus");
UIDeleteBtn = transform.Find("Bottom/BottomMenus/DeleteBtn");
UIDetailBtn = transform.Find("Bottom/BottomMenus/DetailBtn");
UIDeletePanel.gameObject.SetActive(false);
UIBottomMenus.gameObject.SetActive(true);
}
void InitClick(){
UIMenuWeapon.GetComponent<Button>().onClick.AddListener(OnClickWeapon);
UIMenuFood.GetComponent<Button>().onClick.AddListener(OnClickFood);
UICloseBtn.GetComponent<Button>().onClick.AddListener(OnClickClose);
UILeftBtn.GetComponent<Button>().onClick.AddListener(OnClickLeft);
UIRightBtn.GetComponent<Button>().onClick.AddListener(OnClickRight);
UIDeleteBackBtn.GetComponent<Button>().onClick.AddListener(OnDeleteBack);
UIDeleteConfirmBtn.GetComponent<Button>().onClick.AddListener(OnDeleteConfirm);
UIDeleteBtn.GetComponent<Button>().onClick.AddListener(OnDelete);
UIDetailBtn.GetComponent<Button>().onClick.AddListener(OnDetail);
}
void OnDetail(){
print(">>>>>>> OnDetail()");
}
void OnDelete(){
print(">>>>>>> OnDelete()");
}
void OnDeleteConfirm(){
print(">>>>>>> OnDeleteConfirm()");
}
void OnDeleteBack(){
print(">>>>>>> OnDeleteBack()");
}
void OnClickRight(){
print(">>>>>>> OnClickRight()");
}
void OnClickLeft(){
print(">>>>>>> OnClickLeft()");
}
void OnClickWeapon(){
print(">>>>>>> OnClickWeapon()");
}
void OnClickFood(){
print(">>>>>>> OnClickFood()");
}
void OnClickClose(){
ClosePanel();
}
}
因为物品的逻辑是写在PackageCell.cs脚本中,
那么找到PackageCell点击的回调方法,
也就是OnPointerClick()方法,
修改PackageCell.cs脚本:
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class PackageCell : MonoBehaviour,IPointerClickHandler,IPointerEnterHandler,IPointerExitHandler{
Transform UIIcon;
Transform UIHead;
Transform UINew;
Transform UISelect;
Transform UILevel;
Transform UIStars;
Transform UIDeleteSelect;
//动态数据
PackageLocalItem packageLocalData;
//静态数据
PackageTableItem packageTableItem;
//父物体也就是PackagePanel本身
PackagePanel uiParent;
void Awake(){
InitUIName();
}
void InitUIName(){
UIIcon = transform.Find("Top/Icon");
UIHead = transform.Find("Top/Head");
UINew = transform.Find("Top/New");
UILevel = transform.Find("Bottom/LevelText");
UIStars = transform.Find("Bottom/Stars");
UISelect = transform.Find("Select");
UIDeleteSelect = transform.Find("DeleteSelect");
UIDeleteSelect.gameObject.SetActive(false);
}
//刷新
public void Refresh(PackageLocalItem packageLocalData, PackagePanel uiParent){
//数据初始化
this.packageLocalData = packageLocalData;
this.packageTableItem = MainGame.Instance.GetPackageItemById(packageLocalData.id);
this.uiParent = uiParent;
//等级信息
UILevel.GetComponent<Text>().text = "Lv." + this.packageLocalData.level.ToString();
//是否是新获得?
UINew.gameObject.SetActive(this.packageLocalData.isNew);
Debug.Log("ImagePath: " + this.packageTableItem.imagePath);
//物品的图片
Texture2D t = (Texture2D)Resources.Load(this.packageTableItem.imagePath);
if (t != null){
Sprite temp = Sprite.Create(t, new Rect(0, 0, t.width, t.height), new Vector2(0, 0));
// 继续处理 Sprite 对象
UIIcon.GetComponent<Image>().sprite = temp;
}
else{
// 处理纹理加载失败的情况
Debug.LogError("Failed to load texture.");
}
//刷新星级
RefreshStars();
}
//刷新星级
public void RefreshStars(){
for (int i = 0; i < UIStars.childCount; i++){
Transform star = UIStars.GetChild(i);
if (this.packageTableItem.star > i)
star.gameObject.SetActive(true);
else
star.gameObject.SetActive(false);
}
}
public void OnPointerClick(PointerEventData eventData){
if (this.uiParent.ChooseUid == this.packageLocalData.uid)
return;
//根据点击设置最新的uid 进而刷新详情界面
this.uiParent.ChooseUid = this.packageLocalData.uid;
}
public void OnPointerEnter(PointerEventData eventData){
Debug.Log($"OnPointerEnter {eventData.ToString()}");
}
public void OnPointerExit(PointerEventData eventData){
Debug.Log($"OnPointerExit {eventData.ToString()}");
}
}
回到unity编辑器中运行项目,点开背包点击物品查看详情页面的更新,
已实现点击背包物品更换详情页面,
下一步实现UI动画点击效果动画,
首先在ACs动画控制器文件包中创建一个UI文件夹准备放UI动画,
在UI文件夹中创建两个PackageAC背包控制器,
其中PackageAC1代表鼠标掠过的动画控制器,PackageAC2代表鼠标选中的动画控制器,
在PackageItem预制体空间下创建两个空物体,
设置尺寸,
设置子物体Image为拉伸模式
重命名Image为Image1,并设置比例为1.1
再创建Image2,同样设置比例为1.2,拉伸模式
同样添加选中图片,
接下来在ACs的UI文件夹中创建动画Animation,命名为PackageSelectAni
在这个文件夹再创建两个动画,分别对应 鼠标进入物品 和 退出物品 的效果,
下一步绑定组件Animator,将PackageAC1拖拽给 选中对象,
打开PackageAC1动画控制器,将PackageSelectAni动画拖拽在动画控制器中,
创建一个空状态并连线,
然后添加Trigger类型的变量,
接着双击打开Animation这个窗口,
选中设置谁的动画,
同样添加Image2的color,
点击左上角的红点即可进入录制模式,点击播放修改两个image的d颜色为0,再次点击结束录制即可,
同样方法绑定鼠标点击对象组件Animator并拖拽PackageAC2,
双击PackageAC2进入动画控制器,并拖拽其余两个动画,
还是把默认条件设置为空状态,
然后创建两个转换变量In 和 Out,用来设置切换鼠标进入与鼠标退出,
对于MouseOverAni这个对象添加一个Image,并设置大小,拉伸模式
我们先将SelectAni隐藏,
还是添加一个color,
1.点击录制,
2.拖动动画线到中间,设置color d 为 0,
3.调试:
4.结束录制,
同样手法配置PackageMouseOut动画,
提醒:In的动画color透明度变化是 0 - 1 - 0,而Out的动画color透明度变化是 1 - 0,
Select的动画为 0.5 - 1-0.5 - 0,总之最后透明度均为0,
动画控制器设置完成,
下一步修改PackageCell.cs脚本:
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class PackageCell : MonoBehaviour,IPointerClickHandler,IPointerEnterHandler,IPointerExitHandler{
Transform UIIcon;
Transform UIHead;
Transform UINew;
Transform UISelect;
Transform UILevel;
Transform UIStars;
Transform UIDeleteSelect;
//添加
Transform UISelectAni;
Transform UIMouseOverAni;
//动态数据
PackageLocalItem packageLocalData;
//静态数据
PackageTableItem packageTableItem;
//父物体也就是PackagePanel本身
PackagePanel uiParent;
void Awake(){
InitUIName();
}
void InitUIName(){
UIIcon = transform.Find("Top/Icon");
UIHead = transform.Find("Top/Head");
UINew = transform.Find("Top/New");
UILevel = transform.Find("Bottom/LevelText");
UIStars = transform.Find("Bottom/Stars");
UISelect = transform.Find("Select");
UIDeleteSelect = transform.Find("DeleteSelect");
//添加
UIMouseOverAni = transform.Find("MouseOverAni");
UISelectAni = transform.Find("SelectAni");
UIDeleteSelect.gameObject.SetActive(false);
//添加
UIMouseOverAni.gameObject.SetActive(false);
UISelectAni.gameObject.SetActive(false);
}
//刷新
public void Refresh(PackageLocalItem packageLocalData, PackagePanel uiParent){
//数据初始化
this.packageLocalData = packageLocalData;
this.packageTableItem = MainGame.Instance.GetPackageItemById(packageLocalData.id);
this.uiParent = uiParent;
//等级信息
UILevel.GetComponent<Text>().text = "Lv." + this.packageLocalData.level.ToString();
//是否是新获得?
UINew.gameObject.SetActive(this.packageLocalData.isNew);
Debug.Log("ImagePath: " + this.packageTableItem.imagePath);
//物品的图片
Texture2D t = (Texture2D)Resources.Load(this.packageTableItem.imagePath);
if (t != null){
Sprite temp = Sprite.Create(t, new Rect(0, 0, t.width, t.height), new Vector2(0, 0));
// 继续处理 Sprite 对象
UIIcon.GetComponent<Image>().sprite = temp;
}
else{
// 处理纹理加载失败的情况
Debug.LogError("Failed to load texture.");
}
//刷新星级
RefreshStars();
}
//刷新星级
public void RefreshStars(){
for (int i = 0; i < UIStars.childCount; i++){
Transform star = UIStars.GetChild(i);
if (this.packageTableItem.star > i)
star.gameObject.SetActive(true);
else
star.gameObject.SetActive(false);
}
}
public void OnPointerClick(PointerEventData eventData){
if (this.uiParent.ChooseUid == this.packageLocalData.uid)
return;
//根据点击设置最新的uid 进而刷新详情界面
this.uiParent.ChooseUid = this.packageLocalData.uid;
UISelectAni.gameObject.SetActive(true);
UISelectAni.GetComponent<Animator>().SetTrigger("In");
}
public void OnPointerEnter(PointerEventData eventData){
UIMouseOverAni.gameObject.SetActive(true);
UIMouseOverAni.GetComponent<Animator>().SetTrigger("In");
}
public void OnPointerExit(PointerEventData eventData){
Debug.Log($"OnPointerExit {eventData.ToString()}");
}
}
最后这个操作可以确保我们的子物品不会影响我们点触事件的判断,
运行项目即可实现,
鼠标滑动效果,
鼠标点击效果,
点击右上角×退出键即可退出面板,
End.
相关文章:

项目02《游戏-08-开发》Unity3D
基于 项目02《游戏-07-开发》Unity3D , 本次任务做物品相互与详情的功能, 首先要做 点击相应, 接下来用接口实现点击相应事件,具体到代码中,我们找到需要响应鼠标事件的对象, 双击PackageCell…...

【数据库原理及应用】简答题归纳总结
第一章 数据库概论 1.人工管理阶段数据管理的特点: (1)数据不保存在机器中 (2)无专用的软件对数据进行管理 (3)只有程序的概念,没有文件的概念 (4)数据面向程…...

通过无线打通两个路由器
通过无线打通两个路由器 上网向导无线连接 配置比较简单,有些路由器支持有些不支持,支持的大致就是下面的方法,不过不同型号面板不一样,这里主要学习方法,所以不做路由器型号介绍。 重要的事情说三遍:学习要…...

idea 配置文件,中文出现乱码如何解决
在进行 spring 项目开发时,项目中有 application.properties/application.yml 等配置文件,在配置文件中使用中文注解时可能会出现乱码的情况,如下: 这是因为 idea 配置文件的编码和其他文件的不同,我们需要修改配置文件…...

网络协议梳理
1 引言 在计算机网络中要做到有条不紊地交换数据,就必须遵守一些事先约定好的规则。这些规则明确规定了所交换的数据的格式以及有关的同步问题。这里所说的同步不是狭义的(即同频或同频同相)而是广义的,即在一定的条件下应当发生什…...

14. 【Linux教程】文件压缩与解压
文件压缩与解压 前面小节介绍了如何对文件和目录删除、移动操作,本小节介绍如何使用命令对文件和目录进行压缩与解压操作,常见的压缩包格式有 .bz2、.Z、.gz、.zip、.xz,压缩之后的文件或目录占用更少的空间。 1. tar 命令介绍 下面列举 ta…...

ruoyi-nbcio中xxl-job的安装与使用
更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio 演示地址: http://122.227.135.243:9666 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码: https://gitee.com/nbach…...
从零学算法162
162.峰值元素是指其值严格大于左右相邻值的元素。 给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。 你可以假设 nums[-1] nums[n] -∞ 。 你必须实现时间复杂度为 O…...

5.0 ZooKeeper 数据模型 znode 结构详解
数据模型 在 zookeeper 中,可以说 zookeeper 中的所有存储的数据是由 znode 组成的,节点也称为 znode,并以 key/value 形式存储数据。 整体结构类似于 linux 文件系统的模式以树形结构存储。其中根路径以 / 开头。 进入 zookeeper 安装的 …...

《数电》理论笔记-第1章-逻辑代数基础
参考:视频 和 《数字电路与逻辑设计》 电子书 一,第1章 逻辑代数基础 1 数字量和模拟量 略 2 数制(十进制,二进制,八进制和十六进制) 拨电话(BoDH)---(2八10十六&…...
计算指定路径下的可用空间大小
方法一、使用psutil库 import psutildef check_disk_space(path):usage psutil.disk_usage(path)## 1GB 1 * 1024 * 1024 * 1024字节if usage.free > 1 * 1024 * 1024 * 1024:return 1else:return 0disk_path "/home" result check_disk_space(disk_path) pr…...

2023年全球软件架构师峰会(ArchSummit上海站):核心内容与学习收获(附大会核心PPT下载)
微服务架构是当今软件架构的主流趋势之一。随着云计算和分布式系统的普及,越来越多的企业开始采用微服务架构来构建他们的应用。微服务架构可以将一个大型的应用拆分成多个小型的服务,每个服务都独立部署、独立运行,并通过轻量级的通信协议进…...
踩坑实录(Second Day)
作为公司的小菜鸟,每天都踩坑应该是一件很正常的事情吧,哈哈哈。今天遇到了比较棘手的问题,以前从来没有遇到过。然后就是在某平台上接的一个 bug 修改的单子,也拿出来和大家分享一下~ 此为第二篇(2024 年 02 月 05 日…...
已解决org.springframework.web.HttpMediaTypeNotAcceptableException异常的正确解决方法,亲测有效!!!
已解决org.springframework.web.HttpMediaTypeNotAcceptableException异常的正确解决方法,亲测有效!!! 文章目录 问题分析 报错原因 解决思路 解决方法 总结 问题分析 在Spring MVC应用中处理HTTP请求时,我们有…...

根据MySql建表语句创建Java实体类工具
点击下载《根据MySql建表语句创建Java实体类工具》 1. 前言 在软件开发领域,特别是在构建企业级应用时,数据模型与代码模型之间的映射是至关重要的。该软件是一款基于C#开发的高效工具,它将这一繁琐且容易出错的过程变得简洁且快速。此工具…...

做跨境电商需要使用住宅代理IP吗?
住宅代理IP是近年来跨境电商领域日益受到重视的技术工具,不仅可以保护隐私、优化网络速度,还能助推跨境电商的精细化管理。接下来,我们将深入探讨利用住宅代理IP如何为跨境电商业务带来竞争优势。 一、住宅代理IP与跨境电商 住宅代理IP&…...

vue3 之 组合式API—reactive和ref函数
ref() 作用:接收简单类型或者对象类型的数据传入并返回一个响应式的对象 核心步骤: 1️⃣ 从 vue 包中导入 ref 函数 2️⃣在 <script setup>// 导入import { ref } from vue// 执行函数 传入参数 变量接收const count …...

Python库-PyAutoGUI
pyautogui是一个Python库,可以自动控制键盘和鼠标,非常适合进行自动化任务。它可以用于各种场景,比如自动化测试、数据录入任务,甚至是简单的游戏机器人。下面是一个关于pyautogui的入门教程,包括它的安装、基本使用方…...
越权测试是什么?
一、越权测试是什么? 越权漏洞是web应用程序中常见的一种安全漏洞。它的威胁在于一个账户可控制全站用户数据。越权漏洞产生的原因主要是因为开发人员在对数据进行增删改查时对客户端的请求数据过分相信而遗漏了权限的判定。 二、越权漏洞的分类 越权分为2种&…...

H5 简约四色新科技风引导页源码
H5 简约四色新科技风引导页源码 源码介绍:一款四色切换自适应现代科技风动态背景的引导页源码,源码有主站按钮,分站按钮2个,QQ联系站长按钮一个。 下载地址: https://www.changyouzuhao.cn/11990.html...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...