本文是自己在研究學(xué)習(xí)Godot時(shí)的筆記。
一、使用插件
1.1 在Godot里使用的情況
一個(gè)iOS插件需要一個(gè) .gdip 配置文件, 一個(gè)二進(jìn)制文件, 它可以是 .a 靜態(tài)庫(kù), 也可以是 .xcframework 包含 .a 靜態(tài)庫(kù), 可能還有其他依賴關(guān)系. 要使用它, 需要:
- 1.將插件的文件復(fù)制到Godot項(xiàng)目的
res://ios/plugins目錄中. 你也可以將文件分組在一個(gè)子目錄中, 比如res://ios/plugins/my_plugin - 2.Godot編輯器自動(dòng)檢測(cè)并導(dǎo)入
res://ios/plugins及其子目錄中的.gdip文件. - 3.可以通過(guò)進(jìn)入
Project->Export... ->iOS, 在選項(xiàng)卡中, 滾動(dòng)到Plugins部分, 找到并激活檢測(cè)到的插件.

在Godot項(xiàng)目里面的iOS插件目錄:

注意,自己創(chuàng)建的.gdip文件,注意下面的問(wèn)題:
[config]
name="GodotSkyBridge" # 插件的名稱
binary="GodotSkyBridge.xcframework" # 千萬(wàn)注意別寫(xiě)錯(cuò)xcframework的名字
initialization="godot_iosbridge_init" # 兩個(gè)函數(shù)是代碼寫(xiě)的,這里不能寫(xiě)錯(cuò)
deinitialization="godot_iosbridge_deinit"
[dependencies] # 如果有依賴的情況
linked=[]
embedded=[]
system=[]
capabilities=[]
files=[]
[plist] # 隱私key之類(lèi)的情況,會(huì)加到info.plist里面
1.2 在iOS工程里使用的情況
我當(dāng)前就是這種情況,我并不需要將插件放到Godot工程里面,而是將插件打包成xcframework放在iOS工程里面,在工程運(yùn)行時(shí),讓Godot引擎加載插件即可。
例如在iOS工程的dummy.cpp文件內(nèi)容如下:
// Godot Plugins
void godot_ios_plugins_initialize();
void godot_ios_plugins_deinitialize();
// Exported Plugins
// Plugin: GodotSkyBridge
extern void my_plugin_init();
extern void my_plugin_deinit();
// Use Plugins
void godot_ios_plugins_initialize() {
my_plugin_init();
}
void godot_ios_plugins_deinitialize() {
my_plugin_deinit();
}
dummy.cpp文件為Godot引擎所需的插件入口文件,會(huì)在引擎啟動(dòng)時(shí)調(diào)用。這樣的好處時(shí),可以暴漏代碼的.h頭文件,原生能直接和Godot引擎通信,例如工程結(jié)構(gòu):

二、創(chuàng)建iOS插件
2.1 編譯Godot頭文件
下載下面官方的iOS插件倉(cāng)庫(kù),以為里面有現(xiàn)成的腳本和例子。(==注意所需分支==)
iOS插件倉(cāng)庫(kù):https://github.com/godotengine/godot-ios-plugins
倉(cāng)庫(kù)的下載可以直接下載對(duì)應(yīng)release代碼,或者使用git命令下載,例如:
$ git clone --recursive https://github.com/godotengine/godot-ios-plugins.git godot-ios-plugins

下載好倉(cāng)庫(kù)代碼之后,是沒(méi)有紅色框的東西的。
- a.如果直接下載的倉(cāng)庫(kù)源碼,
godot文件夾會(huì)是空的,需要自己再下載Godot的源碼并放到godot文件夾下 - b.使用上面
git命令下載的代碼,godot文件夾會(huì)自動(dòng)拉取對(duì)應(yīng)的Godot源碼 - c.將
extract_headers.sh和generate_headers.sh這2個(gè)腳本,從scripts文件夾里面拷貝到外面的根目錄下,如上圖的紅色框。(其實(shí)不復(fù)制出來(lái)也可以,這里只是為了突出這些腳本的重要性) - d.終端來(lái)到這個(gè)根目錄下,執(zhí)行腳本:
$ cd xxxx_path # 倉(cāng)庫(kù)目錄
$ ./generate_headers.sh # 注意下面的說(shuō)明
$ ./extract_headers.sh
需要注意的是:執(zhí)行./generate_headers.sh之后,會(huì)開(kāi)始編譯Godot的源碼,沒(méi)必要編譯完畢,執(zhí)行大概十秒就直接停掉就行。執(zhí)行./extract_headers.sh之后,倉(cāng)庫(kù)根目錄就會(huì)多一個(gè)/bin文件夾,里面接下來(lái)所需的Godot頭文件
A.腳本generate_headers.sh內(nèi)容如下:
#!/bin/bash
cd ./godot && \
./../scripts/timeout scons platform=iphone target=release_debug
# 從腳本可以看出來(lái),其實(shí)是在 scons 構(gòu)建iPhone平臺(tái)的目標(biāo)文件
# 注意
B.腳本extract_headers.sh內(nèi)容如下:
#!/bin/bash
rsync -a -m -R --include '*/' --include '*.h' --include '*.inc' --exclude '*' ./godot ./bin/extracted_headers
2.2 創(chuàng)建和設(shè)置Xcode工程
創(chuàng)建靜態(tài)庫(kù)工程,我這里隨便起個(gè)名字叫GodotSkyBridge:

設(shè)置iOS的版本:

設(shè)置架構(gòu):

將生成好的Godot頭文件拖到項(xiàng)目里,簡(jiǎn)單粗暴:

設(shè)置HEADER_SEARCH_PATHS:

這里的值,簡(jiǎn)單的辦法是,選中工程里面的Godot目錄,在Xcode左側(cè)屬性里復(fù)制即可:

此時(shí)直接編譯一下,會(huì)成功,其實(shí)已經(jīng)生成.a文件了,但是可能不知道在哪里。有2個(gè)辦法:
2.2.1 在下圖中,直接復(fù)制,粘貼到文本工具里,會(huì)有.a的路徑:

2.2.2 第二種辦法是:打開(kāi)項(xiàng)目的project.pbxproj,搜索productRefGroup,將productRefGroup上面一行的mainGroup的值,復(fù)制給productRefGroup,再保存一下,Xcode就自動(dòng)刷新出來(lái)了。

開(kāi)始敲代碼之前,還需要設(shè)置一下Other C Flags:

增加 -fcxx-modules 和 -fmodules,如果你需要支持調(diào)試就還有 -DDEBUG
2.3 導(dǎo)出靜態(tài)庫(kù)方案A
(我不推薦此方案)敲完代碼,選擇Scheme,分別設(shè)置Release和Debug,進(jìn)而拿到.a文件:

我將2個(gè).a復(fù)制到了一個(gè)單獨(dú)的文件夾,并重命名了:

執(zhí)行下面的命令。將.a文件轉(zhuǎn)為了.xcframework文件:
# debug文件
$ xcodebuild -create-xcframework -library libGodotSkyBridge.arm64_debug.a -output libGodotSkyBridge.debug.xcframework
# release文件
$ xcodebuild -create-xcframework -library libGodotSkyBridge.arm64_release.a -output libGodotSkyBridge.release.xcframework
可以通過(guò)lipo -info命令查看.a的架構(gòu)信息:
$ lipo -info libGodotSkyBridge.arm64_release.a
Non-fat file: libGodotSkyBridge.arm64_release.a is architecture: arm64
??這部分可以參考iOS的靜態(tài)庫(kù)的創(chuàng)建和使用
2.4 導(dǎo)出靜態(tài)庫(kù)方案B
在2.3的方案里面,需要在工程的setting里面設(shè)置很多參數(shù),一旦有錯(cuò)誤,就在Godot里面使用不了,下面使用腳本的方案:
從官方的 godot-ios-plugins 項(xiàng)目下載下來(lái),注意分支。將寫(xiě)好的代碼。放到plugins里面,注意建單獨(dú)的文件夾:

修改項(xiàng)目根目錄下面的SConstruct腳本內(nèi)容,讓腳本知道我們?cè)黾恿艘粋€(gè)自己的庫(kù):

將generate_static_library.sh從scripts拷貝到項(xiàng)目的根目錄下。然后在終端執(zhí)行,注意加參數(shù):
$ cd xxx
$ ./generate_static_library.sh GodotSkyBridge release 3.x
# 三個(gè)參數(shù) 插件名 編譯類(lèi)型 Godot版本
我在執(zhí)行腳本之前,在倉(cāng)庫(kù)目錄里面的godot是有內(nèi)容的,也就是godot的頭文件,可以在
2.3里面看看怎么生成頭文件。
備份generate_static_library.sh腳本內(nèi)容:
#!/bin/bash
set -e
# Compile static libraries
# ARM64 Device
scons target=$2 arch=arm64 plugin=$1 version=$3
# x86_64 Simulator
scons target=$2 arch=x86_64 simulator=yes plugin=$1 version=$3
# Creating a fat libraries for device and simulator
# lib<plugin>.<arch>-<simulator|iphone>.<release|debug|release_debug>.a
lipo -create "./bin/lib$1.x86_64-simulator.$2.a" \
"./bin/lib$1.arm64-iphone.$2.a" \
-output "./bin/$1.$2.a"
腳本執(zhí)行完畢,會(huì)在倉(cāng)庫(kù)根目錄下,生成bin/文件夾里面,

將.a生成.xcframework,例如只將arm64和x86_64合并:
$ cd bin
$ xcodebuild -create-xcframework -library libGodotSkyBridge.arm64-iphone.release_debug.a -library libGodotSkyBridge.x86_64-simulator.release_debug.a -output GodotSkyBridge.debug.xcframework
生成的.xcframework如下圖所示:

三.將Godot項(xiàng)目結(jié)合原生項(xiàng)目
3.1 Godot導(dǎo)出iOS項(xiàng)目情況
Godot導(dǎo)出的iOS項(xiàng)目結(jié)構(gòu)如下:

使用Xcode打開(kāi)之后,如下圖所示,注意觀察紅框里面的內(nèi)容:

3.2 新建的Xcode工程+Godot工程
兩個(gè)步驟:
- A.新建
Xcode工程,設(shè)置版本號(hào),Pod依賴,并且能正確編譯 - B.來(lái)到新建項(xiàng)目的根目錄下,處理如下:

其中dylibs是直接從Godot導(dǎo)出的復(fù)制過(guò)來(lái)的,godot_project是自己新建的,并將.pck和Godot引擎的xcframework給復(fù)制過(guò)來(lái)了。
將dylibs和godot_project導(dǎo)入到Xcode里面,注意結(jié)構(gòu)和選擇:


正確之后,兩個(gè)文件夾的顏色應(yīng)該是藍(lán)色的,此時(shí)刪除AppDelegate、ViewController和main.m三個(gè)文件。并把Godot導(dǎo)出的dummy.cpp也導(dǎo)入Xcode里面。
此時(shí)還是無(wú)法啟動(dòng)工程的,去下圖那里,導(dǎo)入庫(kù)即可,這些庫(kù)都在dylibs和godot_project 2個(gè)文件夾里面,其實(shí)可以直接拖拽的方式到這里。

最后在Info.plist里面增加字段,告訴Godot引擎,怎么啟動(dòng)Godot游戲:

此時(shí)可以運(yùn)行iOS工程了,結(jié)合最初使用插件的部分,就可以對(duì)引擎進(jìn)行高度的定制化。