unity内的资源检测通常都会使用unity内的接口来完成,但是这次要做的一个功能是一个比较另类的,它需要检查prefab内的一些游戏对象的命名,所以想到读取文件然后使用正则表达式来完成这一工作,最终将py脚本打包成exe文件,其它同学不需要安装python环境也可以使用;这里对问题进行简单分解,然后完成每一个步骤。
如下,首先open打开一个文件,然后调用read读取函数拿到整个字符串内容,之后使用正则查找,注意要import re导入相应包,这里的正则语法是要匹配leg字符串,然后前后都要匹配边界,并使用r来标记这个字符串是用于正则匹配的;最终将查找结果返回,如果有则表示正常,如果返回None,则表示资源异常;
def CheckLeg(self, fileName) :
f = open(fileName)
content = f.read()
ret = re.search( r'\bleg\b', content)
f.close()
return ret
首先使用os.walk,传入一个文件夹路径,然后得到一个迭代器dir,随后遍历dir即可,如下:
dir = os.walk(self.fashionPrefabPath)
for path, dir_list, file_list in dir:
for file_name in file_list:
判断文件格式,通过前后缀过滤得到需要的所有文件;通过os.path.splittext来进行分割,如下所示分别得到前缀和后缀,然后对相应文件进行资源检测,由于需要传入的是一个路径,所以使用os.path.join来进行路径的连接
prefix = os.path.splitext(file_name)[0]
suffix = os.path.splitext(file_name)[-1]
if re.search( r'03\b', prefix) and suffix == '.prefab' :
filePath = os.path.join(path, file_name)
if None == self.CheckLeg(filePath) :
errorLog += file_name + '\n'
需要提供一个打开文件夹的按钮,定义了一个如下函数,指定了默认的打开路径,其中在使用路径拼接的时候,可以通过..或者../..获得上级目录和上上级目录等;但是在显示选择的路径时,需要使用os.path.abspath来打印绝对路径;
def openFoler(self):
path = QFileDialog.getExistingDirectory(self, u'选择文件夹', self.fashionPrefabPath)
if path != '' :
self.fashionPrefabPath = path
self.pathLabel.setText(os.path.abspath(self.fashionPrefabPath))
选择以后可以根据日志来弹出提示,这里使用了QMessageBox;
如果想要在clicked.connected()中调用的函数传递参数,可使用lambda表达式,如
btn.clicked.connect(lambda: self.checkPrefab(arg1, arg2))
打包成exe,我们需要安装pyinstaller,这个直接使用pip install pyinstaller命令即可,然后运行pyinstaller name.py,即可生成exe文件;上面那种命令会生成很多文件,如果想打成一个只有exe文件,需要使用pyinstall -F name.py,打出来的exe直接拷贝到其它机器上无需python环境即可运行,但是这种exe会生成一个黑色的dos命令框,使用pyinstall -F -w name.py即可解决问题;
# -*- coding: utf-8 -*-
import re
import os
import sys
from PyQt5.QtWidgets import (QApplication, QWidget, QToolTip, QPushButton, QMessageBox, QDesktopWidget, QFileDialog, QLabel)
from PyQt5.QtGui import (QIcon, QFont)
class CheckWidget(QWidget):
def __init__(self):
self.fashionPrefabPath = os.path.join(os.getcwd(), '../..', 'Assets/Resources/Prefabs/FashionPartPrefab')
# self.fashionPrefabPath = 'D:/WorkSpace/client2/Assets/Resources/Prefabs/FashionPartPrefab'
super().__init__()
self.initUI()
def initUI(self):
label = QLabel(u'鞋子prefab leg命名监测:', self)
label.move(40, 55)
btn = QPushButton('选择文件夹', self)
self.pathLabel = QLabel(os.path.abspath(self.fashionPrefabPath), self)
self.pathLabel.move(300, 55)
label.resize(label.sizeHint())
btn.clicked.connect(self.openFoler)
btn.resize(btn.sizeHint())
btn.move(200, 50)
btn = QPushButton(u'开始检测', self)
btn.clicked.connect(self.checkPrefab)
btn.resize(btn.sizeHint())
btn.move(40, 100)
self.setGeometry(300, 300, 800, 600)
self.center()
self.setWindowTitle(u'3D角色美术资源监测工具')
self.show()
def center(self):
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def openFoler(self):
path = QFileDialog.getExistingDirectory(self, u'选择文件夹', self.fashionPrefabPath)
if path != '' :
self.fashionPrefabPath = path
self.pathLabel.setText(os.path.abspath(self.fashionPrefabPath))
# 如果没有查找到,返回None
def CheckLeg(self, fileName) :
f = open(fileName)
content = f.read()
ret = re.search( r'\bleg\b', content)
f.close()
return ret
def checkPrefab(self):
if not self.fashionPrefabPath or '' == self.fashionPrefabPath :
QMessageBox.warning(self, 'Warning',
u'错误:文件夹未选择或文件夹无效', QMessageBox.Yes)
dir = os.walk(self.fashionPrefabPath)
errorLog = ''
for path, dir_list, file_list in dir:
for file_name in file_list:
prefix = os.path.splitext(file_name)[0]
suffix = os.path.splitext(file_name)[-1]
if re.search( r'03\b', prefix) and suffix == '.prefab' :
filePath = os.path.join(path, file_name)
if None == self.CheckLeg(filePath) :
errorLog += file_name + '\n'
if errorLog == '' :
QMessageBox.information(self, u'检测结果',
u"无资源错误", QMessageBox.Yes)
else :
QMessageBox.information(self, u'检测结果',
u"以下资源leg命名出错:\n" + errorLog, QMessageBox.Yes)
def main():
app = QApplication(sys.argv)
ex = CheckWidget()
sys.exit(app.exec_())
if __name__ == '__main__':
main()