Unity自动化之自动构建图集与压缩

文章目录

  • 前言
  • 一、UI图集的压缩
    • unity2020之前的版本使用图集
    • unity2020之后的版本使用图集
  • 二、非UI图集压缩
  • 总结


前言

为降低DrawCall,我们需要将多个图片构建在图集上。同时还有个好处,可以自动补齐图片补齐2的幂次方或正方形图,这样便可以进行ETC和PVRTC压缩了。

官方解释请注意 Sprite Packer 在 Unity 2020.1 和更新版本中已弃用,并且将不再作为精灵打包模式的可用选项。现有已使用 Sprite Packer 的项目仍然可以继续使用它,但是在 2020.1 以后创建的任何新项目在打包纹理时将默认使用 Sprite Atlas 系统。


一、UI图集的压缩

如果是UI图片,设置了相同packingTag的Sprite会合并在一个图集,但是游戏中有很多本身就很大的图片,比如背景图或者大头像图。由于这些图片不一定是2的幂次方或正方形图,所以我们可以自动给它们设置成一个唯一的packingTag,这样它们也可以进行压缩了。

如果有些大图需要设置成了RGBA32或者RGBA16,并且自身并不是2的幂次方或者正方形图的话,在去加pakcingTag就不太合适了,这样只会让图片变得更大。所以,在自动构建图集的时候可以做个判断,当图片出现这类情况时不再构建图集。

首先打开图集模式在这里插入图片描述
内部选项,根据需要选择
在这里插入图片描述
在包管理器安装2D Sprite插件包
在这里插入图片描述

unity2020之前的版本使用图集

在这里插入图片描述
设置PackingTag
在这里插入图片描述

using System;
using System.Linq;
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;public class CustomPackerPolicySample : UnityEditor.Sprites.IPackerPolicy
{bool UnityEditor.Sprites.IPackerPolicy.AllowSequentialPacking {get {return true;}}protected class Entry{public Sprite            sprite;public UnityEditor.Sprites.AtlasSettings settings;public string            atlasName;public SpritePackingMode packingMode;public int                anisoLevel;}private const uint kDefaultPaddingPower = 3;public virtual int GetVersion() { return 1; }protected  string TagPrefix { get { return "[RECT]"; } }protected  bool AllowTightWhenTagged { get { return true; } }protected  bool AllowRotationFlipping { get { return true; } }//判断图片是否为压缩格式public static bool IsCompressedFormat(TextureFormat fmt){if(fmt >= TextureFormat.DXT1 && fmt <= TextureFormat.DXT5)return true;if(fmt >= TextureFormat.DXT1Crunched && fmt <= TextureFormat.DXT5Crunched)return true;if(fmt >= TextureFormat.PVRTC_RGB2 && fmt <= TextureFormat.PVRTC_RGBA4)return true;if(fmt == TextureFormat.ETC_RGB4)return true;if(fmt >= TextureFormat.ETC_RGB4 && fmt <= TextureFormat.ETC2_RGBA8)return true;if(fmt >= TextureFormat.EAC_R && fmt <= TextureFormat.EAC_RG_SIGNED)return true;if(fmt >= TextureFormat.ETC2_RGB && fmt <= TextureFormat.ETC2_RGBA8)return true;if(fmt >= TextureFormat.ASTC_RGB_4x4 && fmt <= TextureFormat.ASTC_RGBA_12x12)return true;if(fmt >= TextureFormat.DXT1Crunched && fmt <= TextureFormat.DXT5Crunched)return true;return false;}
public void OnGroupAtlases(BuildTarget target, UnityEditor.Sprites.PackerJobjob, int[] textureImporterInstanceIDs){List<Entry> entries = new List<Entry>();foreach(int instanceID in textureImporterInstanceIDs){TextureImporter ti = EditorUtility.InstanceIDToObject(instanceID)as TextureImporter;TextureFormat desiredFormat;ColorSpace colorSpace;int compressionQuality;ti.ReadTextureImportInstructions(target, out desiredFormat, out colorSpace,out compressionQuality);TextureImporterSettings tis = new TextureImporterSettings();ti.ReadTextureSettings(tis);Sprite[] sprites =AssetDatabase.LoadAllAssetRepresentationsAtPath(ti.assetPath).Select(x => x as Sprite).Where(x => x != null).ToArray();foreach(Sprite sprite in sprites){//设置图片的压缩参数Entry entry = new Entry();entry.sprite = sprite;entry.settings.format = desiredFormat;entry.settings.colorSpace = colorSpace;entry.settings.compressionQuality = IsCompressedFormat(desiredFormat)? compressionQuality : 0;entry.settings.filterMode = Enum.IsDefined(typeof(FilterMode),ti.filterMode)? ti.filterMode: FilterMode.Bilinear;entry.settings.maxWidth = 2048;entry.settings.maxHeight = 2048;entry.settings.generateMipMaps = false;entry.settings.enableRotation = AllowRotationFlipping;entry.settings.paddingPower = (uint)EditorSettings.spritePackerPaddingPower;entry.settings.allowsAlphaSplitting = ti.GetAllowsAlphaSplitting();entry.atlasName = ParseAtlasName(ti.spritePackingTag);entry.packingMode = GetPackingMode(ti.spritePackingTag,tis.spriteMeshType);entry.anisoLevel = ti.anisoLevel;entries.Add(entry);}Resources.UnloadAsset(ti);}//将相同图集的名称划分成不同图集var atlasGroups =from e in entriesgroup e by e.atlasName;foreach(var atlasGroup in atlasGroups){int page = 0;//相同的图集中压缩格式不同的图划分成不同的组var settingsGroups =from t in atlasGroupgroup t by t.settings;foreach(var settingsGroup in settingsGroups){//已经设置了非压缩的图,这里不做成图集,避免图片变大bool skipAtlas = (settingsGroup.Count() == 1 && !IsCompressedFormat(settingsGroup.ElementAt(0).settings.format));if(skipAtlas) {continue;}string atlasName = atlasGroup.Key;if(settingsGroups.Count() > 1)atlasName += string.Format("(Group {0})", page);UnityEditor.Sprites.AtlasSettings settings = settingsGroup.Key;settings.anisoLevel = 1;if(settings.generateMipMaps)foreach(Entry entry in settingsGroup)if(entry.anisoLevel > settings.anisoLevel)settings.anisoLevel = entry.anisoLevel;job.AddAtlas(atlasName, settings);foreach(Entry entry in settingsGroup){job.AssignToAtlas(atlasName, entry.sprite, entry.packingMode,SpritePackingRotation.None);}++page;}}}protected bool IsTagPrefixed(string packingTag){packingTag = packingTag.Trim();if(packingTag.Length < TagPrefix.Length)return false;return (packingTag.Substring(0, TagPrefix.Length) == TagPrefix);}private string ParseAtlasName(string packingTag){string name = packingTag.Trim();if(IsTagPrefixed(name))name = name.Substring(TagPrefix.Length).Trim();return(name.Length == 0) ? "(unnamed)" : name;}private SpritePackingMode GetPackingMode(string packingTag, SpriteMeshTypemeshType){if(meshType == SpriteMeshType.Tight)if(IsTagPrefixed(packingTag) == AllowTightWhenTagged)return SpritePackingMode.Tight;return SpritePackingMode.Rectangle;}
} 
    //如果打包前需要自动指定策略,可以强制设置本地打包使用什么图集策略,然后将策略以及打包平台传入即可static private void BuildAtlas(BuildTarget buildTarget){Packer.SelectedPolicy = typeof(CustomPackerPolicySample).Name;Packer.RebuildAtlasCacheIfNeeded(buildTarget);}

unity2020之后的版本使用图集

创建图集
在这里插入图片描述
图集制作
在这里插入图片描述
使用方法

 SpriteAtlas spriteAtlas = AssetDatabase.LoadAssetAtPath<SpriteAtlas>("Assets/Art/xxxx");Sprite sprite = spriteAtlas.GetSprite("xxx")

具体的封装,请根据项目自行调整。

二、非UI图集压缩

如果美术人员没有提供符合2的幂次方或正方形要求的图片,那么这些角色、特效和场景图可能无法进行有效压缩。但是,在图形编辑软件中,可以通过在"Advanced"下拉面板中选择适当的"Non Power of 2"选项来强制将这些图片调整为2的幂次方大小。

在这个选项中,"ToNearest"会将图片大小调整到最接近的2的幂次方,"ToLarger"会将图片大小调整到大于等于原始大小的最小2的幂次方,而"ToSmaller"则会将图片大小调整到小于等于原始大小的最大2的幂次方。通过这些选项,可以自动将图片拉伸到符合规则的大小,从而使图片能够进行有效压缩,提高游戏性能和效率。

在这里插入图片描述


总结

该篇分享了关于Unity中图集压缩的技巧,包括UI图集和非UI图集的处理方法。通过设置packingTag和在图形编辑软件中调整图像大小的方法,大家可以学会如何有效地压缩游戏中的图像资源,提高游戏性能和效率。希望大家可以通过学习这些技能来优化自己的开发工作。不断学习和探索,打造出更出色的作品!

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

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

相关文章

【CV】特征匹配FAST和MSER

特征匹配是计算机视觉领域的重要概念&#xff0c;涉及在图像中寻找关键点和描述符。FAST和MSER是两种常用的关键点检测算法。 FAST (Features from Accelerated Segment Test) FAST算法是一种快速角点检测器。它基于像素强度比较&#xff0c;在一个圆圈内进行强度对比&#x…

解决uniapp修改内置组件样式,在微信中不生效问题

下面是作者在开发工作中遇到的问题&#xff0c;踩坑几小时最后解决的办法。 接下来以UNIAPP文档中的内置组件 slider 为例 接下来直接上样式代码&#xff1a; <style lang"scss" scoped>::v-deep .wx-slider-wrapper {height: 100% !important;}::v-deep .w…

前端实现将当前页面内容下载成图片(图片可做到高清画质)

插件背景&#xff1a; html2canvas可以把你想要转变的元素变为图片&#xff0c;使用file-saver下载图片。 1、安装html2canvas、file-saver npm install html2canvasnpm install file-saver --save 2、在Vue组件中引入并使用html2canvas、file-saver import html2canvas fro…

Django 学习 笔记

Django 一、模型models 继承django.db.models.Model 1.模型字段 / 模型字段选项参考&#xff1a; 官网&#xff1a;https://docs.djangoproject.com/zh-hans/3.2/ref/models/fields/#common-model-field-options 2.模型Meta选项(定义模型类的属性)&#xff1a; csdn: https:/…

C#基础|对象初始化器与构造方法对比总结

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 01 对象初始化器的作用 为了更加灵活的初始化对象的“属性”&#xff0c;是对构造化方法的补充。 02 构造方法总结 2.1、存在的必要性&#xff1a;一个类中&#xff0c;至少要有一个构造方法&#xff08;有无参数均…

五一节前的信息系统的安全保障工作

文章目录 保障流程制定安全保障计划确定检查人员确定检查内容实施检查风险评估修复漏洞定期复查 保障内容系统安全检查网络安全检查数据安全检查应用安全检查用户安全检查安全政策和流程检查 关闭信息系统说明制定关闭计划备份数据通知相关人员停止系统服务关闭系统设备监控关闭…

合合信息引领AI场景化革新,供应链金融智能化审核全面升级!

官.网地址&#xff1a;合合TextIn - 合合信息旗下OCR云服务产品 随着供给侧结构性改革的深入推进和产业结构的不断升级&#xff0c;金融机构在监管部门的指导下&#xff0c;积极拓展供应链金融业务&#xff0c;取得了显著成效。这一举措有效缓解了上下游中小企业的融资困难&a…

国产麒麟v10系统下打包electron+vue程序,报错unknown output format set

报错如下&#xff1a; 报错第一时间想到可能是代码配置原因报错&#xff0c;查看代码似乎感觉没啥问题 又查看具体报错原因可能是因为icon的原因报错&#xff0c;后面查阅发现ico在各系统平台会不兼容&#xff0c;也就是ico是给win下使用的&#xff0c;此处改下图标格式就ok&am…

Unreal Engine动态添加Button实例

在控件蓝图中添加容器&#xff0c;注意命名不要有中文 C代码中找到容器实例 1 2 3 4 5 6 7 8 UVerticalBox* verticalBox Cast<UVerticalBox>(CurrentWidget->GetWidgetFromName(TEXT("VerticalBox_0"))); if (verticalBox ! nullptr) { UScrollBox* …

AJAX——黑马头条-数据管理平台项目

1.项目介绍 功能&#xff1a; 登录和权限判断查看文章内容列表&#xff08;筛选&#xff0c;分页&#xff09;编辑文章&#xff08;数据回显&#xff09;删除文章发布文章&#xff08;图片上传&#xff0c;富文本编辑器&#xff09; 2.项目准备 技术&#xff1a; 基于Bootst…

stm32mp135d bringup

stm32mp135d bringup 一、安装交叉编译链二、获取bsp代码并编译1. tf-a(trust-firmware)二、optee三、u-boot四、linux 三、快速开始四、st社区关于bringup问题链接 关于 stm32mp135d的移植 一共分为4个部分 tf-a(trusted-firmware) optee u-boot linux文件系统编译后面再说&a…

ShardingSphere 5.x 系列【26】 数据分片原理之 SQL 路由

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 3.1.0 本系列ShardingSphere 版本 5.4.0 源码地址:https://gitee.com/pearl-organization/study-sharding-sphere-demo 文章目录 1. 概述2. 携带分片键2.1 直接路由2.2 标准路由2.3 笛卡尔路由3. 不携带分片…

如何在docker上面使用hbase shell

在新公司上班&#xff0c;hbase是cdh6.3.2安装在docker上面&#xff0c;如何直接在shell上面使用hbase shell是访问不到的。使用教程如下&#xff1a; 要在Docker上使用CDH 6.3.2中的HBase shell&#xff0c;你需要按照以下步骤操作&#xff1a; 步骤1&#xff1a;启动HBase服…

【内网横向】SSH协议隧道搭建详解

什么是SSH隧道 SSH隧道是通过Secure Shell&#xff08;SSH&#xff09;协议在两个网络节点之间创建的加密通道。它可以用于安全地传输数据&#xff0c;绕过网络限制或保护数据免受窃听。通过SSH隧道&#xff0c;可以在两个网络之间建立安全的连接&#xff0c;例如在本地计算机和…

字符串简单运算(BigDecimal相关运算)

目录 1.除法 2.乘法 3.减法 4.加法 1.除法 使用 divide(BigDecimal, int, RoundingMode) 方法进行除法运算。第一个参数是要除的 BigDecimal&#xff0c;第二个参数指定结果的小数位数&#xff0c;第三个参数是舍入模式。这里选择了 RoundingMode.HALF_UP&#xff0c;即四舍…

济宁市中考报名照片要求及手机拍照采集证件照方法

随着中考报名季的到来&#xff0c;并且进入了中考报名演练阶段&#xff0c;济宁市的广大考生和家长都开始忙碌起来。报名过程中&#xff0c;上传一张符合要求的证件照是必不可少的环节。本文将详细介绍济宁市中考报名照片的具体要求&#xff0c;并提供一些实用的手机拍照采集证…

BUUCTF--web(2)

1、[HCTF 2018]admin1 打开题目后发现有注册和登录两个页面&#xff0c;因为题目提示admin&#xff0c;尝试用admin进行爆破 爆破得到密码为123 登录得到flag 2、[护网杯 2018]easy_tornado1 打开题目后有三个文件&#xff0c;分别打开查看 在url地址栏中发现包含两个参数&a…

想要提升爬虫效率,该如何调整动态IP切换时间?

在进行网络爬虫操作时&#xff0c;动态代理IP的使用是常见的策略之一&#xff0c;用于隐藏爬虫的真实身份和规避目标网站的封锁。然而&#xff0c;一个常见的问题是&#xff1a;在做爬虫时&#xff0c;动态代理IP切换频率到底是越快越好呢&#xff1f;本文将从不同角度探讨这个…

Java设计模式 _创建型模式_单例模式(懒汉式,饿汉式)

一、单例模式 1、单例模式&#xff08;Singleton Pattern&#xff09;是一种创建对象的设计模式。一个类负责创建自己的对象&#xff0c;同时确保只有1个对象被创建&#xff0c;这个类提供了一种访问其唯一的对象的方式&#xff0c;不需要在实例化该类的对象。从而保证了这个类…

鸿蒙OpenHarmony【轻量系统 编写“Hello World”程序】 (基于Hi3861开发板)

编写“Hello World”程序 下方将通过修改源码的方式展示如何编写简单程序&#xff0c;输出“Hello world”。请在下载的源码目录中进行下述操作。 确定目录结构。 开发者编写业务时&#xff0c;务必先在./applications/sample/wifi-iot/app路径下新建一个目录&#xff08;或一…