引言
Unity 官方從 Unity 2017.1 版本開始,開源了引擎和編輯器的C#源碼(源碼地址:UnityCsReference),但核心的 C/C++ 部分源碼並未開源。
編譯環境
網上主要的源碼有兩個版本 Unity 4.3.1f1 和 Unity 4.7.1f1 ,但其實基本都是 4.3.1 的版本,這里以 Unity 4.3 為例進行源碼編譯,但編譯之前需要安裝一些工具軟件:
- Visual Studio 2010 (不能使用高版本的 VS 進行源碼編譯,不然會報錯)
- Visual Studio 2010 SP1
- Perl (下載安裝 ActivePerl 即可)
源碼包
Unity4.7.1f1_source_3eo9sdfl01d_final.zip 網上有很多種方式可以獲得源碼包,而且這些包基本都是 Unity 4.3.1f1 的版本,只是包名改成 4.7 來騙下載量的吧~
編譯步驟
將源碼包放在磁盤根目錄下,路徑太深可能會出現解壓時報錯(原因是文件名太長導致的),例如這里我的存放目錄為 F:\Unity4.7.1f1_source ;
進入工程目錄,雙擊 jamCreateWorkspace.bat 腳本,執行完畢后在 Projects 目錄下會多出一個 JamGenerated 目錄;(假如沒有此腳本,也可以使用在當前目錄下使用命令行執行 perl build.pl --prepare 來生成);
然后使用 VS 打開 Projects/JameGenerated/_workspace.vs2010_/AllTarget.sln ,在解決方案資源管理器中選中 Editor 解決方案,右鍵 生成 ;
構建完成后,構建結果在 build/WindowsEditor 目錄下,雙擊 Unity.exe 啟動編輯器即可啟動編輯器。
編譯時報錯解決
- 依賴庫沒自動解壓:
在 External 目錄下有很多依賴庫,有些是以壓縮包的形式存在的,但編譯的時候可能出現壓縮包無法自動解壓縮的情況,要么手動解壓縮這些包,要么就使用自動化工具批量解壓縮,顯然后者要靠譜一些,可以避免遺漏。
其實這些壓縮包都是以 builds 命名的,后綴名為 .zip 、.7z 或這 .tar.gz 三種,這里我直接用 QQ 群友寫的一個 python 腳本實現解壓操作。但是需要安裝 7z.exe 並將其配置到系統環境變量中(確保可以在任何目錄下通過命令行調用),具體代碼如下(例如取名為 unzipExtenalBuilds.py):
# -*- encoding: utf-8 -*-
import os
def unzip():
for path, dirs, files in os.walk(r"External"):
dir = os.path.join(path, "builds")
if os.path.isdir(dir):
continue
for ext in [".7z", ".tar.gz", ".zip"]:
fname = dir + ext
if os.path.exists(fname):
cmd = "7z.exe x " + fname + " -o" + dir
print(cmd)
os.system(cmd)
if __name__ == "__main__":
unzip()
將此腳本放在工程根目錄下,在命令行執行:
$ python unzipExtenalBuilds.py
解壓完成后,再重頭走一遍上面的編譯步驟。
- 中文系統導致的問題:
當如當前的系統是中文系統,然后在編譯時出現很多如下報錯:
C2220 警告被視為錯誤 - 沒有生成 "obj" 文件
C4819 該文件包含不能在當前代碼頁(936)中表示的字符。請將該文件保存為 Unicode 格式以防止數據丟失
...
解決方案:
修改 Projects/Jam/Editor.jam 中第 360 行,插入 /wd4819 ,如下:
local vsflags = /WX /wd4251 ; //修改前
local vsflags = /WX /wd4251 /wd4819 ; //修改后
- 未安裝 VS 2010 SP1 補丁
編譯時出現如下報錯:
C3861 "_xgetbv" :找不到標識符
這是因為沒有安裝 Visual Studio 2010 SP1 ,在編譯 CPUInfo.cpp 時因找不到 _xgetbv 方法而導致報錯。
解決方案:
下載安裝 VS10sp1-KB983509.exe 補丁,重新編譯即可。
啟動時報錯
Error loading page
SSL peer certificate or SSH remote key was not OK
這是因為許可管理導致的,因為在 Unity 啟動時會聯網校驗許可信息。
解決方案:
- 方案1:
可以用常用的方法進行破解,例如從 Unity 官網通過上傳 Unity_v4.3.1f1.alf 再下載一個 Unity_v4.x.ulf 導入編輯器來激活,然后修改 LicenseManager.cpp 的 1709 行獲取失效時間的代碼:
std::string stopString = GetDate("StopDate", doc); // 修改前
std::string stopString = "2112-01-27T08:00:00"; // 修改后
- 方案2:
既然是要研究源碼,最好是從源頭上解決,打開 Editor/Src/LicenseInfo.cpp ,修改兩個地方:
UInt64 LicenseInfo::GetRawFlags ()
{
// 插入內容 start
if (m_Tokens == 0)
{
m_Tokens = 12345678;
}
// 插入內容 end
return m_Tokens;
}
void LicenseInfo::InitializeProtection()
{
...
int state = m_LicenseManager->Initialize();
// 插入一行代碼代碼
state = kLicenseStatus_Valid;
}
打開 Editor/Src/Application.cpp ,修改方法:
void Application::TickTimer()
{
// 屏蔽一下兩行代碼
//if (m_IsInitialized)
// LicenseInfo::Get()->Tick();
...
}
修改完這三處之后,重新編譯即可。
其他
- 嘗試用vs2012編譯,編譯失敗了
- 用VS2010編譯(未安裝VS2010 SP1)報了其他與此不同的錯誤,安裝VS2010后編譯成功
Ref: https://blog.csdn.net/linshuhe1/article/details/90295325