Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Cocos2d-xの深層〜Cocos2d-x組み込みによるピュアAndroid/iOSアプリの...

 Cocos2d-xの深層〜Cocos2d-x組み込みによるピュアAndroid/iOSアプリの外科手術的統合

2016年8月24日パシフィコ横浜にて開催されたCEDEC 2016での久富木隆一による講演の資料です。
http://cedec.cesa.or.jp/2016/session/ENG/3462.html
ピュアJavaまたはObjective-Cで別個に開発されたAndroid/iOS各プラットフォーム向けクライアントコードベースを、Cocos2d-xへの単純移植ではなく、既存アプリへのプラグインのようにCocos2d-x自体をまるごと組み込むこと(embed)により、移行のコストとリスクを最小限に抑制しつつ統合してゆく手法をご紹介いたします。

Avatar for Ryuichi Kubuki

Ryuichi Kubuki

September 13, 2023
Tweet

More Decks by Ryuichi Kubuki

Other Decks in Programming

Transcript

  1. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-xの深層 2016/08/24 @

    CEDEC 2016 久富⽊ 隆⼀ (KUBUKI Ryuichi) Cocos2d-x組み込みによる ピュアAndroid/iOSアプリの 外科⼿術的統合
  2. Copyright © GREE, Inc. All Rights Reserved. 本⽇お話する内容 2 1. 

    ⾃⼰紹介 2.  前提の共有: Cocos2d-xとは何か 3.  Android/iOSクライアント統合という問題 -  2-1. 問題の状況と⽬指すべきゴール -  2-2. 統合案の検討と採⽤案 4.  Cocos2d-x組み込みによるクライアント統合 -  3-1. Android/iOSアプリの構造 -  3-2. Cocos2d-xのAndroid/iOS実装の構造 -  3-3. Cocos2d-x組み込みの技術的詳細 -  3-4. これからのCocos2d-x 5.  総括
  3. Copyright © GREE, Inc. All Rights Reserved. ⾃⼰紹介 3 • 久富⽊

    隆⼀ (KUBUKI Ryuichi) • グリー株式会社 • West Game事業本部 GREE International Entertainment(⽶国サ ンフランシスコ)等、海外ゲーム事業を担当
  4. Copyright © GREE, Inc. All Rights Reserved. ⾃⼰紹介 4 Crime

    City •  Android / iOS •  2011- •  Over tens of millions download globally Modern War •  Android / iOS •  2011- •  Over tens of millions download globally
  5. Copyright © GREE, Inc. All Rights Reserved. ⾃⼰紹介 5 • 久富⽊

    隆⼀ (KUBUKI Ryuichi) Twitter: @ryukbk 『ゲームアプリの数学 Unityで学ぶ基礎からシェーダーまで』 (SBクリエイティブ刊) •  リアルタイム3Dグラフィックスを成 り⽴たせている数学要素をUnityサン プルプロジェクト付きで解説 •  OpenGL ESレンダリングパイプライ ンやGPUアーキテクチャー、モバイ ル向け最適化も紹介
  6. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-xとは何か 6 • 

    Cocos2d •  iOS向けの2Dゲームエンジン(Objective-C, Ricardo Quesada, 2008) •  Cocos2d-x •  Cocos2dのAPIを保持しつつAndroid/ Windows向けに移植(C++, Zhe Wang, 2010) •  Cocos2d-xの現在 •  Cocos2d作者も合流した主流となり、APIを独 ⾃発展。中国Chukong Technologiesを主な ⽀援者としてオープンソース開発中
  7. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-xとは何か 7 • 

    Cocos2d-xは完全にオープンソース •  Unityは完全にオープンソースではない •  Cocos2d-xは完全無料 •  Unity、Unreal Engineは有料 メリット デメリット •  Cocos2d-xにはベンダーサポートはない(コミュ ニティはある) •  3Dや開発環境など発展途上
  8. Copyright © GREE, Inc. All Rights Reserved. Android/iOSクライアント統合という問題 8 Crime

    City •  Android / iOS •  2011- Modern War •  Android / iOS •  2011- •  iOS/Androidクライアントを、別々のチーム がそれぞれ独⽴して開発(ピュアObj-C/Java) •  通信するサーバー、スタティックデータ(マ スターデータ)は共通 •  それ以外(ビュー/UI、ロジック)は全てプ ラットフォーム別に独⾃実装 状況把握
  9. Copyright © GREE, Inc. All Rights Reserved. Android/iOSクライアント統合という問題 9 • 問題1:

    同じゲームの複数の実装 • ⾞輪の再発明 • Android/iOS開発者が別個にい るためヘッドカウントが2倍 • Android/iOS実装間での⾒た⽬ や挙動の差異
  10. Copyright © GREE, Inc. All Rights Reserved. Android/iOSクライアント統合という問題 10 • 問題2:

    データ駆動ではないデザイ ンパイプライン • エンジニアがUIやアニメーショ ンの調整を実施 • エンジニアがステート遷移を コードで実装 • スタティックデータの変更以外 エンジニアの助⼒なしに⾏えな い
  11. Copyright © GREE, Inc. All Rights Reserved. Android/iOSクライアント統合という問題 11 • 

    問題3: 将来にわたって安⼼(future-proof) ではないレガシーアーキテクチャー •  描画がOpenGL ES 1.1に留まる •  新OSバージョンへの対応コスト •  3D、パーティクル、物理、AIなどゲー ムデザインに影響を与える技術要素の追 加困難 •  Objective-CはSwiftに取って代わられる •  開発者を探しにくい
  12. Copyright © GREE, Inc. All Rights Reserved. Android/iOSクライアント統合という問題 12 1. 

    同じゲームの複数の実装 2.  データ駆動ではないデザイ ンパイプライン 3.  将来にわたって安⼼ (future-proof)ではないレ ガシーアーキテクチャー 問題
  13. Copyright © GREE, Inc. All Rights Reserved. Android/iOSクライアント統合という問題 14 1. 

    単⼀の実装への統合 •  Write Once, Run Everywhere •  ユニットテスト/テスト⾃動化が楽 2.  データ駆動デザインパイプライン •  エンジニアリングリソースがボトルネックと ならない 3.  将来にわたって安⼼(future-proof)なアー キテクチャー •  ⼀般的なゲームエンジンの最新版を利⽤ •  既に流通しているソフトウェアコンポーネン トの再利⽤ ゴール
  14. Copyright © GREE, Inc. All Rights Reserved. Android/iOSクライアント統合という問題 15 1. なるべく早期のローンチを

    2. なるべく移⾏をスムースに 3. なるべく低い⾦銭的コストで 4. なるべく低い開発者教育コストで 5. サーバーとスタティックデータは 現在のものを流⽤ 6. オリジナルの⾒た⽬を踏襲 現実的な追加要件
  15. Copyright © GREE, Inc. All Rights Reserved. Android/iOSクライアント統合という問題 16 1. 保守的な案

    •  現実的、低リスク、地味、 コード駆動、旧式 2. ⾰新的な案 •  理想的、⾼リスク、派⼿、 データ駆動、モダン 2つの案
  16. Copyright © GREE, Inc. All Rights Reserved. Android/iOSクライアント統合という問題 17 • 

    今回のゲーム(既存アプリ)内に、スク リプトエンジン等を組み込むのと同様 に、Cocos2d-xゲームエンジンをまる ごと組み込み(embed) •  新フィーチャーのみCocos2d-xで開発 •  既存アプリのコードを原則再利⽤し、 必要に応じてCocos2d-x部分へ漸次移 植 保守的な案
  17. Copyright © GREE, Inc. All Rights Reserved. Android/iOSクライアント統合という問題 18 1. 

    単⼀の実装への統合 •  C++でAndroid/iOS向けに実装できる •  ただし既存アプリ部分とのブリッジAPIを実装 するコードは複雑になる •  ただし既存コード(Obj-C/Java)のメインテナ ンスは必要 2.  データ駆動デザインパイプライン •  Cocos Studio/Cocos Creatorが使える 3.  将来にわたって安⼼(future-proof)なアー キテクチャー •  最新のオープンソースゲームエンジン 保守的な案(Cocos2d-x組み込み)
  18. Copyright © GREE, Inc. All Rights Reserved. Android/iOSクライアント統合という問題 19 • 

    Unityへ移植 •  現在のサーバー&スタティックデータ &アセットデータとの互換性を持つク リーン実装 •  課⾦や通知など再実装/再検証コスト が⾼い部分のみ既存アプリ実装をネイ ティブプラグイン化して再利⽤ •  データ駆動デザインを促進するUnity アセットの利⽤ ⾰新的な案
  19. Copyright © GREE, Inc. All Rights Reserved. Android/iOSクライアント統合という問題 20 1. 

    単⼀の実装への統合 •  C#でAndroid/iOS向けに実装できる 2.  データ駆動デザインパイプライン •  Unity Editor中⼼の開発 •  MarkUX: XMLによるMVVMでUI作成 •  NodeCanvas: Behaviour TreeやHierarchical State Machineで状態遷移作成 3.  将来にわたって安⼼(future-proof)なアー キテクチャー •  最新のトレンドを押さえたゲームエンジン ⾰新的な案(Unity移植)
  20. Copyright © GREE, Inc. All Rights Reserved. Android/iOSクライアント統合という問題 21 • 

    保守的な案(Cocos2d-x組み込み)と ⾰新的な案(Unity移植)を3つのゴー ルの達成度で⽐較した場合、⾰新的 な案の⽅が優位となった •  しかし、追加的要件も勘案すると、 保守的な案(Cocos2d-x組み込み)が 優位となったため、今回はそちらを 採⽤した 採⽤案
  21. Copyright © GREE, Inc. All Rights Reserved. Android/iOSクライアント統合という問題 22 1. 

    なるべく早期のローンチを 2.  なるべく移⾏をスムースに 3.  なるべく低い⾦銭的コストで 4.  なるべく低い開発者教育コストで 5.  サーバーとスタティックデータは現在のものを 流⽤ 6.  オリジナルの⾒た⽬を踏襲 Cocos2d-x組み込みはこれらの要件を満たす 1: (Cocos2d-x組み込みの技術さえ確⽴できれば)移植より早く済む。 2/5/6: 既存部分の流⽤が多いので問題が少ない。 3: Cocos2d-xは無料である。 4: 偶然今回のプロジェクトチームではCocos2d-x経験者が多かったので 問題とならなかった。
  22. Copyright © GREE, Inc. All Rights Reserved. Android/iOSクライアント統合という問題 23 • 

    Unityのネイティブプラグインは独 ⾃描画を⾏えるため、既存アプリ部 分をまるごとネイティブプラグイン 化することも考えられる •  しかし、Unity側に変更を加える必 要が出てくる可能性、既存アプリ部 分のビルドシステムとの親和性を考 え、今回は⾒送った Unityへの既存アプリの組み込みはできないのか
  23. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 24 • 

    いきなり実装の詳細に⼊って⾏く前に、全体の ⼤まかな構造をイメージし、何ができそうかを 構想してみよう •  Cocos2d-x組み込みを思いついたのは、 Cocos2d-xの内部実装に⾃分が通暁していたか らではなく、⼀般的なアプリを構成するゲーム エンジンなら必ず⼀定の構造を内包しているは ずなのでそれを再利⽤してやればよい、という 想定が⾃分の中にあったから •  ソースコードがある以上どうにでもなるという 楽観があった(OSの仕様に阻まれないかぎりは) 実装の詳細を追う前に
  24. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 25 • 

    単純化して考えると、アプリは4つの要 素から成⽴している 1.  イベントループ 2.  ロジック 3.  GLビュー 4.  ネイティブUIウィジェットビュー アプリの抽象的構造
  25. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 26 • 

    常に動作しているイベントループが必要に応じて 異なるユーザー定義ロジック(Java/Obj-C)を実⾏ •  結果を、ネイティブUIウィジェットビュー(OS固 有のダイアログなどのUIウィジェット表⽰)、また はアプリが独⾃にOpenGL ESでカスタム描画する GLビューへ出⼒ アプリの抽象的構造
  26. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 27 • 

    常に動作しているイベントループが必要 に応じて異なるユーザー定義ロジック(C ++)を実⾏し、実⾏結果を、アプリが独 ⾃にOpenGL ESで描画するGLビューへ 反映 Cocos2d-xの抽象的構造
  27. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 28 • 

    Cocos2d-xのGLビューが最前⾯に描 画される Cocos2d-xを組み込んだアプリ構造の完成形
  28. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 29 • 

    UIView(とCALayer)の階層にGLビューを含む全 てのビューは属する •  Objective-C⾔語は、ファイル拡張⼦を.mか ら.mmにするとObjective-C++としてCだけで はなくC++コードを混ぜることができる •  Obj-Cの世界とC++の世界のメモリ空間は単⼀ •  Obj-C - C++ - Obj-CまたはC++ - Obj-C - C ++の呼び出しとコールバック実⾏による処理継 続は、同期で、同じスタックフレーム上で起こ る •  メタファー: iOSアプリの世界は、モノリシック (⼀枚岩)な世界である iOSアプリの特性
  29. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 30 • 

    1つのアプリが複数のActivityを内包する •  Activityは複数のFragmentを内包する •  ActivityはWindowとViewの階層を持つ •  ViewはGLビューであるGLSurfaceViewを含む •  Activity同⼠はIntentで通信しあう •  Activityが存在するJavaの世界(JVM)と、Linuxネイ ティブのC/C++の世界(NDK)のメモリ空間は、分離さ れており、越境(JNI)のコストは⾼い •  Java - C++ - JavaまたはC++ - Java - C++の呼び 出しとコールバック実⾏による処理継続は、⾮同期で、 異なるスタックフレーム/スレッド上で起こる •  メタファー: Androidの世界は、分散オブジェクト/ メッセージパッシング/疎結合マイクロサービスの世界 である Androidアプリの特性
  30. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 31 • 

    Cocos2d-x⾃⾝は、これまで⾒てきた両プラット フォームの特性を利⽤しつつ差異を吸収する形で 実装してある •  Cocos2d-xは、他アプリに組み込まれることを想 定した構造にはなっていないはず •  であれば、今回やるべきことの中⼼は2つ 1.  既存アプリとCocos2d-xとのブリッジコード を実装してやる 2.  Cocos2d-xのAndroid/iOS実装が他アプリの 存在を想定していない構造になっている部分 にパッチを適⽤(実際はほんの少しで済んだ) Cocos2d-xのAndroid/iOS実装と組み込み
  31. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 32 1. 

    (AppDelegateはstatic変数領域に起動時 ⽣成) 2.  AppController# didFinishLaunchingWithOptionsでGL ビューであるCCEAGLViewを⽣成 3.  作成したGLビューをRootViewController でビュー階層内に追加 4.  Cocos2d-x側からGLビューに描画を⾏う GLViewオブジェクトを⽣成 Cocos2d-xのiOS実装の起動フロー
  32. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 33 1. 

    Java: Cocos2dxActivityを⽣成 2.  C++: platform/android下のjavaactivity- android.cppをJNIで呼び出し、Cocos2d-xア プリケーション本体であるAppDelegateをヒー プ領域に⽣成 3.  Java: GLビューであるGLSurfaceViewを⽣成 4.  Java: Cocos2dxRendererを⽣成 5.  C++: javaactivity-android.cppを呼んで、 Cocos2d-x側からGLビューに描画を⾏う GLViewImplを⽣成 Cocos2d-xのAndroid実装の起動フロー
  33. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 34 1. 

    既存アプリ内からCocos2d-xを起動してシーンを 作成し、全画⾯/モーダルダイアログとして表⽰ •  シーン属性情報(例えばCocos2d-xダイアログの表⽰ サイズ)はJava/Obj-C側ではなくCocos2d-x側で持つ 2.  複数回表⽰を反復しても問題ないこと(冪等性) 3.  アプリ起動直後からCocos2d-xオブジェクト (AppDelegate)がC++側に存在すること 4.  パフォーマンス低下を防ぐこと(速度/占有メモ リ/占有ストレージサイズ) 5.  Cocos2d-xと既存アプリのモジュールを混在させ た単⼀バイナリを⽣成するビルドプロジェクトを 構成 Cocos2d-x組み込み要件
  34. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 35 1. 既存アプリ側からCocos2d-xを

    起動し指定したシーンを表⽰ 2. Cocos2d-xから既存アプリ側の Android/iOSネイティブ機能を クロスプラットフォームの同じ インターフェイスで利⽤するた めのAPI Cocos2d-x組み込みのために実装する機能
  35. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 36 • 

    iOSアプリの中からのCocos2d-x起動は、 Cocos2d-x⾃体のiOS実装同様に、シンプル •  Cocos2d-x起動フローと同様のGLビュー⽣成を、 既存アプリ内でCocos2d-xを起動したい場所から 呼び出すだけ •  GLビューをどの位置にどのサイズで⽣成するか という点のみ解決できればよい •  [UIScreen mainScreen].applicationFrameで取得し た画⾯サイズ(iOS 7以前はw/hが逆なので注意)と、 Cocos2d-xシーン側に設定したシーンサイズを使う •  Obj-C++なので既存アプリからCocos2d-x側の関数 を簡単に呼び出せる 組み込みCocos2d-x起動: iOS
  36. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 37 • 

    Cocos2d-xのAndroid版はActivity(Cocos2dxActivity) として実装されているため、継承したクラスを作成し 挙動をオーバーライド。「アプリ起動直後から AppDelegateがC++側に存在すること」という要件を 満たすために、起動直後に⽣成されるメインActivityと してそのクラスを指定 •  Cocos2d-xのライブラリ(libcocos2dcpp.so)をロード し、C++側のメモリ空間にAppDelegateとGLViewが ⽣成されたら、C++側からJavaのCocos2dxActivity継 承クラス側にメッセージを送り、既存アプリのActivity を起動して、既存アプリ起動プロセスを続⾏ •  既存アプリActivityの中からCocos2d-xのActivityを起 動する •  異種システム間でどのようにメッセージを送る? 組み込みCocos2d-x起動: Android
  37. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 38 • 

    Cocos2d-x側と既存アプリ側とのブリッジAPIの 仕様を考える •  iOS側はモノリシックな構造だがAndroid側は分 散・疎結合の構造。両⽅を抽象化し単⼀のAPIで 制御するためには制限が⼤きい⽅に合わせるべき •  Android側の、メモリ空間が別れた⾮同期通信 モデルを基準とする •  Cocos2d-xシーンが主体となり、離れた世界(既 存アプリ側)のリソースをC++コードで制御する ための、RPC(remote procedure call:遠隔関数 呼出)の仕組みが要る Cocos2d-x側と既存アプリの通信
  38. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 39 • 

    Android •  JNI(Java Native Interface)で通信 •  API呼び出し時にstd::function/ラムダ式のコール バックを、boost::uuidで⽣成したUUIDをキーとして マップへ登録。既存アプリ側は受け取っていたUUID を返事を返す際に添えて返し、Cocos2d-x側は対応 コールバックを実⾏ •  iOS •  Cocos2d-x -> 既存アプリ: Obj-C++のファイルにC の関数を定義し、externで参照し呼び出し •  既存アプリ -> Cocos2d-x: std::functionで渡された コールバック関数を直接実⾏ Cocos2d-x側から既存アプリへのRPC
  39. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 40 • 

    宣⾔: std::functionにコールバックとしてラムダ式を設定する Cocos2d-x側から既存アプリへのRPC •  実⾏: サーバーから返事が来るとラムダ式が実⾏される
  40. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 41 • 

    iOS •  同じメモリー空間でC/C++の型が共通で存在してい るのでデータ型の問題は存在しない •  Android •  C++とJavaの世界でデータを翻訳/交換するための合 意が必要 •  任意のデータをペイロードとしてラップし変換/交換 (marshalling)するための便利なバッグがあればよい •  今回使ったもの •  boost::variant using VariantValueType = boost::variant<int64_t, double, std::string>; •  JSON (rapidjson::Document) RPCとデータ型
  41. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 42 • 

    既存アプリ側から⽂字列でCocos2d-xシーンを指定したい •  まずは可変⻑テンプレート引数を取れるC++テンプレー ト(Variadic Templates)を使って、型リストの要素各々に 対してラムダ式を適⽤できるforEachを定義 ⽂字列とデータ型の関連付け
  42. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 43 • 

    登録しておいたシーンクラスのリストの要素に対し、RTTI のtypeidで取得した型名⽂字列をabi::__cxa_demangle でデマングルし、そのCocos2d-xシーンを作成する Scene::create関数のラムダ式と関連付け(ラムダ引数の autoはC++14) ⽂字列とデータ型の関連付け
  43. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 44 • 

    単にデータのやり取りをするだけでなく、 既存アプリ側の特定メソッドを実⾏するAPI が必要になった •  各プラットフォームのリフレクションの仕 組みが使える •  iOS •  NSInvocation#invoke •  Android •  Method#invoke ⽂字列とコードの関連付け
  44. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 45 1. 

    既存アプリ側からCocos2d-xを起動し指定した シーンを表⽰ 2.  Cocos2d-xから既存アプリ側のAndroid/iOSネイ ティブ機能をクロスプラットフォームの同じイン ターフェイスで利⽤するためのAPI •  これらの要素が最低限あればアプリ⾃体は Cocos2d-xを組み込んだ状態で動くように なっているが、実際にはそのアプリをビル ドするためのプロジェクトを整備しなけれ ばならない Cocos2d-x組み込みアプリのビルド
  45. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 46 • 

    iOS •  既存アプリのXcodeプロジェクトにCocos2d-xの Xcodeプロジェクトcocos2d_libs.xcodeprojを⼊れる •  ただしXcodeプロジェクトのマージが難しいので Cocos2d-xバージョンアップのたびに同じ作業が必要 •  Android •  既存アプリがモジュラーなgradleビルドシステムを採 ⽤していたので、Cocos2d-xのAndroid Studio向けプ ロジェクトをgradleモジュールとして差し込むことが できる •  ただしC++部分はcocosコマンドでビルドする必要が ある •  Android Studio 2のInstant Runとは相性が悪い Cocos2d-x組み込みアプリのビルド
  46. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 47 • 

    Cocos2d-xのビューを、全画⾯ではなく画⾯の1部に表⽰ •  矩形ではなく、丸みのある⾓など⾃由な形状に •  フレームバッファーをアルファ値を持てるフォーマット にする •  iOS •  CCEAGLViewでeaglLayer.opaque = NO、 pixelFormatをkEAGLColorFormatRGBA8に •  AndroidはそのままでOK •  Cocos2d-x側でそもそも⿊く塗りつぶしていたので透明 に替える •  FrameBufferで_clearColor(Color4F(0, 0, 0, 0))、 Rendererで_clearColor.a = 0.0f Cocos2d-xシーンのモーダルダイアログ表⽰
  47. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 48 • 

    Cocos2d-xのActivityを表⽰していると、背後に回った既 存アプリのActivityがOSによって制御できないタイミン グでkillされてしまう トラブルシューティング: Android Activity問題 •  AndroidManifestで @android:style/ Theme.Translucent.N oTitleBar.Fullscreenを 指定し背後の既存アプ リActivityが⾒えるよ うにしてやればkillされ ない(全画⾯表⽰でも)
  48. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 49 • 

    HTC J Butterfly(HTV31)上でのリリースビルドのみで、 OpenGL ESのコンテクストがおかしいことによるエラー が起こる(call to OpenGL ES API with no current context) •  Cocos2d-xのAPIを操作しOpenGL ESコンテクストを操 作する可能性のあるJNI呼び出しは、全て GLSurfaceView.queueEvent経由の呼び出しとして Cocos2d-x描画⽤スレッドで実⾏されるように •  逆に、Androidのビュー階層をJNIから操作する場合は Handler(Looper.getMainLooper())でUIスレッドにポス ト •  Cocos2d-x側では、AndroidからJNIで受けたものは performFunctionInCocosThreadで実⾏ トラブルシューティング: Androidスレッド問題
  49. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 50 • 

    アプリ起動時にAppDelegateのみ初期化しているものの、 Android版Cocos2d-xは元々バックグラウンドからの復帰 時にGLSurfaceViewを再⽣成するようになっておりその 処理がCocos2d-xビューを⽣成時にも必要なため、重い 初期化処理が⾛ることにより表⽰されるまで時間がか かっていた •  Cocos2d-xは内部で使っているシェーダープログラムを 全て起動時に初期化しており、parseUniforms()と glLinkProgramが特に重かった •  3D向けなど使わないシェーダーの初期化を省略 •  今後シェーダーの利⽤時に初期化されるようになるかも https://github.com/cocos2d/cocos2d-x/issues/15637 トラブルシューティング: Androidシェーダー問題
  50. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 51 • 

    Cocos2d-xビュー作成時は既存アプリGLビューのレンダ リングループを⽌める •  Cocos2d-xビュー終了時には、Director::endを呼ぶと次 のフレームで呼ばれるGLViewImpl::end内で、GCDで dispatch_asyncした先で、GLコンテクスト(今誰が描画 しているのか)を既存アプリのものに復帰 •  Cocos2d-xと既存アプリのGLコンテクストの競合は起 こっていないはずにもかかわらず、Cocos2d-xを起動し て閉じた後、既存アプリのテクスチャーが時々乱れた •  Cocos2d-xビュー作成前に開始されていた既存アプリの テクスチャー⾮同期ダウンロードジョブが、ダウンロー ド完了時(Cocos2d-x起動中)にglBindTextureなどGLの 関数を呼び出してしまっていたのでスキップするよう変 更 トラブルシューティング: iOSテクスチャー問題
  51. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 52 • 

    C++ラムダ式での変数キャプチャには注意 •  サーバー通信などをCocos2d-xシーンからブリッジAPIを 経由して⾏うと、時間が経ち結果が帰ってきた時には元 のシーンが消滅しており、コールバックのラムダ式内に キャプチャされたシーンのthisポインタが無効になってい る場合がある •  staticなSceneFactoryでシーン毎にUUIDを発⾏して 同⼀性を保証し、シーンが存在しない/そのシーンが 発⾏していないAPI実⾏の結果が来た時は弾く •  参照キャプチャ(&)を使うとスタック変数がキャプチャさ れてしまい、iOSではスレッドを分けない限り原則として 同⼀スタックフレーム上でブリッジAPIが最後まで実⾏さ れるので問題ないが、Androidではコールバックのスタッ クフレームが異なり無効なアドレスを参照して落ちる トラブルシューティング: シーンライフサイクル問題
  52. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 53 • 

    透明領域を少なくして描画負荷を抑えるために、 Cocos2d-xのGLビューのサイズを、Cocos2d-x 内部で⽣成するシーンのサイズと同じにして既存 アプリ側から⽣成する仕様とした •  つまり、GLビューのサイズは端末画⾯サイズ より多くの場合⼩さくなる •  この仕様により、Cocos2d-x側で全画⾯表⽰した 場合に⾏ってくれるスケーリングに頼れないこと になり、様々なAndroid/iOSデバイス向けのス ケーリングのコードを⾃前実装することになり、 かなり⼿間になった 失敗点: ⾃前スケーリングは⾯倒
  53. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 54 • 

    ここまでの⼿間を経て、ようやくCocos2d-x組み 込みは実⽤に耐える技術として確⽴する •  しかし、Cocos2d-x⾃体も⽇々変化しており、明 ⽇はまた異なるものになっているかもしれない •  Director::getInstance()- >getRunningScene()->getChildren().at(0)だ とCameraが取れてしまう(現在のシーンはat(1)) •  Cocos2d-xのSceneは、Node/Layerと異なり、 Camera、BaseLight、NavMesh、 Physics3DWorldを持つ •  Cocos2d-xは3D/VRゲームエンジンへと変容 を遂げつつある(Cocos2d-xからCocosへ) これからのCocos2d-x
  54. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 55 • 

    Cocos Studio開発終了 •  Cocos Creatorが主流に •  Electronベースでオープンソース。Unityライ クなビジュアル開発環境 •  Chukongは、コンソール版をキャンセルして でも開発環境の充実を第⼀⽬標に置いている •  (UnityがC#で開発するように)JavaScriptでの ダイナミックな開発を推奨、C++は重い処理 を書く場合以外は使われなくなる •  プロジェクト構成が従来と変わるので、新し くCocosプロジェクトを起こすならCocos Creatorベースとすべし これからのCocos2d-x
  55. Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 56 • 

    余計な⾎は流さない •  Cocos2d-xへのパッチは最⼩限に •  Cocos2d-x最新版への追随更新を妨 げない •  ゴールはあくまでアプリを活かすこと •  UnityにCocos2d-xを組み込むことも 不可能ではない… かもしれない •  ゲームエンジンの深層は学びの宝庫で ある 総括: 外科⼿術の⼼得