每天学习一点新知识(一)——Unity开发游戏的拆包

每天学习一点新知识(一)——Unity开发游戏的解包

用了CSDN有一段时间了,但一直都没有写过blog,只是在输入,没有输出。而且一直主要都是在查一些作业、题解什么的,还是希望自己能够多学到一些新东西吧,不管是语言也好,技术也好,提高自己就可以。
所以打算写这么一个系列,就是每天学一点新知识、每天有一点提高。可能其中主要的还是学习一些CSDN和Github上的小项目,争取每周写一篇,如果简单的话,还可以再频繁一些。

好,说在前面的就这么多,既是给读者看的,也是给自己看的。下面正式开始写今天的内容——Unity开发的游戏的解包。

想法的由来

因为玩游戏,所以一直以来都对游戏的开发有点兴趣,在开始学各种语言的时候也会了解或者自己练习着写两个小游戏的程序,虽然基本是照着源码敲。
最近一直在玩明日方舟,每次更新的时候,开服前就会有人将提前拆包的得到的新图的信息发布在超话中,于是我就想,如果自己也能够学会解包,那岂不是很爽。于是我就开始搜索学习。
这个就是我学习解包的blog,大家可以看一下

准备工作

首先,要解包Unity引擎开发的游戏,我们需要下载一个Unity Studio。这是我们进行解包的主要工具,它的操作也非常简单。
其次是python,这个是用来对解包得到的数据进行处理的,如果说你不打算对数据进行任何处理,只希望能看到就好,那就没有必要用python。使用python最重要的目的就是利用它多种多样的库,因为解包游戏的目的主要是为了立绘(老婆),所以暂时只用到opencv库。如果想要对其他诸如文本数据进行处理的话,就要去下载一些别的库。

那我们的工作正式开始

这里就以明日方舟为例,游戏的apk文件直接到官网下载即可。下载到本地之后,将apk后缀改为rar,然后解压。
明日方舟的数据文件都在assets这个文件夹中,我们可以看到其中大部分都是以ab为后缀的。
打开Unity Studio中的exe执行文件,可以看到如下界面:

然后要进行的就是最重要的一步,将文件加载进来,点击File,如果想要看某一个文件的话,就点击Load file单选那个文件就好,若像看所有的文件,就点击Load folder将整个assets文件夹加载即可(如果只看立绘,选择assets\AB\Android\charpack\文件夹就可以了)。
加载完毕后,点击Unity Studio中的Asset List就可以看自己想看的东西啦!
能天使
如果只是想要看到数据,到这一步就可以了,但是,对于立绘来说,每次要点进去,再加载是很费时间的,所以我们希望可以将图片全部导出来,这一功能也可以在Unity Studio中很简单的实现,点击Export可以导出自己选中的文件,也可以导出全部文件,之后我们就可以在外部欣赏老婆立绘了。

如果你不满足于此的话,请继续往下看

到上一步为止,我们已经将所有的图片用png格式保存到了外面,但是我们会发现,这些图片会有一个铺满效果的背景,并不是我们想象中的白底的样式,看起来并不是很舒服。
因此,这个时候就到了python上场的时间了。
正如前文所说,python需要使用到opencv库,这是一个用来做图像处理的库,C++中也有,但是python使用起来比较简单。
在命令行下载opencv库的命令是pip install opencv-python,如果速度很慢的话,可以换源(如清华源、中科大源等),这里以清华源为例,执行下面命令即可
pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple

安装好库之后,我们就开始来写代码了:

# -*- coding: utf-8 -*-
import shutil
import time
import cv2
import os

def read_png(s):
	img = cv2.imread(s, cv2.IMREAD_UNCHANGED)
	return img
def save_png(s, img):
	cv2.imwrite(s, img, [int(cv2.IMWRITE_PNG_COMPRESSION), 9])
def exchange(img, x): #放大图像
	w, h = img.shape[0:2]
	tempimg = cv2.resize(img,(w*x,h*x), interpolation=cv2.INTER_CUBIC)
	return tempimg
def Do(a, b):
	a[:,:,3] = b[:,:,0] #合成的基本思路
	return a
    
print("提取图片/合成立绘?1/2")
a = input()
if a == '1': #提取立绘
	file_list = os.listdir("./Texture2D")
	print("共%d个图片:" %len(file_list))
	print('begin')
	for i in file_list:
		img = cv2.imread("./Texture2D/" + i, cv2.IMREAD_UNCHANGED)
		if img is not None and img.shape[0] > 512:
			if '#' in i:
				i2 = i.replace(i[i.find('#'):], '#1[alpha].png')
				i3 = i.replace(i[i.find('#'):], '#1.png')
			else:
				i2 = i.replace(".png", '[alpha].png')
				i3 = i
			if i2 in file_list:
				shutil.copy("./Texture2D/" + i, "./Texture2D_A/" + i3)
				os.remove("./Texture2D/" + i)
				shutil.copy("./Texture2D/" + i2, "./Texture2D_B/" + i2)
				os.remove("./Texture2D/" + i2)
	print('over')
if a == '2': #合成立绘
	file_list = os.listdir("./Texture2D_A")
	print("待合成%d个图片:" %len(file_list))
	for i in file_list:
		print('正在处理%s' %i)
		time_start = time.time()
		i2 = i.replace(".png", '[Alpha].png')
		a = read_png('./Texture2D_A/' + i)
		b = read_png('./Texture2D_B/' + i2)
		if a.shape[0]/b.shape[0] != 1:
			b = exchange(b, int(a.shape[0]/b.shape[0]))
		save_png('./Picture/' + i, Do(a, b))
		shutil.copy("./Texture2D_A/" + i, "./Used/" + i)
		os.remove("./Texture2D_A/" + i)
		time_end = time.time()
		print("耗时 %f s" %(time_end-time_start))
	print('over')
	os.system('pause')

代码并不难理解,大家可以自己分析一下。
执行1提取图片,执行2合成立绘。
需要注意的是程序中提到的Texture2D_A、Texture2D_B、Used、Picture这几个文件夹是需要提前建好的。另外,因为yj的图片命名有些毒,所以可能在提取图片时可能会中途停止,多执行几次就好了;还有可能会漏掉一些立绘,这个应该可以同归正则表达式来解决,还在研究中。
当全部执行完后,你就可以在Picture文件夹中看到已经合成好的立绘啦!
在这里插入图片描述

自我尝试

以上的全部都是在我开头所指出的博客中讲到的,为了自己练习,我又尝试了元气骑士的解包,效果如下:
在这里插入图片描述
在这里插入图片描述
以上就是我对与自己学习解包的一些总结。

发布了1 篇原创文章 · 获赞 1 · 访问量 46

猜你喜欢

转载自blog.csdn.net/chuo_xiaowei/article/details/105024789