unity美术资源优化(资源冗余,主界面图集过多)
图片资源冗余:
UPR unity的性能优化工具检查资源
1.检查纹理读/写标记
开启纹理资源的读/写标志会导致双倍的内存占用
检查Inspector -> Advanced -> Read/Write Enabled选项
2.检查纹理资源alpha通道
如果纹理的alpha通道全部为0,或者全部为255,可以认为其中不包含有效信息,此时应禁用’Alpha源’标志,否则会浪费这部分的内存。
检查Inspector -> Alpha Source选项
3.检查纯色纹理
纯色纹理的使用可能可以由一些设置来代替。由于某些情况下纯色纹理是必不可少的,此警告仅会在所使用的纹理较大(大于设定值, 默认为16x16)时才会触发。
Custom Parameters: heightThreshold : 16widthThreshold : 16
4.检查重复纹理
问题1 方案:可继承AssetPostprocessor对资源改动的时候检查是否有开启读/写标记
问题2,3 ,4 方案:定期检查
其中问题2,3只需要判断颜色通道比较简单不做解释
问题4 解决:
1.遍历所有贴图 用字典缓存 找到重复的资源
2.找到项目下所有材质,并且缓存
3.找到引用该重复贴图的材质
4.判断该材质所有引用贴图字段 如有和重复贴图相同 则替换
5.删除重复贴图
代码:
static void RemoveReportTexture(string[] searchInFolders){Dictionary<string, string> md5dic = new Dictionary<string, string>();HashSet<int> deleteTexInsId = new HashSet<int>();//string[] guids = AssetDatabase.FindAssets("t:Texture", new string[] { "Assets/actor", "Assets/FX", "Assets/scene", });string[] guids = AssetDatabase.FindAssets("t:Texture", searchInFolders);string[] matFiles = null;string[] matFilesContent = null;//Debug.Log("贴图" + guids.Length);//1.遍历所有贴图 用字典缓存 找到重复的资源 int progress = 0;foreach (var assetGuid in guids){string assetPath = AssetDatabase.GUIDToAssetPath(assetGuid); // 从GUID拿到资源的路径bool isCancel = EditorUtility.DisplayCancelableProgressBar("移除重复的贴图", assetPath, (float)progress / (float)guids.Length);progress++;string md5 = GetMD5Hash(Path.Combine(Directory.GetCurrentDirectory(), assetPath)); //获取md5string path;md5dic.TryGetValue(md5, out path);if (path == null){md5dic[md5] = assetPath;// Debug.Log(assetPath);}else{Debug.LogFormat("资源重复{0},{1}", path, assetPath);if (matFiles == null){//2.找到所有材质,并且缓存List<string> withoutExtensions = new List<string>() { ".mat" };matFiles = Directory.GetFiles(Application.dataPath, "*.*", SearchOption.AllDirectories).Where(s => withoutExtensions.Contains(Path.GetExtension(s).ToLower())).ToArray();matFilesContent = new string[matFiles.Length];for (int i = 0; i < matFiles.Length; i++){matFilesContent[i] = File.ReadAllText(matFiles[i]);}}Texture2D tex = AssetDatabase.LoadAssetAtPath<Texture2D>(path); //保留的图Texture2D deleteTex = AssetDatabase.LoadAssetAtPath<Texture2D>(assetPath); //删除的图//3.找到引用该贴图的所有材质for (int startIndex = 0; startIndex < matFiles.Length; startIndex++){string file = GetRelativeAssetsPath(matFiles[startIndex]);if (Regex.IsMatch(matFilesContent[startIndex], assetGuid)){Material material = AssetDatabase.LoadAssetAtPath<Material>(file);bool isUseTex = false;var textureNames = material.GetTexturePropertyNames();//Debug.Log("遍历所有需要修改替换贴图的材质:" + file + ",贴图数:" + textureNames.Length);//4.判断该材质所有引用贴图字段 如有和重复贴图相同 则替换for (int j = 0; j < textureNames.Length; j++){if (material.HasTexture(textureNames[j])) // 该方法获取不到不属于该shader的贴图(切换材质后unity会保留之前shader的信息){Texture texture = material.GetTexture(textureNames[j]); // 获取材质上的贴图引用if (texture != null){//Debug.Log("获取到图片名字:" + texture.name);if (texture.name == deleteTex.name){isUseTex = true;material.SetTexture(textureNames[j], tex);Debug.Log("修改的材质:" + file + "的贴图" + assetPath + ",assetGuid:" + assetGuid + ",替换为:" + path + "修改材质propertyName:" + textureNames[j]);EditorUtility.SetDirty(material);}}}}}}//5.替换完所有材质,删除该重复贴图//if(isChangeSucceedCount != referencesMatPath.Count)//{// Debug.LogError("+++修改失败+++isChangeSucceedCount:"+ isChangeSucceedCount+ "+++referencesMatPath.Count:" + referencesMatPath.Count);//}//else//{// AssetDatabase.DeleteAsset(assetPath);// Debug.LogError("+++修改成功+++");//}Debug.Log("+++DeleteAsset+++:" + assetPath);deleteTexInsId.Add(deleteTex.GetInstanceID());AssetDatabase.DeleteAsset(assetPath);}}AssetDatabase.SaveAssets();EditorUtility.ClearProgressBar();if (deleteTexInsId.Count > 0){int checkProgress = 0;for (int startIndex = 0; startIndex < matFiles.Length; startIndex++){string file = GetRelativeAssetsPath(matFiles[startIndex]);bool isCancel = EditorUtility.DisplayCancelableProgressBar("检查材质是否缺少贴图", file, (float)checkProgress / (float)matFiles.Length);checkProgress++;Material material = AssetDatabase.LoadAssetAtPath<Material>(file);SerializedObject serializedMaterial = new SerializedObject(material);SerializedProperty texturesProperty = serializedMaterial.FindProperty("m_SavedProperties.m_TexEnvs");foreach (SerializedProperty textureProperty in texturesProperty){string propertyName = textureProperty.displayName;SerializedProperty textureReference = textureProperty.FindPropertyRelative("second.m_Texture");// 检查贴图引用是否丢失if (material.shader.FindPropertyIndex(propertyName) > 0 && textureReference.objectReferenceValue == null && deleteTexInsId.Contains(textureReference.objectReferenceInstanceIDValue)){Debug.LogError($"移除重复的模型贴图导致 Missing texture in material: {material.name}, Property: {propertyName}");}}}EditorUtility.ClearProgressBar();}}
主界面图集过多
主界面UI也就几个界面,但通过unity的Memory Profiler去看内存的时候 却发现了30个左右的图集,原因是因为拼接资源的时候没注意导致一个界面依赖了好几个图集,简单解决就是把主界面和其他界面一起用到的图片放到公用图集里去,然后就调整对应的图集,代码,界面
相关文章:

unity美术资源优化(资源冗余,主界面图集过多)
图片资源冗余: UPR unity的性能优化工具检查资源 1.检查纹理读/写标记 开启纹理资源的读/写标志会导致双倍的内存占用 检查Inspector -> Advanced -> Read/Write Enabled选项 2.检查纹理资源alpha通道 如果纹理的alpha通道全部为0,或者全部为2…...
【git】github中的Pull Request是什么
在 Git 中,"pull request"(简称 PR)是一种在分布式版本控制系统中使用的功能,特别是在使用 GitHub、GitLab、Bitbucket 等基于 Git 的代码托管平台时。Pull Request 允许开发者请求将他们的代码更改合并到另一个分支&am…...
gitlab查询分支API显示不全,只有20个问题
背景 gitlab查询分支API需要查询所有分支,且分支数量大于20,但目前调用接口返回的branch最多就显示了20个 解决方案 根据GitLab的文档,查询分支API默认最多返回20个分支。如果要一次性显示80个分支,可以使用分页参数来获取所有…...

vue3+vite 实现动态引入某个文件夹下的组件 - glob-import的使用
<template><div class"user-content"><HeaderTitle title"用户详情"></HeaderTitle><div class"main-content"><div><UserForm /></div><div><TableList></TableList></d…...
hhhhh
x torch.tensor([1.0,0.],[-1.,1.],requires_gradTrue) z x.pow(2).sum() z.backward() x.grad在这段代码中,我们利用 PyTorch 进行自动求梯度,下面详细解释代码的每一个部分及其在反向传播中的作用。同时,我们也将介绍函数对象和叶子节点的…...

扫雷小游戏纯后端版
package com.wind;import java.util.Random; import java.util.Scanner;public class ResultLei {static Random random new Random();public static void main(String[] args) {boolean end true;while (end) {System.out.println("请输入你选择的难度对应的数字&#…...
RuoYi-Vue-Plus(动态添加移除数据源)
一、添加数据 private final DynamicRoutingDataSource dynamicRoutingDataSource;private final DefaultDataSourceCreator dataSourceCreator;//添加一个dynamic的数据源@GetMapping("createDynamic")public void createDynamic() {DataSourceProperty property =…...

idea启动项目报:the command line via JAR manifest or via a classpath file and rerun.
解决方案 1.打开Edit Configurations,进去编辑,如下: 笔记配置 2.选择Modfiy options,点击Shorten command line 3.在新增的Shorten command line选项中选择JAR manifest或classpath file 4.点击保存后即可...
vue3 + ts中有哪些类型是由vue3提供的?
在 Vue 3 中结合 TypeScript 使用时,Vue 提供了一系列的类型帮助函数和接口,这些类型用于增强 TypeScript 的集成和提供类型安全。以下是一些由 Vue 3 提供的常用 TypeScript 类型: RefType: 用于标注一个 ref 返回的响应式引用类型。Reacti…...

【Linux】远程连接Linux虚拟机(MobaXterm)
【Linux】远程连接Linux虚拟机(MobaXterm) 零、原因 有时候我们在虚拟机中操作Linux不太方便,比如不能复制粘贴,不能传文件等等,我们在主机上使用远程连接软件远程连接Linux虚拟机后可以解决上面的问题。 壹、软件下…...
LeetCode Hot100 生成特殊数字的最少操作
给你一个下标从 0 开始的字符串 num ,表示一个非负整数。 在一次操作中,您可以选择 num 的任意一位数字并将其删除。请注意,如果你删除 num 中的所有数字,则 num 变为 0。 返回最少需要多少次操作可以使 num 变成特殊数字。 如…...

Spring MVC 应用分层
1. 类名使⽤⼤驼峰⻛格,但以下情形例外:DO/BO/DTO/VO/AO 2. ⽅法名、参数名、成员变量、局部变量统⼀使⽤⼩驼峰⻛格 3. 包名统⼀使⽤⼩写,点分隔符之间有且仅有⼀个⾃然语义的英语单词. 常⻅命名命名⻛格介绍 ⼤驼峰: 所有单词⾸字⺟…...

QT--进程
一、进程QProcess QProcess 用于启动和控制外部进程,管理其输入输出流。 使用方法 start():启动一个新进程。setStandardInputFile():将文件作为标准输入。将进程的标准输入(stdin)重定向到指定的文件。换句话说&am…...

凸优化笔记-基本概念
原文 文章目录 最小二乘问题 仿射affine hullaffine dimension 凸集锥集超平面和半空间单纯形整半定锥保凸性的操作透视函数 凸函数的条件1阶判定条件2阶判定条件 Epigraph 外图 m i n i m i z e f 0 ( x ) minimize\ \ \ f_0(x) minimize f0(x) s u b j e c t t o f i ( …...

1858. 数组查找及替换
问题描述 给定某整数数组和某一整数 b 。 要求删除数组中可以被 b 整除的所有元素,同时将该数组各元素按从小到大排序。如果数组元素数值在 𝐴‘ 到 Z 的 ASCII 之间,替换为对应字母。 元素个数不超过 100,𝑏 在 1 …...

计算机视觉与面部识别:技术、应用与未来发展
引言 在当今数字化时代,计算机视觉技术迅速发展,成为人工智能领域的一个重要分支。计算机视觉旨在让机器理解和解释视觉信息,模拟人类的视觉系统。它在各行各业中发挥着重要作用,从自动驾驶汽车到智能监控系统,再到医疗…...

懒人精灵安卓版纯本地离线文字识别插件
目的 懒人精灵是一款可以模拟鼠标和键盘操作的自动化工具。它可以帮助用户自动完成一些重复的、繁琐的任务,节省大量人工操作的时间。懒人精灵也包含图色功能,识别屏幕上的图像,根据图像的变化自动执行相应的操作。本篇文章主要讲解下更优秀的…...

在线教育数仓项目(数据采集部分1)
文章目录 数据仓库概念项目需求及架构设计项目需求分析系统数据流程设计框架版本选型集群规模估算集群资源规划设计 数据生成模块目标数据页面事件曝光启动播放错误 数据埋点主流埋点方式(了解)埋点数据上报时机埋点数据日志结构 服务器和JDK准备服务器准…...

帕金森病(PD)诊断:三种基于语音的深度学习方法
帕金森病(Parkinson’s disease, PD)是世界上第二大流行的神经退行性疾病,全球影响着超过1000万人,仅次于阿尔茨海默症。人们通常在65岁左右被诊断出患有此病。PD的一些症状包括震颤、肌肉僵硬和运动迟缓。这些症状往往出现在较晚…...

【资料分享】2024钉钉杯大数据挑战赛A题思路解析+代码演示
2024第三届钉钉杯大学生大数据挑战赛今天已经开赛,【A题】思路解析代码,资料预览:...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...

C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...

汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...

C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...

VisualXML全新升级 | 新增数据库编辑功能
VisualXML是一个功能强大的网络总线设计工具,专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑(如DBC、LDF、ARXML、HEX等),并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...
【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?
FTP(File Transfer Protocol)本身是一个基于 TCP 的协议,理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况,主要原因包括: ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...

Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践
在 Kubernetes 集群中,如何在保障应用高可用的同时有效地管理资源,一直是运维人员和开发者关注的重点。随着微服务架构的普及,集群内各个服务的负载波动日趋明显,传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...
[特殊字符] 手撸 Redis 互斥锁那些坑
📖 手撸 Redis 互斥锁那些坑 最近搞业务遇到高并发下同一个 key 的互斥操作,想实现分布式环境下的互斥锁。于是私下顺手手撸了个基于 Redis 的简单互斥锁,也顺便跟 Redisson 的 RLock 机制对比了下,记录一波,别踩我踩过…...