Slide 1

Slide 1 text

Copyright © GREE, Inc. All Rights Reserved. Cocos2d-xの深層 2016/08/24 @ CEDEC 2016 久富木 隆一 (KUBUKI Ryuichi) Cocos2d-x組み込みによる ピュアAndroid/iOSアプリの 外科手術的統合

Slide 2

Slide 2 text

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. 総括

Slide 3

Slide 3 text

Copyright © GREE, Inc. All Rights Reserved. 自己紹介 3 • 久富木 隆一 (KUBUKI Ryuichi) • グリー株式会社 • West Game事業本部 GREE International Entertainment(米国サ ンフランシスコ)等、海外ゲーム事業を担当

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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を主 な支援者としてオープンソース開発中

Slide 7

Slide 7 text

Copyright © GREE, Inc. All Rights Reserved. Cocos2d-xとは何か 7 • Cocos2d-xは完全にオープンソース • Unityは完全にオープンソースではない • Cocos2d-xは完全無料 • Unity、Unreal Engineは有料 メリット デメリット • Cocos2d-xにはベンダーサポートはない(コミュ ニティはある) • 3Dや開発環境など発展途上

Slide 8

Slide 8 text

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、ロジック)は全てプ ラットフォーム別に独自実装 状況把握

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

Copyright © GREE, Inc. All Rights Reserved. Android/iOSクライアント統合という問題 13 よし、Android/iOSで 分かれているクライア ントを1つに統合しよ う! 結論

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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組み込み)

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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移植)

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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経験者が多かったので 問題とならなかった。

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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アプリの特性

Slide 30

Slide 30 text

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アプリの特性

Slide 31

Slide 31 text

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実装と組み込み

Slide 32

Slide 32 text

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実装の起動フロー

Slide 33

Slide 33 text

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実装の起動フロー

Slide 34

Slide 34 text

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組み込み要件

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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側と既存アプリの通信

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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組み込みアプリのビルド

Slide 47

Slide 47 text

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シーンのモーダルダイアログ表示

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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スレッド問題

Slide 50

Slide 50 text

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シェーダー問題

Slide 51

Slide 51 text

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テクスチャー問題

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

Copyright © GREE, Inc. All Rights Reserved. Cocos2d-x組み込みによるクライアント統合 56 • 余計な血は流さない • Cocos2d-xへのパッチは最小限に • Cocos2d-x最新版への追随更新を妨 げない • ゴールはあくまでアプリを活かすこと • UnityにCocos2d-xを組み込むことも 不可能ではない… かもしれない • ゲームエンジンの深層は学びの宝庫で ある 総括: 外科手術の心得

Slide 57

Slide 57 text

Copyright © GREE, Inc. All Rights Reserved. Thank You