iOS 的插件

Godot 提供了 StoreKit、GameCenter、iCloud 服务等插件。它们使用下面解释的相同异步调用模型。

ARKit和Camera访问也作为插件提供.

最新的更新、文档和源代码可以在Godot iOS插件库找到 Godot iOS plugins repository

访问插件单例

要访问插件功能, 首先需要通过调用 Engine.has_singleton() 函数来检查插件是否导出并可用, 该函数会返回一个注册的单例.

下面是一个如何在GDScript中做到这一点的例子:

  1. var in_app_store
  2. var game_center
  3. func _ready():
  4. if Engine.has_singleton("InAppStore"):
  5. in_app_store = Engine.get_singleton("InAppStore")
  6. else:
  7. print("iOS IAP plugin is not available on this platform.")
  8. if Engine.has_singleton("GameCenter"):
  9. game_center = Engine.get_singleton("GameCenter")
  10. else:
  11. print("iOS Game Center plugin is not available on this platform.")

异步方法

请求异步操作时, 方法如下所示:

  1. Error purchase(Variant params);

参数通常是一个字典,包含发出请求所需的信息,并且调用将有两个阶段。首先,该方法将立即返回 Error 值。如果这个 Error 不是“OK”,则调用操作完成,可能在本地引起错误(没有网络连接、API 配置不正确等)。如果错误值是“OK”,则会生成响应事件并将其添加到“挂起事件”队列中。例如:

  1. func on_purchase_pressed():
  2. var result = InAppStore.purchase({ "product_id": "my_product" })
  3. if result == OK:
  4. animation.play("busy") # show the "waiting for response" animation
  5. else:
  6. show_error()
  7. # put this on a 1 second timer or something
  8. func check_events():
  9. while in_app_store.get_pending_event_count() > 0:
  10. var event = in_app_store.pop_pending_event()
  11. if event.type == "purchase":
  12. if event.result == "ok":
  13. show_success(event.product_id)
  14. else:
  15. show_error()

请记住,当一个调用返回 OK 时,API 将始终通过 pending_event 接口产生一个事件,即使它是一个错误,或网络超时等。您应该能够,例如,安全地阻止等待的接口来自服务器的回复。如果任何 API 不以这种方式运行,则应将其视为错误。

挂起事件接口包含两个方法:

  • get_pending_event_count() 返回队列中挂起事件的数量。

  • Variant pop_pending_event() 弹出队列中的第一个事件并返回它。

Store Kit

实现在 Godot iOS InAppStore 插件 .

Store Kit API 可通过 InAppStore 单例访问。它是自动初始化的。

提供了以下方法,文档如下:

  1. Error purchase(Variant params)
  2. Error request_product_info(Variant params)
  3. Error restore_purchases()
  4. void set_auto_finish_transaction(bool enable)
  5. void finish_transaction(String product_id)
  6. and the pending events interface:
  7. ::
  8. int get_pending_event_count()
  9. Variant pop_pending_event()

purchase

通过 Store Kit API 购买一个产品 ID。你需要在收到成功响应后调用 finish_transaction(product_id),或者在调用 purchase() 之前调用 set_auto_finish_transaction(true)。这两个方法确保事务完成。

参数

参数是一个字典,包含一个 product_id 字段,是你的商品的字符串 ID。例子:

  1. var result = in_app_store.purchase({ "product_id": "my_product" })

响应事件

响应事件将是包含以下字段的字典:

出错时:

  1. {
  2. "type": "purchase",
  3. "result": "error",
  4. "product_id": "the product ID requested",
  5. }

成功时:

  1. {
  2. "type": "purchase",
  3. "result": "ok",
  4. "product_id": "the product ID requested",
  5. }

request_product_info

在产品ID列表中请求产品信息.

参数

参数为字典,只有一个字段 product_ids,是产品 ID 字符串的数组。例如:

  1. var result = in_app_store.request_product_info({ "product_ids": ["my_product1", "my_product2"] })

响应事件

响应事件将是包含以下字段的字典:

  1. {
  2. "type": "product_info",
  3. "result": "ok",
  4. "invalid_ids": [ list of requested IDs that were invalid ],
  5. "ids": [ list of IDs that were valid ],
  6. "titles": [ list of valid product titles (corresponds with list of valid IDs) ],
  7. "descriptions": [ list of valid product descriptions ] ,
  8. "prices": [ list of valid product prices ],
  9. "localized_prices": [ list of valid product localized prices ],
  10. }

restore_purchases

恢复用户账户之前完成的购买。会为每一个之前购买过的产品 ID 创建响应事件。

响应事件

响应事件将是包含以下字段的字典:

  1. {
  2. "type": "restore",
  3. "result": "ok",
  4. "product_id": "product ID of restored purchase",
  5. }

set_auto_finish_transaction

设为 true 时,一旦购买成功,就会自动结束购买。请在调用 purchase() 前调用本方法。

参数

参数为布尔值,表示购买是否应该自动结束。例如:

  1. in_app_store.set_auto_finish_transaction(true)

finish_transaction

如果你不希望自动结束交易事务,请在接收到成功购买响应后调用本方法。

参数

参数 product_id 是一个字符串。product_id 表示需要结束购买的产品。例如:

  1. in_app_store.finish_transaction("my_product1")

游戏中心

Godot iOS GameCenter 插件中实现。

Game Center API 可以通过“GameCenter”单例使用。它有以下方法:

  1. Error authenticate()
  2. bool is_authenticated()
  3. Error post_score(Variant score)
  4. Error award_achievement(Variant params)
  5. void reset_achievements()
  6. void request_achievements()
  7. void request_achievement_descriptions()
  8. Error show_game_center(Variant params)
  9. Error request_identity_verification_signature()

以及未决事件接口:

  1. int get_pending_event_count()
  2. Variant pop_pending_event()

authenticate

在游戏中心对用户进行身份验证.

响应事件

响应事件将是包含以下字段的字典:

出错时:

  1. {
  2. "type": "authentication",
  3. "result": "error",
  4. "error_code": the value from NSError::code,
  5. "error_description": the value from NSError::localizedDescription,
  6. }

成功时:

  1. {
  2. "type": "authentication",
  3. "result": "ok",
  4. "player_id": the value from GKLocalPlayer::playerID,
  5. }

post_score

将分数发布到游戏中心排行榜.

参数

参数为一个字典,有两个字段:

  • score 浮点数

  • category 表示类别名称的字符串

示例:

  1. var result = game_center.post_score({ "score": 100, "category": "my_leaderboard", })

响应事件

响应事件将是包含以下字段的字典:

出错时:

  1. {
  2. "type": "post_score",
  3. "result": "error",
  4. "error_code": the value from NSError::code,
  5. "error_description": the value from NSError::localizedDescription,
  6. }

成功时:

  1. {
  2. "type": "post_score",
  3. "result": "ok",
  4. }

award_achievement

修改游戏中心成就的进度.

参数

将Dictionary作为参数, 包含3个字段:

  • name(字符串)成就名称

  • progress(float)成就进度从 0.0 到 100.0(传递给 GKAchievement :: percentComplete

  • show_completion_banner(bool)游戏中心是否应该在屏幕顶部显示成就横幅

示例:

  1. var result = award_achievement({ "name": "hard_mode_completed", "progress": 6.1 })

响应事件

响应事件将是包含以下字段的字典:

出错时:

  1. {
  2. "type": "award_achievement",
  3. "result": "error",
  4. "error_code": the error code taken from NSError::code,
  5. }

成功时:

  1. {
  2. "type": "award_achievement",
  3. "result": "ok",
  4. }

reset_achievements

清除所有 Game Center 成就。该函数不带参数。

响应事件

响应事件将是包含以下字段的字典:

出错时:

  1. {
  2. "type": "reset_achievements",
  3. "result": "error",
  4. "error_code": the value from NSError::code,
  5. }

成功时:

  1. {
  2. "type": "reset_achievements",
  3. "result": "ok",
  4. }

request_achievements

请求游戏角色取得进步的所有游戏中心成就. 该函数不带参数.

响应事件

响应事件将是包含以下字段的字典:

出错时:

  1. {
  2. "type": "achievements",
  3. "result": "error",
  4. "error_code": the value from NSError::code,
  5. }

成功时:

  1. {
  2. "type": "achievements",
  3. "result": "ok",
  4. "names": [ list of the name of each achievement ],
  5. "progress": [ list of the progress made on each achievement ],
  6. }

request_achievement_descriptions

无论进度如何, 都要求描述所有现有的Game Center成就. 该函数不带参数.

响应事件

响应事件将是包含以下字段的字典:

出错时:

  1. {
  2. "type": "achievement_descriptions",
  3. "result": "error",
  4. "error_code": the value from NSError::code,
  5. }

成功时:

  1. {
  2. "type": "achievement_descriptions",
  3. "result": "ok",
  4. "names": [ list of the name of each achievement ],
  5. "titles": [ list of the title of each achievement ],
  6. "unachieved_descriptions": [ list of the description of each achievement when it is unachieved ],
  7. "achieved_descriptions": [ list of the description of each achievement when it is achieved ],
  8. "maximum_points": [ list of the points earned by completing each achievement ],
  9. "hidden": [ list of booleans indicating whether each achievement is initially visible ],
  10. "replayable": [ list of booleans indicating whether each achievement can be earned more than once ],
  11. }

show_game_center

显示内置的游戏中心叠加层, 显示排行榜, 成就和挑战.

参数

将Dictionary作为参数, 包含两个字段:

  • view(字符串)(可选)要呈现的视图的名称。接受“default”(默认)“leaderboards”(排行榜)“achievements”(成就)“challenges”(挑战)。默认为“default”。

  • leaderboard_name(字符串)(可选)要显示的排行榜的名称。仅在“view”为“leaderboards”(或“default”被配置为显示排行榜)时使用。如果未指定,Game Center 将显示聚合排行榜。

示例:

  1. var result = show_game_center({ "view": "leaderboards", "leaderboard_name": "best_time_leaderboard" })
  2. var result = show_game_center({ "view": "achievements" })

响应事件

响应事件将是包含以下字段的字典:

关闭时:

  1. {
  2. "type": "show_game_center",
  3. "result": "ok",
  4. }

多平台游戏

在开发多平台游戏时,您不会总是使用“GameCenter”单例(例如在 PC 或 Android 上运行时)。 因为 GDScript 编译器在编译时查找单例,所以不能只查询单例以查看和使用条件块中需要的内容,还需要将它们定义为有效标识符(局部变量或类成员)。 这是一个如何在类中解决此问题的示例:

  1. var GameCenter = null # define it as a class member
  2. func post_score(score):
  3. if GameCenter == null:
  4. return
  5. GameCenter.post_score({ "value": score, "category": "my_leaderboard" })
  6. func check_events():
  7. while GameCenter.get_pending_event_count() > 0:
  8. # do something with events here
  9. pass
  10. func _ready():
  11. # check if the singleton exists
  12. if Globals.has_singleton("GameCenter"):
  13. GameCenter = Globals.get_singleton("GameCenter")
  14. # connect your timer here to the "check_events" function