RPG项目01_UI登录

这篇具有很好参考价值的文章主要介绍了RPG项目01_UI登录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

首先创建一个项目

RPG项目01_UI登录,c#,1024程序员节

将资源包导进Resources文件夹

RPG项目01_UI登录,c#,1024程序员节

创建一个Scripts脚本文件夹

RPG项目01_UI登录,c#,1024程序员节

然后再对Scripts脚本文件夹分门别类

RPG项目01_UI登录,c#,1024程序员节

导入UI资源包

RPG项目01_UI登录,c#,1024程序员节

创建一个Image

RPG项目01_UI登录,c#,1024程序员节

按住Alt 选择右下角 image就会覆盖整个面板

RPG项目01_UI登录,c#,1024程序员节

修改image名字为BG

RPG项目01_UI登录,c#,1024程序员节

将image图片放置背景栏

RPG项目01_UI登录,c#,1024程序员节

再创建一个image

RPG项目01_UI登录,c#,1024程序员节

改名为MainMenu

RPG项目01_UI登录,c#,1024程序员节

修改MainMenu得长宽尺寸 320 500

RPG项目01_UI登录,c#,1024程序员节image选取输入3_0

RPG项目01_UI登录,c#,1024程序员节

RPG项目01_UI登录,c#,1024程序员节

   RPG项目01_UI登录,c#,1024程序员节

RPG项目01_UI登录,c#,1024程序员节

解释:

RPG项目01_UI登录,c#,1024程序员节

RPG项目01_UI登录,c#,1024程序员节

选择具体图片

RPG项目01_UI登录,c#,1024程序员节

RPG项目01_UI登录,c#,1024程序员节

点击以下Slice切片,即可在图片中选择区域分割

RPG项目01_UI登录,c#,1024程序员节

这样每一块都可以分割了

RPG项目01_UI登录,c#,1024程序员节

如果切割不明显,可以做见拉动自定义截取

仔细看图片外面有蓝色的线框,和四个绿色的点

调节四个点内缩

RPG项目01_UI登录,c#,1024程序员节

这样的设定是设计成无论是横向拉伸与纵向拉伸都不会被拉伸

这样设定是为了适配任何面板,点击Apply应用

替换掉图片对面板进行拖拽拉伸,其都不会改变最外四角边框

RPG项目01_UI登录,c#,1024程序员节

RPG项目01_UI登录,c#,1024程序员节

知识点讲解完成换成图片3_0 并调节位置与尺寸

RPG项目01_UI登录,c#,1024程序员节

调节字体大小

RPG项目01_UI登录,c#,1024程序员节

调节y轴位置

RPG项目01_UI登录,c#,1024程序员节

ctrl + d 复制出一份

RPG项目01_UI登录,c#,1024程序员节

改名为BtnLoad

RPG项目01_UI登录,c#,1024程序员节

修改第二个Btn得y轴坐标为10

RPG项目01_UI登录,c#,1024程序员节

修改字体内容

RPG项目01_UI登录,c#,1024程序员节

继续复制向下串90坐标

RPG项目01_UI登录,c#,1024程序员节

以此手法

RPG项目01_UI登录,c#,1024程序员节

在代码文件夹中新建文件夹Effect效果

RPG项目01_UI登录,c#,1024程序员节

文件夹下新建脚本UITween

RPG项目01_UI登录,c#,1024程序员节

将以下代码复制UITween

RPG项目01_UI登录,c#,1024程序员节

using System.Collections;
using UnityEngine;
public delegate void FunBack();
public class UITween : MonoBehaviour{
    Vector2 startPos;//开始坐标
    Vector2 targetPos;
    public Vector2 offsetPos;
    public event FunBack funback;
    public event FunBack funStart;
    RectTransform rect;//当前坐标
    void Awake(){
        startPos = transform.position;
        rect = GetComponent<RectTransform>();
    }
    public void UIStart(){
        targetPos = offsetPos + new Vector2(Screen.width / 2, Screen.height / 2);
        StartCoroutine(MoveTo());
        if (funStart != null){
            funStart();
        }
    }
    public IEnumerator MoveTo(){
        while (Mathf.Abs(rect.position.x - targetPos.x) > 5){
            rect.position = Vector2.Lerp(rect.position, targetPos, 0.01f);
            yield return new WaitForEndOfFrame();
        }
        if (funback != null){
            funback();
            funback = null;
        }
    }
    public void UIBack(){
        targetPos = startPos;
        StartCoroutine(MoveTo());
    }
    public void AddEventBackHandle(FunBack fun){
        funback += fun;
    }
    public void AddEventStartHandle(FunBack fun){
        funback += fun;
    }
    public void SetBtnHandle(params UITween[] uis){
        for (int i = 0; i < uis.Length; i++){
            AddEventBackHandle(uis[i].UIStart);
        }
    }
}
之后回到unity场景中将主UI面板拖拽至屏幕外侧

RPG项目01_UI登录,c#,1024程序员节

在Canvas下再创建一个image

RPG项目01_UI登录,c#,1024程序员节

修改名字QuitMenu

RPG项目01_UI登录,c#,1024程序员节

尺寸修改 600 * 300

RPG项目01_UI登录,c#,1024程序员节

图片使用4_1

RPG项目01_UI登录,c#,1024程序员节

接着复制一个按钮

RPG项目01_UI登录,c#,1024程序员节

粘粘作为子物体

RPG项目01_UI登录,c#,1024程序员节

RPG项目01_UI登录,c#,1024程序员节

修改位置

RPG项目01_UI登录,c#,1024程序员节

复制并修改名字为 BtnYes 和 BtnNo

RPG项目01_UI登录,c#,1024程序员节

将QuitMenu的x轴设为1000移出屏幕外

RPG项目01_UI登录,c#,1024程序员节

在脚本文件夹下的Manager文件夹下新建脚本MainMenu

RPG项目01_UI登录,c#,1024程序员节

将以下代码复制

RPG项目01_UI登录,c#,1024程序员节

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MainMenu : MonoBehaviour
{
    UITween mainMenu;
    UITween quitMenu;
    void Start()
    {
        mainMenu = GetComponent<UITween>();
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}
接下来再在Manager文件夹下创建脚本GameManager

RPG项目01_UI登录,c#,1024程序员节

将以下代码复制

RPG项目01_UI登录,c#,1024程序员节

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum GameState { Play,Menu };
public class GameManager 
{
    //当只需要一个的时候使用静态类
    public static GameState gameState = GameState.Play;
    public static void Init() {
    
    }
    public static T FindType<T>(Transform t, string n) {
        return t.Find(n).GetComponent<T>();
    }
    public static T ParseEnum<T>(string value) {
        return (T)System.Enum.Parse(typeof(T), value, true);
    }
}
修改MainMenu脚本代码:

RPG项目01_UI登录,c#,1024程序员节

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MainMenu : MonoBehaviour
{
    UITween mainMenu;
    UITween quitMenu;
    void Start()
    {
        mainMenu = GetComponent<UITween>();
        quitMenu = GameManager.FindType<UITween>(transform.parent, "QuitMenu");
        mainMenu.UIStart();
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}
接下来挂载代码

RPG项目01_UI登录,c#,1024程序员节

RPG项目01_UI登录,c#,1024程序员节

RPG项目01_UI登录,c#,1024程序员节

运行即实现主功能面板缓慢移至屏幕中心

RPG项目01_UI登录,c#,1024程序员节

如果觉得移速过慢可以调整UITween脚本中的移动速度

RPG项目01_UI登录,c#,1024程序员节

 RPG项目01_UI登录,c#,1024程序员节

修改代码前,看一下unity场景中Canvas的Mainmenu下的四个按键

RPG项目01_UI登录,c#,1024程序员节

然后修改MainMenu代码

RPG项目01_UI登录,c#,1024程序员节

继续修改MainMenu代码:

RPG项目01_UI登录,c#,1024程序员节

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class MainMenu : MonoBehaviour{
    UITween mainMenu;
    UITween quitMenu;
    Button btnStart;
    Button btnLoad;
    Button btnQuit;
    Button btnSet;
    void Start(){
        //gameObject.通常省略
        mainMenu = gameObject.GetComponent<UITween>();
        //查找子物体身上得组件 先返回父级再找QuitMenu
        quitMenu = GameManager.FindType<UITween>(transform.parent, "QuitMenu");

        btnStart = GameManager.FindType<Button>(transform, "BtnStart");
        btnLoad = GameManager.FindType<Button>(transform, "BtnLoad");
        btnQuit = GameManager.FindType<Button>(transform, "BtnQuit");
        btnSet = GameManager.FindType<Button>(transform, "BtnSet");
        //监听
        btnQuit.onClick.AddListener(delegate
        {
            mainMenu.SetBtnHandle(quitMenu);
            mainMenu.UIBack();
        });
        mainMenu.UIStart();
    }
    void Update()
    {
        
    }
}
回到unity中运行即可实现:

开始主页面移至屏幕中心

RPG项目01_UI登录,c#,1024程序员节

点击退出游戏按钮,主页面移出屏幕,提示是否信息页面进入屏幕中心

RPG项目01_UI登录,c#,1024程序员节

下面继续做提示是否退出游戏页面代码

修改MainMenu代码:

RPG项目01_UI登录,c#,1024程序员节

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class MainMenu : MonoBehaviour{
    UITween mainMenu;
    UITween quitMenu;
    Button btnStart;
    Button btnLoad;
    Button btnQuit;
    Button btnSet;
    Button BtnYes;
    Button BtnNo;
    void Start(){
        //gameObject.通常省略
        mainMenu = gameObject.GetComponent<UITween>();
        //查找子物体身上得组件 先返回父级再找QuitMenu
        quitMenu = GameManager.FindType<UITween>(transform.parent, "QuitMenu");        btnStart = GameManager.FindType<Button>(transform, "BtnStart");
        btnLoad = GameManager.FindType<Button>(transform, "BtnLoad");
        btnQuit = GameManager.FindType<Button>(transform, "BtnQuit");
        btnSet = GameManager.FindType<Button>(transform, "BtnSet");
        BtnYes = GameManager.FindType<Button>(quitMenu.transform, "BtnYes");
        BtnNo = GameManager.FindType<Button>(quitMenu.transform, "BtnNo");
        //监听
        btnQuit.onClick.AddListener(delegate
        {
            mainMenu.SetBtnHandle(quitMenu);
            mainMenu.UIBack();
        });
        BtnYes.onClick.AddListener(Application.Quit);
        BtnNo.onClick.AddListener(delegate
        { 
            quitMenu.SetBtnHandle(mainMenu);
            quitMenu.UIBack();
        });
        mainMenu.UIStart();
    }
    void Update()
    {
        
    }
}

修改提示面板信息

RPG项目01_UI登录,c#,1024程序员节

RPG项目01_UI登录,c#,1024程序员节

RPG项目01_UI登录,c#,1024程序员节

回到unity场景中运行测试

RPG项目01_UI登录,c#,1024程序员节

主体思想就是在MainMenu等面板上挂载UITween移动代码只负责UI移动,后续用Manager管理开始点及目标点即可。

接下来做一个UI得片头动画:

首先在Canvas下添加一个 Raw Image

RPG项目01_UI登录,c#,1024程序员节

改Image名为Video

RPG项目01_UI登录,c#,1024程序员节

点击锚点alt + 右下角全屏

RPG项目01_UI登录,c#,1024程序员节

在Video下新增一个组件Video Player

RPG项目01_UI登录,c#,1024程序员节

在顶层文件夹下创建一个Video文件夹

RPG项目01_UI登录,c#,1024程序员节

RPG项目01_UI登录,c#,1024程序员节

拖动视频放入Video Player 的 Video Clip选框中

RPG项目01_UI登录,c#,1024程序员节

再右键Video文件夹下创建一个渲染纹理Render Texture

RPG项目01_UI登录,c#,1024程序员节

将渲染纹理分别放在Video的Raw Image下的Texture内框,及Video Player下的Target Texture内框中。

RPG项目01_UI登录,c#,1024程序员节

换成满屏

RPG项目01_UI登录,c#,1024程序员节

RPG项目01_UI登录,c#,1024程序员节

这样视频就导入了开场UI

拓展知识:

所有UI都有Raycast Target 射线检测目标 如果是勾选的

RPG项目01_UI登录,c#,1024程序员节

点击射线是能碰撞到这个UI的 如果取消 点击就会穿过它

最后代码:

RPG项目01_UI登录,c#,1024程序员节

using UnityEngine;
public enum GameState { Play,Menu };
public class GameManager {
    //当只需要一个的时候使用静态类
    public static GameState gameState = GameState.Play;
    public static void Init() {

    }
    public static T FindType<T>(Transform t, string n) {
        return t.Find(n).GetComponent<T>();
    }
    public static T ParseEnum<T>(string value) {
        return (T)System.Enum.Parse(typeof(T), value, true);
    }
}
RPG项目01_UI登录,c#,1024程序员节

using UnityEngine;
using UnityEngine.UI;
public class MainMenu : MonoBehaviour{
    UITween mainMenu;
    UITween quitMenu;
    Button btnStart;
    Button btnLoad;
    Button btnQuit;
    Button btnSet;
    Button BtnYes;
    Button BtnNo;
    void Start(){
        //gameObject.通常省略
        mainMenu = gameObject.GetComponent<UITween>();
        //查找子物体身上得组件 先返回父级再找QuitMenu
        quitMenu = GameManager.FindType<UITween>(transform.parent, "QuitMenu");

        btnStart = GameManager.FindType<Button>(transform, "BtnStart");
        btnLoad = GameManager.FindType<Button>(transform, "BtnLoad");
        btnQuit = GameManager.FindType<Button>(transform, "BtnQuit");
        btnSet = GameManager.FindType<Button>(transform, "BtnSet");
        BtnYes = GameManager.FindType<Button>(quitMenu.transform, "BtnYes");
        BtnNo = GameManager.FindType<Button>(quitMenu.transform, "BtnNo");
        //大多数需要动态UI时 需要使用监听
        //监听 实际可以看成是一种委托 在实现一种匿名函数
        btnQuit.onClick.AddListener(delegate
        {
            //设置后续动作
            mainMenu.SetBtnHandle(quitMenu);
            mainMenu.UIBack();
        });
        BtnYes.onClick.AddListener(Application.Quit);
        BtnNo.onClick.AddListener(delegate
        { 
            quitMenu.SetBtnHandle(mainMenu);
            quitMenu.UIBack();
        });
        mainMenu.UIStart();
    }
    void Update(){
        
    }
}
RPG项目01_UI登录,c#,1024程序员节

using System.Collections;
using UnityEngine;
public delegate void FunBack();
//通用工具类pow-有部分多余代码等待拓展
public class UITween : MonoBehaviour{
    Vector2 startPos;//开始坐标
    Vector2 targetPos;
    //偏移量本次不使用
    public Vector2 offsetPos;
    public event FunBack funback;
    public event FunBack funStart;
    RectTransform rect;//当前坐标
    void Awake(){
        startPos = transform.position;
        rect = GetComponent<RectTransform>();
    }
    //从屏幕外部进入屏幕的函数 UIStart()
    public void UIStart(){
        targetPos = offsetPos + new Vector2(Screen.width / 2, Screen.height / 2);
        StartCoroutine(MoveTo());
        if (funStart != null){
            funStart();
        }
    }
    //协程函数 模拟Update函数
    //携程具体作用:1.重复执行 2.延迟执行
    public IEnumerator MoveTo(){
        //按照绝对值根据距离是否大于五判断UI到没到目标点 
        while (Mathf.Abs(rect.position.x - targetPos.x) > 5){
            //Lerp比例插值越走越慢
            rect.position = Vector2.Lerp(rect.position, targetPos, 0.03f);
            //等待一帧时间
            yield return new WaitForEndOfFrame();
        }
        //回调
        if (funback != null){
            funback();
            //释放
            funback = null;
        }
    }
    public void UIBack(){
        targetPos = startPos;
        StartCoroutine(MoveTo());
    }
    //添加后续动作 后续动作是谁就写谁FunBack
    public void AddEventBackHandle(FunBack fun){
        funback += fun;
    }
    public void AddEventStartHandle(FunBack fun){
        funback += fun;
    }
    public void SetBtnHandle(params UITween[] uis){
        for (int i = 0; i < uis.Length; i++){
            AddEventBackHandle(uis[i].UIStart);
        }
    }
}
如果想点击视频动画就进入主页面,则需在视频中加入button按钮

RPG项目01_UI登录,c#,1024程序员节

RPG项目01_UI登录,c#,1024程序员节

扩展可以添加其他窗口页面:

修改MainMenu脚本代码:

RPG项目01_UI登录,c#,1024程序员节

using UnityEngine;
using UnityEngine.UI;
public class MainMenu : MonoBehaviour{
    UITween mainMenu;
    UITween quitMenu;
    UITween loadMenu;
    UITween setMenu;

    Button btnStart;
    Button btnLoad;
    Button btnQuit;
    Button btnSet;
    Button BtnYes;
    Button BtnNo;
    void Start(){
        //gameObject.通常省略
        mainMenu = gameObject.GetComponent<UITween>();
        //查找子物体身上得组件 先返回父级再找QuitMenu
        quitMenu = GameManager.FindType<UITween>(transform.parent, "QuitMenu");
        //loadMenu = GameManager.FindType<UITween>(transform.parent, "LoadMenu");
        //setMenu = GameManager.FindType<UITween>(transform.parent, "SetMenu");

        btnStart = GameManager.FindType<Button>(transform, "BtnStart");
        btnLoad = GameManager.FindType<Button>(transform, "BtnLoad");
        btnQuit = GameManager.FindType<Button>(transform, "BtnQuit");
        btnSet = GameManager.FindType<Button>(transform, "BtnSet");
        BtnYes = GameManager.FindType<Button>(quitMenu.transform, "BtnYes");
        BtnNo = GameManager.FindType<Button>(quitMenu.transform, "BtnNo");
        //大多数需要动态UI时 需要使用监听
        //监听 实际可以看成是一种委托 在实现一种匿名函数
        btnQuit.onClick.AddListener(delegate
        {
            //设置后续动作
            mainMenu.SetBtnHandle(quitMenu);
            mainMenu.UIBack();
        });
        BtnYes.onClick.AddListener(Application.Quit);
        BtnNo.onClick.AddListener(delegate
        { 
            quitMenu.SetBtnHandle(mainMenu);
            quitMenu.UIBack();
        });
        mainMenu.UIStart();
    }
    void Update(){
        
    }
}
添加Unity操作后,打开注释代码即可运行,拓展:

修改代码,让视频动画被点击之后,开始页面才进入屏幕

做好之后修改场景名为UI文章来源地址https://www.toymoban.com/news/detail-773224.html

到了这里,关于RPG项目01_UI登录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 好用且免费的CodeWhisperer,给1024程序员节送礼来了

          国庆期间没有胆量去人从众的景点,关在家里刷手机时意外在亚马逊的User Group公众号上发现了CodeWhisperer这么个好东西(bu yao qian),以后撸代码也可以提高生产力(fang yang mo yu)了,这还不赶紧上手试一下。看官方介绍说它支持流行的IDE开发工具,包括VS Code、Intelli

    2024年02月08日
    浏览(50)
  • 黑马程序员前端 Vue3 小兔鲜电商项目——(八)登录页面

    登录页面的主要功能就是表单校验和登录登出业务。 account password cdshi0080 123456 cdshi0081 123456 cdshi0082 123456 cdshi0083 123456 cdshi0084 123456 cdshi0085 123456 cdshi0086 123456 cdshi0087 123456 cdshi0088 123456 模版代码 在 srcviewsLoginindex.vue 中添加登录页代码: 配置路由跳转 修改 srcviewsLayoutcompon

    2024年02月10日
    浏览(52)
  • 1024程序员节带你玩转图片Exif信息获取之JavaScript

    目录 一、前言 二、背景 三、Exif.js          1、Exif.js 简介 2、Exif.js 引入 四、多场景展示数据获取 1、原始图片直接获取  2、base64 编码文件加载  3、文件上传的方式加载  五、总结        1024是2的十次方,二进制计数的基本计量单位之一。1G=1024M,而1G与1级谐音,也有一

    2024年02月20日
    浏览(58)
  • 1024程序员节特辑 | Spring Boot实战 之 MongoDB分片或复制集操作

    Spring实战系列文章: Spring实战 | Spring AOP核心秘笈之葵花宝典 Spring实战 | Spring IOC不能说的秘密? 国庆中秋特辑系列文章: 国庆中秋特辑(八)Spring Boot项目如何使用JPA 国庆中秋特辑(七)Java软件工程师常见20道编程面试题 国庆中秋特辑(六)大学生常见30道宝藏编程面试题

    2024年02月08日
    浏览(78)
  • RPG项目01_UI面板Game

    基于“RPG项目01_技能释放”,将UI包导入Unity场景中, 将图片放置 拖拽 取消勾选(隐藏攻击切片) 对技能添加蒙版 调节父子物体大小一致 将子类蒙版复制 执行5次 运行即可看到技能使用完的冷却条 在Scripts下创建UI文件夹 写代码: using System.Collections; using System.Collections.Ge

    2024年02月04日
    浏览(39)
  • 1024程序员节特辑 | ELK+ 用户画像构建个性化推荐引擎,智能实现“千人千面”

    专栏集锦,大佬们可以收藏以备不时之需 Spring Cloud实战专栏:https://blog.csdn.net/superdangbo/category_9270827.html Python 实战专栏:https://blog.csdn.net/superdangbo/category_9271194.html Logback 详解专栏:https://blog.csdn.net/superdangbo/category_9271502.html tensorflow专栏:https://blog.csdn.net/superdangbo/category_869

    2024年02月07日
    浏览(82)
  • 1024程序员狂欢节 | IT前沿技术、人工智能、数据挖掘、网络空间安全技术

    一年一度的1024程序员狂欢节又到啦!成为更卓越的自己,坚持阅读和学习,别给自己留遗憾,行动起来吧! 那么,都有哪些好书值得入手呢?小编为大家整理了前沿技术、人工智能、集成电路科学与芯片技术、新一代信息与通信技术、网络空间安全技术,四大热点领域近期

    2024年02月06日
    浏览(64)
  • 1024程序员节?我们整点AI绘图玩玩吧,一文教你配置stable-diffusion

    需提前准备:一台高性能的电脑(尤其是显存)、python、Git、梯子。 其实Github上有很多关于Stable diffusion的库,综合对比之后,我选取的是比较全面的AUTOMATIC1111这个,源码链接:Stable-diffusion(Github) 找到安装那块的教程,此教程以windows为例。 ps:如果你电脑上已经有了pyt

    2024年01月16日
    浏览(72)
  • 1024程序员节特辑 | 解密Spring Cloud Hystrix熔断提高系统的可用性和容错能力

    专栏集锦,大佬们可以收藏以备不时之需 Spring Cloud实战专栏:https://blog.csdn.net/superdangbo/category_9270827.html Python 实战专栏:https://blog.csdn.net/superdangbo/category_9271194.html Logback 详解专栏:https://blog.csdn.net/superdangbo/category_9271502.html tensorflow专栏:https://blog.csdn.net/superdangbo/category_869

    2024年02月08日
    浏览(52)
  • PHP框架开发实践 | 1024 程序员节:通过index.php找到对应的controller是如何实现的

    🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌,CSDN博客专家,阿里云社区专家博主,2023年6月CSDN上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师,项目技术负责人。 🏆本文已收录于PHP专栏:PHP进阶实战教程。 🎉欢迎 👍点赞✍评论⭐收藏

    2024年02月08日
    浏览(69)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包