引言
從 2014 年參加實習便開始使用 Unity 3D 開發遊戲,當時 Unity 還是完全閉源的,但那時候有些公司財大氣粗的會直接跟 Unity 官方購買了引擎源碼,似乎後來 Unity 就不賣給中國的企業了。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(); ... }
修改完這三處之後,重新編譯即可。
其他
由於 2015 年就已經拿到源碼,只是一直都沒時間去倒騰,最近想着抽空看一部分底層的源碼,後續可能會更新一些相關的筆記。