myb design

blog

Unity UIの本を執筆しました - uGUIではじめるUnity UIデザインの教科書

この度、Unity UI(uGUI)の本を執筆し、出版されることになりました!


【Amazon.co.jp限定】uGUIではじめるUnity UIデザインの教科書-Unity5対応 特典PDF付き

Unity 4.6から新しく搭載されたUIシステムを網羅的に解説し、サンプルコードではiOSやAndroidの一般的なアプリケーションでよく使われるUIの作成方法やネイティブプラグインの作成方法を紹介しています。

また表紙は、アイロンビーズ・クリエイターのヌンちゃんにアイロンビーズで作ってもらいました。ありがとうございます!このロボットやアイコン達は本文中にも出てきます。

9月1日には書店に並ぶと思います。
また、Amazon限定でAppendixのPDFがダウンロードできるキャンペーンもおこなわれているので、是非ともよろしくお願いします!

[追記]
Amazon限定の特典PDFの申し込みはこちらからできます。
https://book.mynavi.jp/blog/pc/2015/08/12/811/

書評 - 上を目指すプログラマーのためのiPhoneアプリ開発テクニックiOS7編


上を目指すプログラマーのためのiPhoneアプリ開発テクニック iOS 7編

献本をいただきましたので、遅ればせながらレビューを書かせていただきたいと思います。

iOS7で新しく追加された機能・変更された機能が、読みやすい適度なボリュームで実際の実装で役に立つテクニックも含めて解説されています。
個人的には特にChapter 05 マルチタスキング・通信、Chapter 07 拡張機能が気になりました。


Chapter 05 マルチタスキング・通信

Background Fetch、NSURLSession、 Multipeer Connectivity、サイレントプッシュについて解説されています。
バックグラウンドでデータをあらかじめダウンロードしておくなど、アプリに不可欠なサーバーとの通信の最適化が、具体的な実装で紹介されています。
WWDCのセッションを見たりAppleのドキュメントを読んでも今ひとつピンときませんでしたが、本章の解説は非常にわかりやすいです。


Capter 07 拡張機能

iCloud Core Data、Core Bluetooth、Map KitとCore Location、Core Motion、文字入力・キーボードについて解説されています。
特にCore Bluetoothでの通信はページ数も割かれて詳しく実装が紹介されていて、最近ホットなiBeaconについても触れられています。
文字入力・キーボードでは、UIKeyCommandを使った外部キーボードからのキー入力について紹介されています。


本書はAppendixがまた充実しています。旧バージョンからの移行ポイントとしてアイコンサイズの一覧やステータスバー周りの挙動の注意点、64bit対応などがよくまとまっていて、これまた実用的です。

こんなところで、本書の購入の参考になれば幸いです。

Global Game Jam 2012 (GGJ)に参加してきました。

去る1月27日〜29日に、48時間以内に即席のチームでゲームを制作するイベント、Global Game Jamに参加してきました。
このようないわゆるJamイベントは初めてで、勝手も分からず恐る恐る参加してみたんですが、これがもうなんとも熱く濃密な体験をすることができました。

僕の参加したチームにはUnityのエバンジェリストである高橋さんがいらっしゃって、その時点でチートだろうという噂もありましたが、メインプログラマー×2、リーダー兼サーバー担当、サウンド担当、グラフィック担当(自分)と、構成としては非常にいいチームでした。

そんな構成だったので、今回はデザインに専念。普段はプログラミングに飽きたらデザインやって、デザインに飽きたらプログラミングでと勝手気ままにやっているんですが、限られた時間内で結果を出さなければならないというプレッシャーを感じつつ、出せるものを出してきました。

プロトタイプの時点でシステムとして完成されていたこともあり、キャラクターから世界観が固まっていって完成にこぎ着けたことは非常によかったと思うのですが、普段から自分のデザインに対して感じていた問題点が(自分の中で)浮き彫りになって、それは今後も意識して打ち砕いていかなければなあ、と思ったり。

いずれにせよ、この短時間にこれだけ集中して作業するということも普段ないことなので、なにか新しい世界を見た気がします。

さて、そんな48時間で制作したゲームはこちら、「Greedy Snake-san」。
ページ中ほどのGame Files: Please click it !l (Game Start!)からブラウザ上で遊べます(要Unity Web Player)。
うまく動かない場合はゲーム画面の上にあるUnity Web Player 3.5(RC1)というリンクをクリックしてPlayerをアップデートしてみてください。
タイムアタックのランキングもあります。
Enjoy it!

cocos3d+Bulletで物理シミュレーション (実装編) #cocos2d_2011_adcal

@yoichinejiさん主催のcocos2d Advent Calendar 2011、1日遅れで19日目の記事です。
前日の記事: ゲームを作るなら効果音、声、BGMも必要だよね (@aoi68kさん)

前回導入編の続きで、実装編です。
サンプルコードは前回と同じものです。(こちらからダウンロードできます)
固定された床にキューブが降り注ぎ、積み重なっていくデモです。

ccadcal16_07.png


3Dモデルの読み込みと表示

cocos3dでの3Dモデルの読み込み・表示は、テンプレートから作成したプロジェクトのCC3World派生クラスにもある通り、とても簡単です。

[self addContentFromPODResourceFile: @"hello-world.pod"];

これだけ。

モデルのフォーマットはPOD(PowerVR Object Data)ですが、Collada2PODというツールでCOLLADAフォーマット(.dae)から変換できます。
大概のモデリングツールはCOLLADAで出力できると思います。
Collada2PODのダウンロードはこちらから(要サインアップ)。

ccadcal19_01.png

Collada2PODの設定ファイル(Collada2PODSettings.txt)がcocos3dのToolsフォルダに同梱されているので、これをLoad Optionsから読み込んで変換するとうまい具合にいきます。

テクスチャを貼っている場合は、その画像をプロジェクトのリソースとして追加すればOKです。


物理シミュレーションの準備

物理シミュレーションの実装を記述するソースコードでbtBulletDynamicsCommon.hをimportします。

#import "btBulletDynamicsCommon.h"

BulletはC++で記述されているため、Objective-Cから使う場合はObjective-C++で記述します。
該当するソースコードの拡張子を「.m」から「.mm」に変更します。

サンプルコードではcocos2dAdventCalendarDay16World.hでbtBulletDynamicsCommon.hをimportしているため、このヘッダファイルをimportしているすべてのファイルの拡張子が「.mm」になっていますが、実際にC++のコードを記述しているのはcocos2dAdventCalendarDay16World.mmだけです。


ダイナミクスワールドの作成

まず物理シミュレーションを行うための世界・ダイナミクス(力学)ワールドを作成します。
今回は単純な剛体による物理シミュレーションのため、btDiscreteDynamicsWorldクラスを使います。

collisionConfiguration = new btDefaultCollisionConfiguration();
collisionDispatcher = new btCollisionDispatcher(collisionConfiguration);
broadphaseInterface = new btDbvtBroadphase();
constraintSolver = new btSequentialImpulseConstraintSolver();
dynamicsWorld = new btDiscreteDynamicsWorld(collisionDispatcher, broadphaseInterface, constraintSolver, collisionConfiguration);
dynamicsWorld->setGravity(btVector3(0.0f, -9.8f, 0.0f));

最後にY軸のマイナス方向に1Gの重力を設定しています。


コリジョンシェイプの作成

コリジョンシェイプとは衝突判定を行うために物体がどんな形状をしているかを表すオブジェクトです。
btCollisionShapeクラスを基底として、直方体、球、円柱、円錐、カプセル型などそれぞれの形状の派生クラスが用意されています。
床用のコリジョンシェイプ(直方体)の作成はこんな感じです。

groundCollisionShape = new btBoxShape(btVector3(4.0f, 0.25f, 4.0f));

コンストラクタの引数にX、Y、Z方向の大きさを渡して作成します。
Bulletでは大きさを表すときによくhalf extent(半分の大きさ)が使われています。なので、このシェイプの大きさも縦横8×8、高さ0.5となります。

コリジョンシェイプは使い回すことができます。
サンプルコードでも降り注ぐキューブの方は、一つのコリジョンシェイプをインスタンス変数として保持しておいて使い回しています。


モーションステートの作成

モーションステートとはBulletによる物理シミュレーションの結果変化した向きや位置を受け渡すためのインターフェースです。
通常はbtMotionStateの派生クラスを自分で作る必要はないようなので、デフォルトのbtDefaultMotionStateクラスを使います。

btDefaultMotionState *groundMotionState = new btDefaultMotionState(btTransform(btQuaternion(0.0f, 0.0f, 0.0f, -1.0f), 
  btVector3(groundMeshNode.location.x, groundMeshNode.location.y, groundMeshNode.location.z)));

コンストラクタに初期状態の回転・位置を示す変換情報を渡して作成します。位置は配置済みのCC3MeshNodeオブジェクトのlocationに合わせています。
回転を示すクオータニオンのWが-1な理由は後ほど。


リジッドボディの作成

リジッドボディ(剛体)とはBulletにより物理シミュレーションを行う物体を表すオブジェクトです。
先に作成しておいたコリジョンシェイプとモーションステートをリジッドボディに関連付けます。

btRigidBody::btRigidBodyConstructionInfo groundRigidBodyCI(0.0f, groundMotionState, groundCollisionShape, btVector3(0.0f, 0.0f, 0.0f));
btRigidBody *groundRigidBody = new btRigidBody(groundRigidBodyCI);

btRigidBodyConstructionInfo構造体で、物体の質量、モーションステート、コリジョンシェイプ、慣性を設定します。

Bulletには、シミュレーションによって動かされる「動的剛体」、衝突するが動かない「静的剛体」、ユーザーによって動かされ動的剛体を押すことはできるがそれ自体は影響を受けない「キネマティック剛体」の3種類があります。
質量を正の値にすると動的剛体、0にすると静的剛体になります。静的剛体にキネマティックフラグを設定するとキネマティック剛体になります。
床は衝突するが動かない静的剛体なので、質量に0を指定しています。

降り注ぐキューブは動的剛体なので、以下のようなコードになります。

GLfloat mass = 1.0f;
btVector3 localInertia(0.0f, 0.0f, 0.0f);
cubeCollisionShape->calculateLocalInertia(mass, localInertia);
// (中略)
btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(mass, motionState, cubeCollisionShape, localInertia);
btRigidBody *rigidBody = new btRigidBody(rigidBodyCI);

動的剛体の場合は、慣性をcalculateLocalInertia()関数によって算出します。

こうして作成したリジッドボディには、パラメータで表面の摩擦や弾み具合など物体の材質を設定できます。
このリジッドボディをダイナミクスワールドに追加することによって物理シミュレーションされるようになります。

dynamicsWorld->addRigidBody(rigidBody);


シミュレーションの実行

まずCCSchedulerを使って、更新用メソッドが毎フレーム呼ばれるようにしておきます。

[[CCScheduler sharedScheduler] scheduleSelector:@selector(updatePhysics:) forTarget:self interval:0 paused:NO];

更新用メソッドの方では、dynamicsWorldのstepSimulation()関数を呼びます。

dynamicsWorld->stepSimulation(dt, 2);

これで物理シミュレーションが1ステップ実行され、各物体の向きや位置が更新されます。
あとは、各物体のモーションステートから変換情報を取り出して、対応するCC3Nodeオブジェクトに反映していけばいいわけです。

CC3MeshNode *meshNode = cube.meshNode;
btRigidBody *rigidBody = cube.rigidBody;

btTransform transform;
rigidBody->getMotionState()->getWorldTransform(transform);
btVector3 pos = transform.getOrigin();
meshNode.location = cc3v(pos.getX(), pos.getY(), pos.getZ());
btQuaternion quaternion = transform.getRotation();
meshNode.quaternion = CC3Vector4Make(quaternion.getX(), quaternion.getY(), quaternion.getZ(), -quaternion.getW());

物体の位置は座標をそのまま渡せばOKです。
回転は、クオータニオンのWを-1倍して渡します。回転方向が合わず物体同士がめり込むことがあったのでこうしています。

完成したデモはこんな感じです。

ちょうど0.6.5がリリースされたcocos3dですが、3Dオブジェクトを簡単に扱え、かつ、CCActionによるアクションももちろん使えるという非常に便利なフレームワークです。
ぜひ使ってみてください!


参考資料:
cocos3d APIリファレンス
http://brenwill.com/docs/cocos3d/0.6.5/api
cocos3d プログラミングガイド
http://brenwill.com/2011/cocos3d-programming-guide/
Bullet APIリファレンス
http://bulletphysics.com/Bullet/BulletFull/
Bullet 日本語マニュアル
http://bulletjpn.web.fc2.com/


次の記事: Cocos3dをさわってみた。 (@kclabさん)

cocos3d+Bulletで物理シミュレーション (導入編) #cocos2d_2011_adcal

@yoichinejiさん主催のcocos2d Advent Calendar 2011、16日目の記事です。
前日の記事: CCSendMessagesでもっと簡潔に直感的なコードを書こう (@Seasonsさん)

今回はcocos2d上で3Dオブジェクトを扱えるフレームワーク「cocos3d」とオープンソースの物理演算エンジン「Bullet」を使って物理シミュレーションをしてみます。
サンプルコードはこちらからダウンロードできます。


cocos3dの導入

cocos3dはhttp://brenwill.com/cocos3d/の右カラムの「DOWNLOAD COCOS3D」からダウンロードできます。
執筆時点での最新バージョンは0.6.4です。

Terminalで解凍したフォルダへ移動し、cocos2dのパスを指定してインストールスクリプトを実行すると、Xcodeのテンプレートがインストールされます。
この操作は管理者権限で実行する必要があります。

$ cd cocos3d\ 0.6.4
$ ./install-cocos3d.sh -u -f -2 "../cocos2d-iphone-1.0.1"


cocos3dのプロジェクトを作成する

Xcodeのメニュー File → New → New Project... を選択し、iOS / cocos3dから「cocos3d Application」を選択します。
プロジェクト名を付けて適当な場所に保存します。

ccadcal16_01.png

これをそのままビルド・実行してみるとHello worldの文字が回転します。

ccadcal16_02.png


Bulletの導入

Bulletはhttp://bulletphysics.org/wordpress/の左上の「Bullet Download」からダウンロードできます。
執筆時点での最新バージョンは2.79です。

今回は、Bulletを静的ライブラリとして導入します。
解凍したフォルダ内にあるsrcフォルダをプロジェクトフォルダにコピーして、名前をBulletに変更しておきます。
Project Navigatorでプロジェクトを選択して下のAdd Targetをクリック、Mac OS X / Framework & Libraryから「C/C++ Library」を選択します。

ccadcal16_03.png

Product Nameは「Bullet」、Typeは「Static」にして、Use Automatic Reference Countingはオフにしておきます。

ccadcal16_04.png

Xcodeのメニュー File → Add Files to "<プロジェクト名>"... を選択して、Bulletのソースファイルをプロジェクトに追加します。
このときAdd to targetsで「Bullet」にチェックして、先ほどのBulletフォルダを指定します。

ccadcal16_05.png

Project Navigatorでビルドしないファイルの参照をごそっと削除します。

ccadcal16_06.png

プロジェクトのBuild Settingsを変更します。

  • Header Search PathsにBulletフォルダへのパス($SRCROOT/$PROJECT_NAME/Bullet)をRecursiveで追加。

BulletのターゲットのBuild Settingsを変更します。

  • Base SDKを「Latest iOS」に変更。
  • Architecturesを「Standard (armv7)」に変更。
  • Other Linker Flagsから「-lz」を外す。

アプリケーションターゲットのBuild Settingsを変更します。

  • Build Phases → Target Dependencies の+ボタンを押してBulletを追加。
  • Build Phases → Link Binary With Libraries の+ボタンを押してlibBullet.aを追加。

さて、ようやくこれでコードを書く準備ができました。
思いのほか長くなってしまったのでここまでを導入編として、実際の物理シミュレーションの実装は次の機会にしたいと思います。

ccadcal16_07.png
こんな感じになります!

次の記事: よく分かってない人がgoogle先生と一緒につくるはじめてのBox2D (@marchEnterpriseさん)