Unity实现自定义图集(一)

以下内容是根据Unity 2020.1.0f1版本进行编写的

Unity自带有图集工具,包括旧版的图集(设置PackingTag),以及新版的图集(生成SpriteAtlas)。一般来说,unity自带的图集系统已经够用了,但是实际使用上还是存在一些可优化的地方,例如加载到Canvas上的资源,打图集不能同时设置TightPacking和AllowRotation,即打图集不能旋转。

此外,也可以更加深入地了解图集的运行逻辑,以及ui材质球的合批。

1、先看看两种打图集方法的效果

关于unity是怎么打图集的,这里有一个链接可以参考:
SpriteAtlas图集预览算法:MaxRectsBinPack
本文是基于这个基础上进行改动的。
按照上述博文的内容,先简单尝试一下,实现其中的内容,效果:
图片资源(资源为网络资源):

Unity的SpriteAtlas打出来的图集:
在这里插入图片描述
根据博文得到的图集:
在这里插入图片描述
(代码中有5种不同的匹配方式,实际结果都大同小异)
可以看到,unity打出来的图集会比上述博文中打出来的图集更小。细看一下发现,是Unity会自动把一些资源周围的空白像素裁掉。

2、旋转资源

先简单做一个ui预制和一个场景预制,都是用相同的资源做的(上面是ui,下面是SpriteRenderer)
在这里插入图片描述
然后把图集改成可旋转
在这里插入图片描述
可以看到部分资源旋转了
接下来运行unity
在这里插入图片描述
可以看到,上半部分ui的界面部分资源方向不对,甚至还把其它资源重叠显示了。

3、接入一个简单的资源加载系统

此处不是重点,简单过一遍,跳过。

using UnityEngine;
/// <summary>
/// 单例类父类
/// </summary>
/// <typeparam name="T"></typeparam>
public class Singleton<T> where T:new()
{private static readonly object _lock = new object();private static T _instance;protected Singleton(){Debug.Assert(_instance == null);}public static bool Exists{get{return _instance != null;}}public static T Instance{get{if (_instance == null){lock (_lock){if (_instance == null){_instance = new T();}}}return _instance;}}
}

实现单例类Singleton

using UnityEngine;public class GameController : MonoBehaviour
{void Start(){
#if UNITY_EDITORAssetsCache.Instance.Init(ResourceLoadMode.Direct);
#elseAssetsCache.Instance.Init(ResourceLoadMode.AssetBundle);
#endif}
}

新建一个游戏管理类GameController,用于初始化资源加载器。
然后在场景上新建一个空节点,命名为Scripts,将GameController挂载到该节点上。
此时可以把canvas下的预制删掉了,如下图:
在这里插入图片描述

using UnityEngine;public class TestView : MonoBehaviour
{const string viewPath = "Assets/Prefabs/testview_myimage.prefab";GameObject viewPrefab;GameObject canvas;void Start(){canvas = GameObject.Find("Canvas");AssetsCache.Instance.GetResource(viewPath, OnGetView);}void OnGetView(AssetsResource asset){viewPrefab = Instantiate(asset.GetAsset(viewPath), canvas.transform) as GameObject;}
}

新建一个类TestView,用于加载ui预制到Canvas节点下,并将其挂载到刚刚创建的Scripts节点上:
在这里插入图片描述
在这里插入图片描述
保存场景,运行unity,可以看到预制正常加载出来了。

4、实现一个简单的打包逻辑

此处也不是重点,简单过一遍。

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;public class AppConst
{// 素材目录 public const string AssetDir = "StreamingAssets";//打包时需要每个子文件夹打一个bundle的目录private static List<string> subDirectoryBundlePaths;//打包时需要每个文件打一个bundle的目录private static List<string> eachFileBundlePaths;//打包时需要将整个文件夹打一个bundle的目录private static Dictionary<string, string> wholeDirectoryBundlePaths;private static bool hasInit = false;public static void Init(){subDirectoryBundlePaths = new List<string>();eachFileBundlePaths = new List<string>();wholeDirectoryBundlePaths = new Dictionary<string, string>();wholeDirectoryBundlePaths.Add("prefab.bundle", "Prefabs/");hasInit = true;}public static List<string> GetSubDirectoryBundlePaths(){if(!hasInit){Init();}return subDirectoryBundlePaths;}public static List<string> GetEachFileBundlePaths(){if (!hasInit){Init();}return eachFileBundlePaths;}public static Dictionary<string, string> GetWholeDirectoryBundlePaths(){if (!hasInit){Init();}return wholeDirectoryBundlePaths;}public static Hashtable GetResourcesHashTable(){Hashtable tb = new Hashtable();foreach(var path in GetSubDirectoryBundlePaths()){DirectoryInfo[] directories = new DirectoryInfo(Application.dataPath + path).GetDirectories();foreach (var directory in directories){string assetsPath = UnifyPath(directory.FullName).Substring(7);tb[directory.Parent.Name + "." + directory.Name + ".bundle"] = assetsPath;}}foreach (var path in GetEachFileBundlePaths()){List<FileSystemInfo> files = new List<FileSystemInfo>();SeachFile(Application.dataPath + path, files, new string[] { ".png", ".jpg", ".jpeg", ".tga" });foreach (var file in files){string assetsPath 

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

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

相关文章

PyQt 入门教程(3)基础知识 | 3.2、加载资源文件

文章目录 一、加载资源文件1、PyQt5加载资源文件2、PyQt6加载资源文件 一、加载资源文件 常见的资源文件有图像与图标&#xff0c;下面分别介绍下加载资源文件的常用方法 1、PyQt5加载资源文件 2、PyQt6加载资源文件 PyQt6版本暂时没有提供pyrcc工具&#xff0c;下面介绍下在不…

雷池社区版本SYSlog使用教程

雷池会对恶意攻击进行拦截&#xff0c;但是日志都在雷池机器上显示 如何把日志都同步到相关设备进行统一的管理和分析呢&#xff1f; 如需将雷池攻击日志实时同步到第三方服务器, 可使用雷池的 Syslog 外发 功能 启用 Syslog 外发 进入雷池 系统设置 页面, 配置 Syslog 设置…

北京京恋在喧嚣的都市中助你邂逅自己的爱情

北京的夜晚&#xff0c;灯火璀璨&#xff0c;车水马龙。刘凡站在他位于国贸的公寓阳台上&#xff0c;望着眼前熙熙攘攘的街道&#xff0c;心中却有一丝落寞。32岁的他&#xff0c;是一家知名互联网公司的中层管理&#xff0c;事业有成&#xff0c;收入稳定&#xff0c;甚至朋友…

anaconda(jupyter)安装教程

目录 一、下载anaconda安装包 二、安装程序 三、怎么使用 四、把jupyter界面语言修改成中文 一、下载anaconda安装包 anaconda官网&#xff1a;下载 Anaconda Distribution |蟒蛇 清华大学开源软件镜像站官网&#xff1a;清华大学开源软件镜像站 | Tsinghua Open Source M…

嵌入式linux中条件变量的具体实现

大家好,今天主要给大家分享一下,如何使用条件变量以及具体实现方法。 第一:条件变量分析 条件变量是另一种逻辑稍微复杂一点点的同步互斥机制,他必须跟互斥锁一起配合使 他的应用场景也是非常常见的,先来看一个例子: 用,小楠是一名在校学生,每个月都会从父母那里得到一笔…

考研C语言程序设计_语法相关(持续更新)

目录 一、语法题strlen转义字符内置数据类型字符串结束标志局部变量和全局变量名字冲突 局部优先switch语句中的关键字数组初始化是否正确注意define不是关键字C语言中不能用连等判断switch( )的括号里可以是什么类型?关于if关于switch关于while 二、程序阅读题有关static有关…

【openGL学习笔记】----GLFW、GLAD环境配置

glew、glad、freeglut、glfw的区别&#xff1f; glew&#xff08;The OpenGL Extension Wrangler Library&#xff09;是对底层OpenGL接口的封装&#xff0c;可以让你的代码跨平台。glad与glew作用相同&#xff0c;可以看作它的升级版。Freeglut&#xff08;OpenGL Utility To…

计算机组成原理(笔记7高速缓冲存储器Cache,计算机组成原理的重难点全、直接、组相连)

为什么要设立高速缓冲存储器 &#xff08;Cache&#xff09;&#xff1f; Cache是介于CPU和主存之间的小容量存储器&#xff0c;存取速度比主存快。它能高速地向CPU提供指令和数据&#xff0c;加快程序的执行速度。它是为了解决CPU和主存之间速度不匹配而采用的一项重要技术。…

使用Mockaroo生成测试数据

使用Mockaroo生成测试数据 最近在学习【Spring Boot & React】Spring Boot和React教程视频的P51.Generating 1000 students一课中&#xff0c;看到了https://www.mockaroo.com/网站可以用来模拟生成测试数据&#xff0c;觉得还不错&#xff0c;特此记录一下。感觉每次看老…

centOS部署Jenkins实现项目可持续自动化部署

个人看的是尚硅谷的视频&#xff0c;跟着实战&#xff0c;但因为视频是21年的&#xff0c;所以很容易出现jenkins插件不适配问题。 因而个人直接用较新版的jdk和jenkins. 先切换到root用户 sudo su一、安装jdk 先查询可安装版本 yum list java*安装jdk&#xff08;只复制圈…

【Python爬虫实战】正则:中文匹配与贪婪非贪婪模式详解

&#x1f308;个人主页&#xff1a;https://blog.csdn.net/2401_86688088?typeblog &#x1f525; 系列专栏&#xff1a;https://blog.csdn.net/2401_86688088/category_12797772.html 目录 前言 一、匹配中文 &#xff08;一&#xff09;匹配单个中文字符 &#xff08;二…

DeepFM模型代码详解

直到看到这篇文章&#xff0c;我才搞明白类别特征怎么做lookup的&#xff0c;也看明白了代码逻辑。如果你看完没懂&#xff0c;私信留下wx&#xff0c;给你讲懂。 1、Deepfm 的原理&#xff0c;DeepFM 是一个模型还是代表了一类模型&#xff0c;DeepFM 对 FM 做了什么样的改进…

单细胞copyKat分析学习和整理

CopyKAT(肿瘤拷贝数核型分析)是一种使用综合贝叶斯方法的计算工具&#xff0c;能够在单细胞中以5MB分辨率检测全基因组非整倍体&#xff0c;以便从高通量单细胞RNA测序数据中区分肿瘤细胞与正常细胞&#xff0c;并识别肿瘤亚克隆。 (这里提一下,“5MB”是指 5兆碱基对(5 megab…

CTF-PWN方向 栈溢出等基础知识笔记(2)

C语言基本函数补充 write函数 ret2syscall 要求有0x80这种系统调用存在 &#xff08;0x0A是回车的意思&#xff09; 案例 通过file查看这个文件 发现是静态编译的文件 所以很多库函数都被编译进去了 但是不存在bin/sh字符串 不存在system和backdoor函数 修改&#xff0c;rea…

【环境搭建】远程服务器搭建ElasticSearch

参考&#xff1a; 非常详细的阿里云服务器安装ElasticSearch过程..._阿里云服务器使用elasticsearch-CSDN博客 服务器平台&#xff1a;AutoDL 注意&#xff1a; 1、切换为非root用户&#xff0c;su 新用户名&#xff0c;否则ES无法启动 2、安装过程中没有出现设置账号密码…

AD9361 在低至 1MHz 的频率下运行

AD9361 在低至 1MHz 的频率下运行 AD -FREQCVT1-EBZ是包含AD9361的FMCOMMS3/4/5板的附加板。虽然完整的芯片级设计包可在此 RF 收发器的ADI产品页面上找到&#xff0c;但有关此卡的信息及其使用方法、围绕它的设计包以及可使其工作的软件可在此处找到。 AD-FREQCVT1-EBZ 模块…

山西农业大学20241015

02-VUE 一. Vue中常用的指令1. Vue指令概述2 Vue中指令的分类3 Vue中指令3.1 内容渲染指令3.2 条件渲染指令3.2.1 v-show3.2.2 v-if3.2.3 v-else 和 v-else-if 3.3 事件绑定指令 v-on--重要3.3.1 内联语句3.3.2 methods中的函数名 一. Vue中常用的指令 1. Vue指令概述 概念: 指…

安装Node.js环境,安装vue工具

一、安装Node.js 去官方网站自行安装自己所需求的安装包 这是下载的官方网站 下载 | Node.js 中文网 给I accept the terms in the License Agreement打上勾然后点击Next 把安装包放到自己所知道的位置,后面一直点Next即可 等待它安装好 然后winr打开命令提示符cmd 二、安装…

MySQL中表的约束

1&#xff0c;概念 表中一定要有各种约束&#xff0c;通过约束&#xff0c;让我们来插入数据库中的数据是符合预期的。 约束本质是通过技术手段&#xff0c;倒逼程序员插入正确的数据&#xff1b;反过来&#xff0c;站在MySQL的角度来单&#xff0c;内部已经插进来的数据&…

Web安全 - 跨站点请求伪造CSRF(Cross Site Request Forgery)

文章目录 OWASP 2023 TOP 10CSRF 导图CSRF的基本概念CSRF的工作原理常见CSRF攻击模式CSRF防御策略补充建议应用场景实战防御策略选择1. CSRF Token&#xff08;首选&#xff09;2. SameSite Cookie属性3. 验证Referer和Origin4. 多因素认证 实现方案CSRF Token实现SameSite Coo…