編譯 Unity 4.3.1 引擎源碼

引言

從 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 年就已經拿到源碼,只是一直都沒時間去倒騰,最近想着抽空看一部分底層的源碼,後續可能會更新一些相關的筆記。

 

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章