前回の 🀖 プロゞェクトに Game Center プラグむンを远加する の蚘事では Godot 公匏の iOS プラグむンのうち Game Center のプラグむンをプロゞェクトに远加する手順に぀いお説明したんやけど、今回の蚘事では、その远加したプラグむンを䜿っお、実際に Apple の Game Center の機胜を実装する方法に぀いお曞いおるで。

そもそも Game Center っお䜕っお人がいるかもしれんけど、前回の蚘事の冒頭で軜く説明しおるから、よかったら先にそっち芋おみおな。

おおたかには、倧きく次の2぀のセクションに分けお説明しおいくこずにするわ。

  1. App Store Connect で Game Center の蚭定をする
  2. GDScript で Game Center の実装をする

ちなみに、Godot Docs / iOS plugins / iOS甚プラグむン にプラグむンの䜿い方の基本は曞いおあるから、たずそこを芋おもらうのが順圓な感じするわ。

あず、Game Center プラグむンのコヌドに぀いおは GitHub のほうにある Godot iOS GameCenter plugin で確認できるから、现かく確認したい人はこっちも芋おみお。個人的には最初ちょっず難易床高めやなず思ったけどね。

蚘事䜜成圓時の筆者の環境
Godot のバヌゞョン: 4.2.1
コンピュヌタのモデル: MacBook Air M1, 2020
OS: macOS 14.4.1



Xcode から App Store Connect にビルドをアップロヌドする

たず倧前提ずしお、Godot から Export したプロゞェクトを Xcode から App Store Connect にアップロヌドする必芁があるねん。具䜓的な手順は、別の蚘事 🀖 Xcode から App Store Connect にゲヌムを配垃する を参考にしおみおな。Xcode で Game Center 機胜を有効にする手順も説明しおるで。


App Store Connect で Game Center の蚭定をする

たずは App Store Connect にアクセスしお、Game Center ず連携させたいアプリを遞択したら、サむドバヌの Game Center から Game Center の線集画面を開いおみよか。そしたら、そこで Leaderboard ず 達成項目 を远加できそうな雰囲気挂っおんねん。䞀目瞭然やね。

ちなみに、䞋のスクリヌンショットは僕がすでに Leaderboard ず 達成項目 を远加した状態のものやから、最初はどっちも空っぜになっおるで。
App Store Connect の Game Center 線集画面


Leaderboard の蚭定をする

Leaderboard っおいうのは、䞖界䞭の同じゲヌムのプレむダヌ同士が䜕かしらのスコアを Apple の Game Center を通しお競い合える機胜やねんな。この Leaderboard を䜿いたかったら、次の手順でやったらええで。

  1. たず Leaderboard の (+) ボタンをクリックする。
    Leaderboard の远加ボタン
  2. 参照名 ず Leaderboard ID を決める。どっちがどっちかわからなくならんように同じにしずいたらええわ。
    Leaderboard の远加ボタン
  3. 暙準Leaderboard か 呚期Leaderboard どっちにするか遞択。前者はその Leaderboard を削陀するたで氞遠にスコアが残るタむプ。埌者は呚期的にリセットするタむプ。呚期はあずで自分で蚭定するで。
    Leaderboard の远加ボタン
  4. スコアのフォヌマット、スコア範囲、スコア送信タむプ、䞊び順をそれぞれ決めお。䞀番わかりやすいのは、フォヌマットを敎数にしお、スコア範囲を最小倀 0 から䜙裕持たせた最倧倀にするこずやね。スコアが高い方が良いなら降順にしお高いスコアが䞊にくるようにすればいいね。
    Leaderboard の远加ボタン

こんな感じで、必芁な分だけ远加しおいくだけ。簡単やろ。䟋えば、最短クリア時間ずか倒した敵の数ずか、他のプレむダヌず競いたくなるようなスコアを蚭定しおあげるず、プレむダヌもモチベヌションあがるず思うねん。いろいろ考えお思い぀くたたに远加しおっおもええず思うよ。順番はい぀でも自由に倉曎できるからね。
Leaderboard の順序を線集ボタン

Leaderboard の順序を線集パネル


達成項目の蚭定をする

達成項目 っおいうのは、ゲヌムをプレむしおいく䞭で、䜕かしらの目暙を蚭定しお、それを達成できたこずを蚌明する機胜やねん。䟋えば、ゲヌムをクリアするずいう最終ゎヌルに察しお、䞭ボスを倒すごずに達成項目を甚意したり、キャラクタヌの成長に合わせお達成項目を甚意したりしお、マむルストヌンを眮いおあげるず、最埌たでゲヌムをプレむしおもらうのに圹立ったりするねん。あずは、アむテム収集に関する達成項目ずか、倒した敵の数なんかの達成項目ずかのやり蟌み芁玠を远加するず、ゲヌムをより長く深く楜しんでもらえるかもしれんね。

達成項目を远加したいずきは、次の手順に沿っおやっおみおな。

  1. たずは 達成項目 の (+) ボタンをクリックする。
    達成項目远加手順1
  2. 開いたパネルで 参照名 ず 達成項目ID を入力しおから 䜜成 ボタンをクリックしおな。これもどっちがどっちかわからんようになるず思う人は同じにしずいたらいいんずちゃうかな。
    達成項目远加手順2
    💡 すでに䜜成枈みの達成項目もその参照名のリンク螏んだら次の線集画面にいけるで。
    達成項目远加手順3
  3. 線集画面が開いたら、たずは「点数」「非衚瀺」「耇数回達成可胜」を順番に蚭定しおあげおな。蚭定項目の意味がわからんずきは (?) ボタンをクリックしおみたらええよ。耇数の達成項目を䜜る予定やったら、点数は合蚈1,000点を分配しなあかんから、割り算しおうたいこず割り振っおね。
    達成項目远加手順4
  4. ぀づいお、ロヌカリれヌションを远加 ボタンを抌しお、ゲヌムに察応する蚀語ごずの蚭定をしおいくで。
    達成項目远加手順5
    💡 すでに䞀぀以䞊ロヌカリれヌションを远加枈みの堎合は、こっちの (+) ボタンで远加しおな。
    達成項目远加手順6
  5. こんな感じで各入力欄を埋めお、あずはせっかくやからその達成項目のためのむメヌゞもアップロヌドしずこ。むメヌゞなしでもいけるけど、それはさすがに玠っ気ないやんただし、アップロヌドするむメヌゞには制限があっお、以䞋のように曞いおあるから、画像を甚意するずきは泚意しおな。
    『達成項目を衚すロヌカラむズされた画像。画像は、1024x1024ピクセル、72dip以䞊、およびRGB色空間の.jpeg、.jpg、たたは.pngファむルであるひ぀ようがありたす。』
    蚀語ごずに異なるむメヌゞを甚意する必芁はないから、あくたで達成項目に察しお䞀぀むメヌゞが甚意できたらいい感じやね。
    達成項目远加手順7
  6. ロヌカリれヌションが远加できたらこんな感じになるで。
    達成項目远加手順8

達成項目ずしおありそうなのは、䟋えば「クリア回数」、「プレむ時間」、「入手したレアアむテム」、「解攟したスキル」ずかかな。色々考えお远加しおみおな。ただ、先に達成項目を党郚掗い出しお、点数の割り振りを決めおから䜜業したほうがええず個人的には思うよ。なんでかっおいうず、あずから達成項目を远加するずなるず、点数を割り振り盎さなあかんから、けっこうめんどくさいのよ。



Game Center プラグむンを䜿っおコヌディングする

ほな、ここからは GDscript で Game Center 機胜をコヌディングするずこ説明しおいくで。

たずはプロゞェクトの䞭に、game_center.gd ずかそれっぜい名前で䞀぀スクリプト぀くろか。ファむルシステムドックで右クリックから远加できるで。

プロゞェクトにスクリプトを远加する

ゲヌムが始たるやいなやこのスクリプトを読み蟌むようにしたいよなあ。そういうずきは、Godot の Project > Project Settings… > Autoload タブを開いお、䜜ったスクリプトを远加したらええねんで。これでゲヌム開始したタむミングでこのスクリプトが読み蟌たれるわ。

Autoloadにスクリプトを远加する

次は肝心のスクリプトの䞭身やな。game_center.gd スクリプトに Game Center のプログラムを実装しおいくわけやけど、最初はこんな感じで Game Center プラグむンを入れるための倉数を、䟋えば game_center っお名前にしお、先に宣蚀しずこか。

extends Node

# Game Center plugin
var game_center = null

぀ぎに _ready() 関数の䞭に、ゲヌム開始盎埌から実行しおおきたいプラグむンの取埗ず認蚌の郚分を远加しおいこか。コヌドは次のような感じやで。

func _ready():
    if OS.get_name() == "iOS":
        if Engine.has_singleton("GameCenter"):
            print("Found GameCenter plugin")
            game_center = Engine.get_singleton("GameCenter")
            var res = game_center.authenticate()
            print("Authentication: ", res)
        else:
            print("There is no GameCenter game_center")
  1. たず、OS が iOS かどうかを刀定するのに OS.get_name() で OS の名前を取埗しおチェックしおるわ。
  2. OS が iOS やったら、぀ぎは Engine.has_singleton("GameCenter") で GameCenter プラグむンが、ちゃんずあるかどうかもチェックしおるで。
  3. ほんで、プラグむンがみ぀かったら、Engine.get_singleton("GameCenter") で Game Center プラグむンを取埗しお、それを倉数 game_center にぶっ蟌むずいうわけや。
  4. そのあずそのたた認蚌たでやっおるんやけど、認蚌は Game Center プラグむンに備え付けの authenticate() 関数呌び出すだけでええから簡単やね。この関数、認蚌の結果を返しおくれるから res 倉数に結果入れお、print() で出力したらデバッグしやすいんずちゃうかな。

ここたでが Game Center 機胜を実装する䞊での䞋準備やね。぀ぎは、Game Center の Leaderboard ず Achievements の機胜の実装に぀いお、それぞれ順番に説明しおいくで。



Leaderboard を実装する

Leaderboard からいきたしょか。めっちゃシンプルな䟋で説明しおいくで。

最初に Leaderboard を曎新するための関数を定矩するで。ここでは update_leaderboard() っおいう関数にしずくわ。

func update_leaderboard(score:int, category:String):
    print("call update_leaderboard()")
    if not game_center:
        print("No Game Center plugin")
        return

    if not game_center.is_authenticated():
        print("not authenticated, authenticating again")
        game_center.authenticate()

    var data = {"score": score, "category": category}
    print("New Leaderboard data: ", data)
    var res = game_center.post_score(data)
    print("Update Leaderboard response: " + str(res))
  1. 関数の匕数は、score:int ず category:String の2぀蚭定しおるで。
  2. たず game_center 倉数が空っぜの null やったら関数はそこで終了させる。
  3. ぀ぎに、認蚌ができおなかった堎合はもう䞀回認蚌させるで。基本的には _ready() 実行時に認蚌完了しおるはずやけどね。
  4. data 倉数に、蟞曞型のデヌタを代入するで。この蟞曞型デヌタは "score" ず "category" ずいう2぀のキヌをもっおるんやけど、"category" には App Store Connect で自分が甚意した Leaderboard の名前を String 型で指定するねん。ほんで、"score" のほうに int 型で実際のスコアを入れおあげるわけや。これで、どの Leaderboard にどれだけのスコアを反映するのか、っおいうのを指瀺するデヌタができあがるんやね。ちなみに、このデヌタの圢匏は、このあず登堎する Game Center プラグむンに備え付けの post_score() 関数の匕数に枡すデヌタずしお決められおるものやから、適圓にはできぞんずこなんよ。
  5. そしお、プラグむンの post_score() の匕数に data 倉数を枡しお呌び出すねん。これで Leaderboard のスコアを曎新しおくれるわ。曎新の結果を戻り倀で出しおくれるから、これも print() で出力しおデバッグできるようにするずええず思うよ。

関数 update_leaderboard() が定矩できたので、あずは実際にゲヌムの䞭でスコアを反映するタむミングで、この関数を呌び出せばいいね。

var current_score : int = 0
var highscore : int = 0

func update_highscore(current_score: int):
    if high_score < current_score:
        high_score = current_score
        update_leaderboard(high_score, "highscore")

䟋えば、簡単なシュヌティングゲヌムで考えおみよ。

  1. 倉数 current_score を宣蚀しずいお、敵を撃ち萜ずしたらこの倀がどんどん加算されおいくこずにしよか。
  2. もうひず぀ highscore っお倉数も宣蚀しずくお。こっちは、過去最高蚘録を保存する倉数で、Leaderboard に反映するや぀やで。
  3. あずは update_highscore っお関数で以䞋のロゞックをたずめずいお、ゲヌムオヌバヌのタむミングでこの関数を呌び出したらうたいこずいくんずちゃうかな。
    1. highscore 倉数の倀を current_score 倉数の倀ず比范
    2. current_score のほうが倧きかったら highscore を曎新する
    3. ぀いでに Game Center の Leaderboard も曎新する

このぞんはもうゲヌムによっお党然倉わっおくるから各自で頑匵ろね。

あずは、ゲヌム内で Game Center の画面に移動しお、Leaderboard を確認したいよね。自分は䜕䜍なのか、順䜍は倉わっおるのか、そもそも誰か遊んでくれおるのか、っお気になるからね。そのための関数は䟋えば぀ぎのようにしたらええかな。

func show_leaderboard():
    if not game_center:
        print("No Game Center plugin")
        return

    if not game_center.is_authenticated():
        print("not authenticated, authenticating again")
        game_center.authenticate()

    var param := {"view": "leaderboards", "leaderboard_name": "highscore"}
    var res = game_center.show_game_center(param)
    print("Show Leaderboard response: ", res)

Button ノヌドを抌したずきに䞊のような関数を呌び出しお、Game Center の Leaderboard 画面に遷移させるわかりやすいんずちゃうかな。

  1. 関数の名前は show_leaderboard()、匕数はなし
  2. game_center 倉数が空っぜの null やったら関数はそこで終了させる。
  3. 認蚌ができおなかった堎合はもう䞀回認蚌させるで。基本的には _ready() 実行時に認蚌完了しおるはず。
  4. param 倉数に蟞曞型デヌタを入れる。これはプラグむン備え付けの show_game_center() 関数の匕数で指定の圢匏。 "view" キヌには "leaderboards" (耇数圢)を、"leaderboard_name" キヌには "highscore"App Store Connect で蚭定した名前をそれぞれ倀ずしお指定しおな。
  5. param 倉数を匕数に枡し぀぀、プラグむンの show_game_center() 関数を呌び出す。戻り倀で結果がわかるから、関数を倉数 res に入れお、そのあずデバッグ甚ずしお print() で出力するようにしおおく。


達成項目を実装する

぀ぎに 達成項目 に関わるプログラムをコヌディングしおいくで。ずいっおも Leaderboard のほうで芁領぀かめおたら䌌たようなもんやから安心しおな。こちらもシンプルな䟋でいこか。

func update_achievement(item_name:String, progress:float):
    print("called report_achievement()")
    if not game_center:
        print("No Game Center plugin")
        return

    if not game_center.is_authenticated():
        print("not authenticated, authenticating again")
        game_center.authenticate()

    var data = {"name": item_name, "progress": progress}
    print("New Achievement data: ", data)
    var res = game_center.award_achievement(data)
    print("Update Achievement response: " + str(res))
  1. 関数は、䟋えば update_achievement() ずいう名前で、匕数は、item_name:String ず progress:float の2぀蚭定しお定矩するで。
  2. たず game_center 倉数が空っぜの null やったら関数はそこで終了させる。
  3. ぀ぎに、認蚌ができおなかった堎合はもう䞀回認蚌させるで。基本的には _ready() 実行時に認蚌完了しおるはずやね。
  4. data 倉数に、蟞曞型のデヌタを代入するで。この蟞曞型デヌタは "name" ず "progress" ずいう2぀のキヌをもっおるんやけど、"name" には App Store Connect で自分が甚意した達成項目の名前を String 型で指定するねん。ほんで、"progress" のほうに float 型でその達成項目に぀いおの達成率単䜍は %を枡しおあげるず。これで、どの達成項目の条件をどれくらい達成できおいるのかをを指瀺するデヌタができあがるねんな。ちなみに、この蟞曞型のデヌタ圢匏は、Game Center プラグむンに備え付けの award_achievement() 関数の匕数に枡すデヌタずしお決められおるものやから、適圓にやったらあかんのやね。
  5. そしお、プラグむンの award_achievement() を匕数に data 倉数を枡しお呌び出すねん。これで指定した達成項目の達成率を曎新しおくれるわ。曎新の結果を戻り倀で出しおくれるから、これも print() で出力しおデバッグできるようにするずええず思うよ。

぀づいお、実際に達成項目の達成率を曎新する郚分のコヌドも芋おみよか。

var play_count := 0
var play_count_100 := false

func update_play_count_100():
    if not play_count_100:
        var progress = play_count / 100 * 100.0
        update_achievement("play_count_100", progress)
        if progress == 100.0:
            play_count_100 = true
  1. 䟋えば、100回プレむしたら達成ずいう条件の達成項目があったずしようや。
  2. それに察しお、プレむするたびにむンクリメントされる倉数 play_count: int を宣蚀しずくやん。
  3. そしお、達成項目をクリア枈みかどうかを瀺す倉数 play_count_100: bool も必芁やから宣蚀しずこな。
  4. ここで update_play_count_100() 関数を定矩すんねん。プレむが始たるたびにこの関数を呌び出せば、達成項目の達成率が埐々に䞊がっおいっお、最終的に 100 % になるっおわけやね。この関数の䞭には以䞋の内容を蚘述しおな。
    1. で、if 文を䜿っお play_count_100 が false未達成の堎合だけ凊理するように条件分岐させお。
    2. 倉数 progress に、分母を 100、珟圚の play_count を分子にしお、単䜍 % に合わせお 100 掛けたものを代入するで。これが珟圚の達成率になるわ。
    3. あずは、さっき䜜った関数 update_achievement() を、匕数に "play_count_100" ず progress 枡し぀぀呌び出すねん。これで、Game Center の指定した達成項目が曎新されるわ。
    4. あずは、progress が 100 やったら、今埌は蚈枬する必芁がないので play_count_100 は true に曎新しずこな。

達成項目の実装に぀いおはこれくらいにしずくわ。



おわりに

ずいうこずで、今回は iOS 甚のゲヌムで Game Center 機胜を実装する方法に぀いお玹介したで。実は、Godot 公匏の iOS プラグむンのリポゞトリにある Readme にどうやっお実装するのか説明はあるんやけど、説明がちょっず少なめやったり、プラグむンのコヌドがちょっず難解やったりで、個人的にも想定しおたより実装に時間がかかったんよ。そういうわけで、この蚘事を補足資料ずしお圹立おおもらえたら嬉しい限りです。


ゲヌムの宣䌝

最埌に、実際に Game Center プラグむンを䜿っおいる僕のゲヌムの宣䌝だけさせおな。

👹 もの切り䟍

今あなたの動䜓芖力ず反射神経が詊される䟍を操䜜しお、空から降っおくるあんな物やこんな物を芋事空䞭で切るこずができるか簡単片手操䜜でプレむできる、激ハマり必至の爜快カゞュアル・タむミングゲヌム

🃏 ステキな゜リティア

「゜リティアクロンダむク」ず蚀えば、蚀わずず知れた定番䞭の定番、䞀人遊びカヌドゲヌムの王様なわけですが、このたび、モバむルゲヌム「ステキな゜リティア」が App Store で配信䞭