Unity中2D和UGUI图集的理解与使用

Unity开发——UGUI优化之图集的生成与运用 制作2D游戏和UI的Batches优化解决方案~ 阅读详情

图集

什么是图集?

在使用3D技术开发2D游戏或制作UI时(即使用GPU绘制),都会使用到图集,而使用CPU渲染的2D游戏和UI则不存在图集这个概念(比如Flash的原生显示列表),那么什么是图集呢?准确的说法图集是一张包含了多个小图的大图和一份记录了每个小图id、位置、尺寸等数据的数据文件,一个图集应该对应两个文件,当然也有人把数据集成到图片中,导致看起来只有一张图片(参考自DragonBones的做法)。

为什么要用图集?

在GPU已经成为PC、手机等设备的必备组件的现在,把所有显示的绘制操作交给专门处理图像的GPU显然比交给CPU更合适,这样空闲下来的CPU可以集中力量处理游戏的逻辑运算。

而GPU处理图像的做法和CPU是不一样的,在GPU中,我们要绘制一个图像需要提交图片(即纹理)到显存,然后在进行绘制(这个过程称为一次DrawCall),那么如果我们一帧要绘制100个就需要提交100次图片,如果使用包含了这100图片的图集,只需要一次提交即可,即一次DrawCall就搞定,处理效率上会有很大的提升。

另外使用图集也方便管理和归类各个模块的图片,可以通过一次加载和一次卸载完成多个图片的处理,同理,加载次数也下来了,可以提升运行效率。

Unity2D中的图集

其实用过NGUI的同学都知道在拼界面之前都必须先制作好对应的图集才行,然而在Unity2D或UGUI中,Unity却自己集成了图集的操作,目的是让我们忘掉图集的存在,更加关注设计这个层面。

如何使用图集

在Unity中我们只要使用小图片即可,可以通过设置图片的Packing Tag来指定小图会被打包到的图集,比如2个小图的Packing Tag都叫“MyAtlas”,则Unity会将这两个小图打包到名为“MyAtlas”的图集中。

注意图片不能放在Resources文件夹下面,Resources文件夹下的资源将不会被打入图集。

是否打包图集的控制选项:Editor->Project Settings 下面有sprite packer的模式。Disabled表示不打包图集,Enabled For Builds 表示只有打包应用的时候才会打包图集,Always Enabled 表示始终会打包图集。

在Windows->Sprite Packer 里,点击packer 在这里你就可以预览到你的图集信息,图集文件被保存在和Assets文件夹同级的目录,Libary/AtlasCache里面。图集的大小还有图集的格式等等很多参数我们都是可以控制的,也可以通过脚本来设置。

通过设置我们就可以发现多个同一Packing Tag的小图放到场景中只会消耗一个DrawCall,表示我们的图集已经开始起作用了。

动态设置的问题

可是Unity的这种设计在下面的这种情况下却给我们带来了很大的困扰:

当我们希望通过代码的方式修改纹理时会无从下手,因为Unity3D并没有给我们提供加载图集和获取图集中指定小图的API。

解决方案

目标是我想把图集放在Resources中加载。

首先我们的原图不能放在Resources文件夹中,这样会导致资源大小翻倍。

具体的思路是通过脚本创建对应的名称的预制件,同时将加载的图片(Sprite)作为该预制件的SpriteRenderer组件的sprite属性即可。

打包代码

打包代码来自我的开源项目中,有一些具体的规则,大家可以看注释:

 =================================================================================================
 2 //
 3 //    Hammerc Library
 4 //    Copyright 2015 hammerc.org All Rights Reserved.
 5 //
 6 //    See LICENSE for full license information.
 7 //
 8 // =================================================================================================
 9 
10 using System.IO;
11 using UnityEditor;
12 using UnityEngine;
13 
14 /// <summary>
15 /// 
16 /// 2D 图集生成对应预制件脚本类.
17 /// 
18 /// 解决问题: 
19 /// 解决不能动态设置 Sprite 对象的贴图的问题, 因为分散的小图最终需要打包为图集而 Unity3D 又将图集的处理隐藏, 所以需要将小图的信息存放到预制件中.
20 /// 
21 /// 使用方法及步骤: 
22 /// 1.修改源目录及目标目录为自己使用的目录;
23 /// 2.把小图存放到源目录中;
24 /// 3.在菜单栏点击 Hammerc/2D/MakeSpritePrefabs 即可在目标目录下生成对应的预制件;
25 /// 4.通过获取生成的预制件的 sprite 对象即可在程序中使用小图.
26 /// 
27 /// </summary>
28 public class MakeSpritePrefabsScript
29 {
30     /// <summary>
31     /// Assets 目录下的小图片目录, 包括子目录的所有图片文件都会进行处理.
32     /// </summary>
33     private const string ORIGIN_DIR = "\\RawData\\Sprites";
34 
35     /// <summary>
36     /// Assets 目录下的小图预制件生成的目标目录, 注意该目录下不要存放其他资源, 每次生成时都会清空该目录下的所有文件.
37     /// </summary>
38     private const string TARGET_DIR = "\\Resources\\Sprites";
39 
40     /// <summary>
41     /// 将制定目录下的原始图片一对一打包成 Prefab 方便在游戏运行中读取指定的图片.
42     /// </summary>
43     [MenuItem("Hammerc/2D/MakeSpritePrefabs")]
44     private static void MakeSpritePrefabs()
45     {
46         EditorUtility.DisplayProgressBar("Make Sprite Prefabs", "Please wait...", 1);
47 
48         string targetDir = Application.dataPath + TARGET_DIR;
49         //删除目标目录
50         if(Directory.Exists(targetDir))
51             Directory.Delete(targetDir, true);
52         if(File.Exists(targetDir + ".meta"))
53             File.Delete(targetDir + ".meta");
54         //创建空的目标目录
55         if(!Directory.Exists(targetDir))
56             Directory.CreateDirectory(targetDir);
57 
58         //获取源目录的所有图片资源并处理
59         string originDir = Application.dataPath + ORIGIN_DIR;
60         DirectoryInfo originDirInfo = new DirectoryInfo(originDir);
61         MakeSpritePrefabsProcess(originDirInfo.GetFiles("*.jpg", SearchOption.AllDirectories), targetDir);
62         MakeSpritePrefabsProcess(originDirInfo.GetFiles("*.png", SearchOption.AllDirectories), targetDir);
63 
64         EditorUtility.ClearProgressBar();
65     }
66 
67     static private void MakeSpritePrefabsProcess(FileInfo[] files, string targetDir)
68     {
69         foreach(FileInfo file in files)
70         {
71             string allPath = file.FullName;
72             string assetPath = allPath.Substring(allPath.IndexOf("Assets"));
73             //加载贴图
74             Sprite sprite = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Sprite)) as Sprite;
75             //创建绑定了贴图的 GameObject 对象
76             GameObject go = new GameObject(sprite.name);
77             go.AddComponent<SpriteRenderer>().sprite = sprite;
78             //获取目标路径
79             string targetPath = assetPath.Replace("Assets" + ORIGIN_DIR + "\\", "");
80             //去掉后缀
81             targetPath = targetPath.Substring(0, targetPath.IndexOf("."));
82             //得到最终路径
83             targetPath = targetDir + "\\" + targetPath + ".prefab";
84             //得到应用当前目录的路径
85             string prefabPath = targetPath.Substring(targetPath.IndexOf("Assets"));
86             //创建目录
87             Directory.CreateDirectory(prefabPath.Substring(0, prefabPath.LastIndexOf("\\")));
88             //生成预制件
89             PrefabUtility.CreatePrefab(prefabPath.Replace("\\", "/"), go);
90             //销毁对象
91             GameObject.DestroyImmediate(go);
92         }
93     }
94 }

加载代码

加载就很简单了,加载对应的预制件,然后取出Sprite即可,核心代码如下:

1 public Sprite LoadSprite(string spriteName)
2 {
3     return Resources.Load<GameObject>("Sprites/" + spriteName).GetComponent<SpriteRenderer>().sprite;
4 }

设置贴图就是向GameObject添加SpriteRenderer脚本后设置其sprite属性即可,如下:

this.gameObject.GetComponent<SpriteRenderer>().sprite = LoadSprite("img1");

打包的问题

虽然解决了动态设置的问题,但是如果我们要让图集支持热更新,使用AssetBundle来打包又该怎么办呢?

解决方案

目标是我想把图集放在AssetBundle中加载,AssetBundle的处理比Resources的处理要简单得多了。

和打包到Resources不同,在AssetBundle中,我们添加图片就是以Sprite的类型存在的,所以打包以后,实际上是已经制作为图集了,但是还是可以按获取单个文件的方式获取指定的图片,也就是Sprite,获取后可以直接使用。

打包代码

打包代码同样来自我的开源项目中,有一些具体的规则,大家可以看注释:

1 // =================================================================================================
 2 //
 3 //    Hammerc Library
 4 //    Copyright 2015 hammerc.org All Rights Reserved.
 5 //
 6 //    See LICENSE for full license information.
 7 //
 8 // =================================================================================================
 9 
10 using UnityEditor;
11 using UnityEngine;
12 
13 /// <summary>
14 /// 
15 /// 简单的 AssetBundle 创建类.
16 /// 
17 /// 解决问题: 
18 /// 实现简单的资源打包.
19 /// 
20 /// 使用方法及步骤: 
21 /// 1.修改要打包到的目标平台枚举;
22 /// 2.选中要打包的文件在菜单栏点击对应的功能菜单.
23 /// 
24 /// </summary>
25 public class SimpleCreateAssetBundle
26 {
27     /// <summary>
28     /// 打包的目标平台.
29     /// </summary>
30     private const BuildTarget BUILD_TARGET = BuildTarget.StandaloneWindows64;
31 
32     /// <summary>
33     /// 将选定的一个对象进行打包, 同时包含依赖项, 可通过 AssetBundle 的 main 属性获取.
34     /// </summary>
35     [MenuItem("Hammerc/AssetBundle/CreateSingleAssetBundle")]
36     private static void CreateSingleAssetBundle()
37     {
38         if(Selection.activeObject != null)
39         {
40             //显示保存窗口
41             string path = EditorUtility.SaveFilePanel("Create Single AssetBundle:", "", "New AssetBundle", "assetbundle");
42 
43             if(path.Length > 0)
44             {
45                 //打包
46                 BuildPipeline.BuildAssetBundle(Selection.activeObject, null, path, BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets, BUILD_TARGET);
47             }
48         }
49     }
50 
51     /// <summary>
52     /// 将选定的多个对象进行打包, 同时包含依赖项, 不指定 AssetBundle 的 main 属性获取.
53     /// </summary>
54     [MenuItem("Hammerc/AssetBundle/CreateMultipleAssetBundle")]
55     private static void CreateMultipleAssetBundle()
56     {
57         if(Selection.objects.Length > 0)
58         {
59             //显示保存窗口
60             string path = EditorUtility.SaveFilePanel("Create Multiple AssetBundle:", "", "New AssetBundle", "assetbundle");
61 
62             if(path.Length > 0)
63             {
64                 //打包
65                 BuildPipeline.BuildAssetBundle(null, Selection.objects, path, BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets, BUILD_TARGET);
66             }
67         }
68     }
69 }

我们不需要关心文件类型,Unity3D会自动帮我们把图片格式的文件转换为Sprite类型。

加载代码

加载代码就比较简单了,加载AssetBundle后从这个AssetBundle中直接加载图片即可。

1 public Sprite LoadSprite(string spriteName)
2 {
3     if(assetbundle == null)
4         assetbundle = AssetBundle.CreateFromFile(Application.streamingAssetsPath +"/Img.assetbundle");
5     return assetbundle.Load(spriteName) as Sprite;
6 }

设置贴图就是向GameObject添加SpriteRenderer脚本后设置其sprite属性即可,如下:

this.gameObject.GetComponent<SpriteRenderer>().sprite = LoadSprite("img1");
unity图集的使用(万能方法) 图集的意义 使用图集可以说是多加了一个步骤 但是这个步骤不是没有意义的 他可以有效的减少drawcall的数量, 多张图片需要多个drawcall,而如果我们合成一个大图 只需要一个drawcall 并且可以减少内存的开销 图集的使用 然后就到了图集的使用上了 首先创建一个图集 然后我们将想要设置的文件夹或者是文件 赋值上去 这里可能会产生报错 如果报错 我们需要设置一下 这样报错就消失了 按钮也可以点击了 然后就要通过代码来给我们想要设置的赋值了 public static Sprite GetA 阅读详情

相关推荐

Unity实现自定义图集(一)

Unity实现自定义图集(一)

weixin_44165354的博客 2696

Unity图集简介及使用

Unity图集简介及使用 定义 图集是将很多零碎的2D小图整合成一张大图,方便unity渲染合批,降低渲染消耗。 优势 1.UI的合批处理,减少DrawCall 多张图片需要多次DrawCall,合并成一张大图只需要调用一次DrawCall 2.减少对内存的占用 OpenGL每张贴图都需要设置为2的N次方才能使用,假设有宽高分别为100x100、10x10的两张图片,如果不合成大贴图,那么就需要分别使用128x128和16x16的图片,会浪费一部分内存空间。 如果是使用一张大图的话,就可以将两张图片打到12

z2014z的博客 1万+

u3d菜鸟入门:游戏中的图集

写本文的目的 希望那些像我一样想从事游戏开发,但对这些基础知识了解甚少的人做一些简单讲解。在图文并茂、理论与实践结合的讲解之后,让那些不了解的初学者能够明白这些基础的原理(也就是为啥要这么用)以及实际应用 关于图集图集,在unity引擎中第一次看到,还是在用NGUI的时候,看到有一个叫做atlas的东东。当时不知道这是何物。网上搜了下,也没能得到太清晰的答案。 百度百科里的解释如下: 1

benimaur0的专栏 2207

Unity 之 图集属性详解和代码示例 -- 拓展一键自动打包图集工具

图集是将许多较小的,独立的纹理合并到一个较大的纹理文件中,从而最小化材质的数量,因此最小化所需使用的Draw Call数量。这是利用动态批处理的有效方法。每个独特的材质都需要额外的Draw Call,但是每种材质只支持单一的主纹理。当然,它们也可以支持多个二级纹理,比如法线纹理和发射纹理。然而,将多个主纹理合并到一个大的纹理文件中,渲染这个纹理的对象时,可以最小化所使用的Draw Call数量。...

陈言必行 -- Unity游戏开发领域优质博主 6585

Unity 将Sprite打包进图集

前言: 打包图集是一个很简单的过程,但是如果没有这样的经验,可能不知道如何下手 本博客大概说一下打包流程,以及一些基本原理 1、为什么要打包图集 首先要了解一点,在UGUI中即使你什么都不干,在项目打包时,Unity也会自动将你的一些小图片资源合在一张大图里面,也就是合成一张图集,但是这种默认的方式,会产生大量的Draw Call,对于性能消耗比较大 而NGUI则是开发者必须要将图片资源打包成图集,然后才能使用这些图片资源 因此无论是UGUI还是NGUI,掌握图集的打包都是非常重要的 2、打包开始前 在合成

xinzhilinger的博客 1万+

【Unity&Atlas】NGUI与UGUI打包图集的步骤以及比较

NGUI更适合做游戏界面UI、游戏背包UI、游戏技能UI等UI UGUI更适合做2D游戏的人物角色、2D游戏怪物图片等UI ------------------------NGUI如何创建精灵呢 NGUI--Create--Sprite(或者Unity 2DSprite) NGUI可以创建2种精灵,一种是Sprite,还有一种是Unity 2D Sprite

BuladeMian的博客,菜得抠脚,菜得真实 1万+

Unity3d Ugui 22图集Sprite Packer

一:版本变化 图集Sprite Packer在 Unity 2020.1以及以后的版本不再作为精灵打包模式的可用选项。以后创建的任何新项目在打包纹理时将默认使用 Sprite Atlas打包图集。 二:为什么使用图集? 1.减少draw call: 多张图片需要多次draw call,合成了一张大图则只需要一次draw call。 创建两个Image使用不同的图片,Batches是2 如果把两个图片打成一个图集,Batches是1 2.减少内存占用:OpenGL ES中每张贴..

HexianWHH的专栏 1万+

【零基础入门unity游戏开发——2D篇】使用SpriteAtlas(精灵图集)打包图集,减少DrawCall提高性能

【零基础入门unity游戏开发——2D篇】使用SpriteAtlas(精灵图集)打包图集,减少DrawCall提高性能

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 2526

UGUI图集的理解与使用

用过NGUI的同学都知道在拼界面之前都必须先制作好对应的图集才行,然而在Unity2D或UGUI中,Unity却自己集成了图集的操作,目的是让我们忘掉图集的存在,更加关注设计这个层面。

Peter的博客 2422

TensorRT-LLM环境配置避坑指南:从安装到实战

本文是一份详尽的TensorRT-LLM环境配置避坑指南。文章重点解析了从Python、CUDA、PyTorch版本选择,到解决mpi4py安装这一核心难题的完整流程,并提供了经过验证的稳定版本组合与实战排错方案,帮助开发者高效部署大语言模型推理优化环境。

a0b1c2d3的专栏 974

Java黑皮书课后题第5章:*5.9(找出得最高分的前两个学生)编写程序,提示用户输入学生的个数、每个学生名字及分数,最后显示获得最高分的学生

*5.9(找出得最高分的前两个学生)编写程序,提示用户输入学生的个数、每个学生名字及分数,最后显示获得最高分的学生名字、次高分的学生名字题目题目概述next()读取一个字符与nextLine()读取一行破题代码 题目 题目概述 *5.9(找出得最高分的前两个学生)编写程序,提示用户输入学生的个数、每个学生名字及分数,最后显示获得最高分的学生名字、次高分的学生名字 使用Scanner类的next()方法而不是nextLine()方法来读取名字 next()读取一个字符与nextLine()读取一行 举个例子理

weixin_46356698的博客 2150

unity性能优化之图集打包——Sprite packer 和 Sprite Atlas 使用总结

UGUI 图集打包1. 为什么要进行图集打包2. NGUI和UGUI 图集的不同3. UGUI图集打包的两种方式【3.1】 sprite packer 旧版本的图集打包方式:sprite packer第一步:设置 Mode: Always Enabled ( Legacy Sprite Packer)[Mode 各个选项的说明]第二步:设置 tag 和 Mesh Type第三步:点击Pack,完成...

weixin_36961960的博客 1万+

如何使用Calibre PERC抽出 点到点/p2p 电阻

@[TOC](如何使用Calibre PERC抽点到点(p2p)电阻) 一、前言 需要实现的功能是从gds中抽出net的点到点的电阻。如下图这样。 二、准备工作 lvs rule pex rule(必要时可以自己定义RC rule) gds p2p点的坐标 定义prode.defs 因为p2p的点是变化的,所以每次prode定义都要重新出,对应的perc rule也是根据每个p2p点的定义来的,perc rule也是每次都要重新出。如果需要可以写一个脚本自动出这些定义文件。 PROBE_POINTS

kobayashiyou的博客 1万+

Unity技术之UGUI-SpriteAtlas(图集)查看工具

本文将介绍一种方式,可以查看SpriteAtlas打包后得到的所有的图集,以方便在开发中对图集进行调整。

Erick的博客 1万+

Windows下的Geant4安装教程

本教程将从0开始展示在Windows下如何安装Geant4,包括各种辅助工具(QT、Cmake、Visual Studio)的下载安装,环境变量的配置,以及example的生成等。

weixin_49065278的博客 4085

RJ45以太网接口EMC设计方案

RJ45以太网接口EMC设计方案 一、 接口概述 RJ45以太网接口是目前应用最广泛的通讯设备接口,以太网口的电磁兼容性能关系到通讯设备的稳定运行。赛盛技术应用电磁兼容设计平台(EDP)软件从接口原理图、结构设计,线缆设计三个方面来设计以太网口的EMC设计方案。 二、 接口电路 原理图的EMC设计 百兆以太网接口2KV防雷滤波设计 图1 百兆以太网接口2KV防雷滤波设计 接口电路设计概述: 本方案从EMC原理上,进行了相关的抑制干扰和抗敏感度的设计;从设计层次解决EMC问题;同时此电路兼容了百兆以太网接

兰陵笑笑生SD的博客 1万+

Unity UGUI图集专题

一:图集介绍 什么是图集:我们可以将其理解为将一系列小图合并为一张大图。使用图集可以减少drawcall,提升效率。 ​ 游戏中的图片模型最终是要给到显卡去渲染的,然后CPU通知GPU要开始渲染,这一次通知就是一次Drawcall。当一个UI里面图片非常多的时候,我们可以使用图集技术将其一次性渲染。 Unity打包图集的方式有很多种,这里我们讲解三种: (1)一种是使用系统自带的打包工具SpritePacker; (2)使用SpriteAtlas进行打包图集 (3)使用TexturePacker

zhuyuqiang1238的专栏 6381

基于Dijkstra算法的共享单车调度优化系统设计与实现

根据最新统计数据,全球共享单车市场规模已超过300亿美元,中国作为最大的共享单车市场,日订单量超过5000万次。Dijkstra算法由荷兰计算机科学家Edsger W. Dijkstra于1956年提出,用于解决带权有向图中的单源最短路径问题。本文详细介绍了基于Dijkstra算法的共享单车调度优化系统的设计与实现。本文将详细介绍基于Dijkstra算法的共享单车调度优化系统的设计与实现,采用Java 17、Spring Boot 3.x等最新技术栈。

2201_76125393的博客 614

Unity UGUI 之 图集

嘻嘻

咩咩的博客 1561

OData 请求里的 Nextlink 实战:在 ABAP Client Proxy 中优雅处理长列表分页

本文介绍了OData v4标准中的@odata.nextLink分页机制及其在SAP ABAP中的实践应用。重点解析了该机制通过服务端提供的完整URL实现分页获取,客户端只需循环处理直到该字段消失的特点。文章提供了清晰的ABAP代码模板,展示如何通过Remote Client Proxy实现分页数据获取,并强调了仅支持OData v4和远程消费的限制条件。通过HR员工数据聚合的实际案例,说明了流式分页处理的最佳实践,包括服务端过滤、稳定排序和内存控制等关键技术要点,为ABAP开发者提供了可直接落地的解决方案

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 256

060、模型蒸馏:把扩散模型压进单步的魔法

《端侧文生图模型蒸馏实战:从32步到1步的优化之道》摘要:针对边缘设备部署难题,本文分享了扩散模型蒸馏的核心经验。通过重构损失函数(感知损失+对抗训练+KL散度)、优化采样轨迹截取策略和改造学生模型架构,成功将Stable Diffusion压缩至单步推理。关键发现包括:小批量训练更有效、标签平滑保障生成多样性、双模型策略平衡质量与速度。在Cortex-A53芯片上实现300ms内生成,内存占用控制在200MB以下。特别强调工业部署需权衡压缩率与稳定性,建议保留迭代模式开关以适配不同场景需求。

2601_95651806的博客 140

Unity UGUI性能优化实战:从12个DrawCall降到2个的完整图集打包指南

本文提供了一份完整的Unity UGUI性能优化实战指南,核心在于通过Sprite Atlas(精灵图集)打包技术,系统性地降低DrawCall。文章详细解释了DrawCall的性能瓶颈原理,并逐步演示如何将UI界面的DrawCall从12个优化至2个,涵盖了图集创建、配置、应用验证及常见问题排查的全流程,旨在帮助开发者解决移动端UI卡顿问题。

cuda7parallel的博客 1083

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Unity2d引入新功能SpriteAtlas,Sprite新的图集方式

在Unity 2017.1.0f3中引入了 SpriteAtlas官方文档: https://docs.unity3d.com/2017.1/Documentation/Manual/SpriteAtlas.htmlhttps://docs.unity3d.com/2017.1/Documentation/Sc

游戏路上的小学生 1万+

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

上一篇: Unity从图集中读取资源
下一篇: android开发常用路径
瘦瘦的胖子
博客等级 码龄9年 71粉丝 21原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值