当前位置: 首页 > news >正文

在unity资源中发现无效引用

本文主要解决在不打开unity的情况下搜索出无效引用的资源的方法

1. 概述

  1. 一般只要遍历一下目录里所有资源,判空一下就好了
  2. 但有些情况下,不希望打开unity, 尤其希望是在资源整合时,想更快验证资源的合法性, 这对合并提交及出包验证时,都要较大的需求

2. 简单的验证方法

  1. 简单来说,要直接分析untiy的资源文件, 而且unity资源大部分是文本文件
  2. 他们的文本格式大多是YAML, 如果直接使用PyYaml, 目前发现不行, 不过幸好, 格式相对简单, 通过分析属性的名称,再找到属性内容的方法,可以定位出Guid的值, 例如, 要查找XXX, YYY的值
import osGuidStr = "guid: "
GuidStrLen = len(GuidStr)class CheckAssetInfo:def __init__(self, filePath):self.filePath = filePathself.allGuids = []self.isInit = Falseself.checkValueNames = ["XXX", "YYY"]self.initData()def initData(self):if not self.isInit:self.allGuids = self.get_file_to_guids(self.filePath) self.isInit = Truedef get_all_guids(self):return self.allGuidsdef get_target_value(self, valueName, valueInfos):for i in range(len(valueInfos)):n, j = valueInfos[i]if n == valueName:return ireturn -1def get_file_to_guids(self, targetFilterPath):allGuids = []with open(targetFilterPath, 'r') as assetFile:contentLines = assetFile.readlines()valueInfos = self.get_all_value_index(contentLines)for checkName in self.checkValueNames:valueIndex = self.get_target_value(checkName, valueInfos)if valueIndex != -1:valueName, stline = valueInfos[valueIndex]valueName, endLine = valueInfos[valueIndex+1]allGuids.extend(self.get_value_guids(contentLines, stline, endLine))return allGuidsdef get_all_value_index(self, contentLines):valueInfos = []lineCount = len(contentLines)for i in range(lineCount):oneLine = contentLines[i]findIndex = oneLine.find(":")if findIndex != -1:valueName = oneLine[0:findIndex].strip()if valueName[0].isalpha():valueInfos.append((valueName, i))valueInfos.append(("", lineCount))return valueInfosdef get_value_guids(self, contentLines, startLineIndex, endLineIndex):allGuids = []for i in range(startLineIndex, endLineIndex):oneLine = contentLines[i]guidIndex = oneLine.find(GuidStr)if guidIndex != -1:endIndex = oneLine.find(", ", guidIndex)allGuids.append(oneLine[guidIndex + GuidStrLen: endIndex].strip())return allGuids
  1. 获得引用的GUID后,还要知道都有什么GUID的资源, 这个比较简单,只要分析meta文件就好, 以下就简单粗暴地遍历资源目录下的meta文件即可
class MetaInfo: def __init__(self, filePath):self.filePath = filePath; self.guid = self.get_guid_from_file(filePath)def get_guid_from_file(self, filePath):with open(filePath, 'r') as metaFile:allLine = metaFile.readlines()for oneLine in allLine:guidIndex = oneLine.find(GuidStr)if guidIndex != -1: return oneLine[guidIndex + GuidStrLen:len(oneLine)].strip()return ""class VegChecker: def __init__(self, baseDir):self.checkAssetDir = "Assets/checkDir" self.allAssetDir = "Assets"self.allAssetGuids = {}def get_all_target_files(self, targetDir, extName):res = []for root, dirs, files in os.walk(targetDir):for file in files:if os.path.splitext(file)[1] == extName:file_path = os.path.join(root, file)res.append(file_path)return resdef get_all_asset_guids(self):allMetaFiles = self.get_all_veg_files(self.allAssetDir, ".meta")for metaFile in allMetaFiles:metaInfo = MetaInfo(metaFile)self.allAssetGuids[metaInfo.guid] = Trueprint("Get total asset count meta count: " + str(len(self.allAssetGuids)))
  1. 获得要引用的GUID与所有的资源GUID,就很简单了,判断引用的GUID不在所有的资源GUID里就可以了
    def check_all_asset(self):res = Trueself.get_all_asset_guids()checkFiles = self.get_all_target_files(self.checkVegDir, ".asset")for oneFilter in checkFiles:assetInfo = CheckAssetInfo(oneFilter)for guid in assetInfo.allGuids:if not self.allAssetGuids.get(guid, False):print(f"fail to find guid {guid} in check asset {oneFilter}")res = Falsereturn res

3.Q&A

  1. 可能直接分析文件, 而且要大范围遍历文件,会有效率问题, 但实质试验下来, 还是挺快的, 测试验证几十个文件引用, 遍历了4万多个文件, 在i9机器,大概就8秒, 这已经比直接打开unity快多了.
  2. 当然会有分析错误的风险,但如果在一些相对明确的结构上, 也许是安全,但人工维护是免不了的
http://www.lryc.cn/news/452119.html

相关文章:

  • C#知识|基于反射和接口实现抽象工厂设计模式
  • 【分布式微服务云原生】gRPC vs RPC:深入探索远程过程调用的现代与经典
  • 听说这是MATLAB基础?
  • 【CSS/HTML】圣杯布局和双飞翼布局实现两侧宽度固定,中间宽度自适应及其他扩展实现
  • 数据流和数据流处理技术
  • (IDEA)spring项目导入本地jar包方法和项目打包时找不到引入本地jar包的问题解决方案
  • 解决TikTok无网络连接问题解析
  • k8s中,ingress的实现原理,及其架构。
  • 【数据结构强化】应用题打卡
  • 解决 MySQL 服务无法启动:failed to restart mysql.service: unit not found
  • Dubbo和Http的调用有什么区别
  • ARM 架构、cpu
  • 【React】入门Day03 —— Redux 与 React Router 核心概念及应用实例详解
  • u2net网络模型训练自己数据集
  • 登录功能开发 P167重点
  • 数据架构图:从数据源到数据消费的全面展示
  • useEffect 与 useLayoutEffect 的区别
  • OPENCV判断图像中目标物位置及多目标物聚类
  • 分布式理论:拜占庭将军问题
  • 从零开始Ubuntu24.04上Docker构建自动化部署(三)Docker安装Nginx
  • 阿里云 SAE Web:百毫秒高弹性的实时事件中心的架构和挑战
  • 人口普查管理系统基于VUE+SpringBoot+Spring+SpringMVC+MyBatis开发设计与实现
  • 使用VBA快速将文本转换为Word表格
  • 力扣题解1870
  • D3.js数据可视化基础——基于Notepad++、IDEA前端开发
  • 在Robot Framework中Run Keyword If的用法
  • 虚拟机ip突然看不了了
  • LeetCode[中等] 763. 划分字母区间
  • Java LeetCode每日一题
  • 数据结构--集合框架