ゆるきゃらアクションゲーム、「空島大乱闘」を大型アップデートしました!

伝説のマニアです♪U・ω・U


やっとで、、、

祝・空島大乱闘をアップデートしました〜♪♪♪

今回のアップデートで多数の項目を追加しました!

大きい変更点は、アクセサリーの実装です♪

、、、例えば、、、

20151203201334.jpg


こんな感じで、キャラクターにメガネとかがかけれちゃいます!

アクセサリーを取得するには、モンスターを倒した時にたまに出てくるルビーを集めると、買う事ができます♪
コンプリートしちゃいましょう♪♪♪


また、今までは、マルチプレイをするには、ランダムマッチングのみでしたが、特定の友達とマッチングしてプレイしたい場合に使用する、パターンマッチング機能を追加しました!

20151203202603.jpg

6文字の数字を入力すると、同じ数字を入力した友達と一緒にプレイする事ができます♪


また、全プレイヤーで競い合える、プレイヤーランキング機能を実装しました!

20151201231200.jpg

自分の実力に自身のある方は、ランキング上位を目指してみましょう♪
なお、ランキングは毎週月曜日にリセットされます!


完全無料で楽しめるアプリなので、気になった方は是非遊んでみてください〜♪U・ω・U



【アップデート情報】
バージョン
2.0.0

追加情報
・インターフェイスの向上。
・アクセサリー(顔・体)の実装。
・アクセサリーを取得するために必要な「ルビー」を実装。
・パターンマッチング(友達同士でプレイしたい場合のマッチング)の実装。
・ランキング(シングル)の実装。
・名前を変更する事ができなくなりました。
・モンスターが湧いてくるペースを変更しました。
・武器取得、スキル取得するさいに、「コインを消費」するように変更。
・ロビーのチャットを削除して、ゲーム待機画面にチャットを設置しました。
・武器やスキルの設定を記憶するように変更(ゲーム終了時はリセット)し、毎回選択する必要がなくなりました。
・コインが少し取りやすくなりました。


【アプリへのリンク】
iPhone
https://itunes.apple.com/jp/app/kong-dao-da-luan-dou/id991719002

Android
https://play.google.com/store/apps/details?id=net.legendarymaniac.lproject


Sponsored Links
テーマ: Unityゲーム制作 | ジャンル: コンピュータ

Unityでmaioを実装する話

伝説のマニアです♪U・ω・U


前回のブログから大分期間が空いてしまいましたが、、、、
またブログの更新を再開していきたいと思います!!


今回は、Unityでmaioの動画広告を実装した話をしていきます。
maioとは、動画広告プラットフォームで、アイモバイルさんが提供しているサービスです。
http://maio.jp/

私はプログラミングはほとんどC/C++で書いていますので、正直Objective-Cの知識は相当浅はかですw

それでも何とか実装できましたw
もし、Unityでmaio使いたい!けどプラグインがないから、、、、と思っている方がいらっしゃいましたら参考になれば幸いです。
(「じゃあお前がプラグイン作れよ」とかは言わないであげて下さい。。。w)


なお、現段階では、maioSDKはiOSのみの対応となっています。


【Unity上から任意のタイミングで動画を再生する】
Unityのスクリプト(C#)からObjective-Cのコードを呼び出す
まず初めに、Unity側のスクリプトに、Objective-Cのコードを呼ぶための関数を宣言します。以下、ソースコードの一部抜粋したものです。

C#


ソースコードを解説していきます。

コードの5行目のSystem.Runtime.InteropServicesは、UnityのスクリプトからObjective-Cのコードを呼び出すさいに必要になり、[DllImport("__Internal")]を使うためのものです。

コードの11行目と12行目で、Objective-Cで使用する関数を宣言しています。これは正確にはC言語の関数を呼び出すさいに使うものです。Objective-Cであれば他にもっといい方法があるかもしれませんが、私は前からこれを使っていたのでこれ使います♪U・ω・U

そして、コードの23行目で実際に動画を再生する関数を呼びます。この関数は、動画の再生に成功すれば0を返し、失敗すると−1を返すように書いています(正確には違いますが(汗)。

なお、ここで気をつけるべきことが、maioの動画を再生しても、Unity上で再生しているBGM等は音が流れ続けてしまいます。よって、AudioSource.volumeのボリュームを0.0fにする等して動画再生前に消音し、動画が終わり次第再度ボリュームを戻す等行って下さい。

次に、Objective-C側のコードを見ていきます。

Objective-C



ソースコードを解説していきます。

コードの1行目で、maioSDKのヘッダーファイルをインクルードしています。

コードの9行目の[Maio show]で、実際に動画の再生がスタートします。その前のコードの7行目の[Maio canShow]で、動画の再生が可能かどうかを判定できます。これが真を返せば、動画の再生を開始し、0をリターン。再生が不可能であれば、動画の再生はせずに−1をリターンします。


ここまで実装できれば、とりあえず動画広告を再生することができるようになります。


【動画再生時にデリゲートで呼ばれるイベントを実装する】
MaioDelegateを採用したインスタンスを用意する
maioの動画再生が始まると(始まる前も)、生成済みインスタンスの中で、MaioDelegateを採用したインスタンスの、特定のイベント関数(いくつかあります)が呼ばれることとなっています。要は、@interface hoge <MaioDelegate>〜@endみたいなインスタンスを用意しないといけないってことですね。。。この辺でObjective-Cの仕組みがわからなくて時間を費やしてしまいましたw

私は、UnityAppControllerのインスタンスにMaioDelegateを適用することとしました。UnityAppControllerは、多分、AppDelegateみたいなものです。多分。。。

以下、UnityAppDelegate.hとUnityAppDelegate.mmを一部抜粋したソースコードです。

Objective-C


ソースコードを解説していきます。

UnityでXcodeプロジェクトを吐き出した時、このヘッダーファイルが生成されているはずです。まず、5行目でmaioSDKをインクルードしています。その後、13行目にMaioDelegateを追加しています。
こうすることで、UnityAppDelegateクラスでMaioDelegateのイベント用関数を実装すると、動画再生に関するイベント発生時に、実装した関数が呼ばれる事になります。

UnityAppControllerクラスにイベント関数を実装する
実装できるイベントはいくつかありますが、私は、「動画再生完了時に呼ばれる関数」だけを使いました。SDKの仕様書に記載されていますが、実際には、以下の通り関数が用意されています。

全てのゾーンの広告表示準備が完了したら呼ばれます。
- (void)maioDidInitialize {}

広告の配信可能状態が変更されたら呼ばれます。
- (void)maioDidChangeCanShow:(NSString *)zoneId newValue:(BOOL)newValue {}

広告が再生される直前に呼ばれます。
最初の再生開始の直前にのみ呼ばれ、リプレイ再生の直前には呼ばれません。
- (void)maioWillStartAd:(NSString *)zoneId {}

広告の再生が終了したら呼ばれます。
最初の再生終了時にのみ呼ばれ、リプレイ再生の終了時には呼ばれません。
- (void)maioDidFinishAd:(NSString *)zoneId playtime:(NSInteger)playtime skipped:(BOOL)skipped rewardParam:(NSString *)rewardParam {}

広告がクリックされ、ストアや外部リンクへ遷移した時に呼ばれます。
- (void)maioDidClickAd:(NSString *)zoneId {}

広告が閉じられた際に呼ばれます。
- (void)maioDidCloseAd:(NSString *)zoneId {}

SDK でエラーが生じた際に呼ばれます。
- (void)maioDidFail:(NSString *)zoneId reason:(MaioFailReason)reason {}


次に、UnityAppController.mmの実装を見ていきます。
Objective-C

ソースコードを解説していきます。
コードの13行目〜16行目で、maioSDKの初期化を行います。このコードはdidFinishLaunchingWithOptions内に実装して下さい。MAIO_MEDIA_IDは、アプリ別にふられた固有のIDを記載します。

コードの23行目のmaioDidFinishAdは、動画再生が完了したさいに呼ばれるイベント関数です。この中の25行目で、Unityのソースコードを呼び出しています。Unityのソースコード内で、動画広告再生完了時の報酬等を実装していけばいいかと思います。


【まとめ】
ぶっちゃけ、Objective-Cには全く自信がないので、この実装で大丈夫かなぁ。。。と思うところもありますが、とりあえずこれで正常に動作したので、、、良しとしましたw

Sponsored Links
テーマ: Unityゲーム制作 | ジャンル: コンピュータ

新作アプリ「みんなで倒せ!70億のゴブリン!」をリリースしました!!

伝説のマニアです♪U・ω・U


前回のブログ更新から一ヶ月近く期間が空いてしまいましたが、、、、


新作アプリ「みんなで倒せ!70億のゴブリン!」をリリースしました〜!!


【ゲームの紹介】

このゲームは、画面いっぱいにウヨウヨしているゴブリンを、ひたすらタップで倒していくというとてもシンプルなものですw

Screenshot1_20150727.png

今回は、キャラクターデザインを担当した「うにょ」さんがキャラクターボイスもやってくれました!!

ゴブリンを退治すると、「うお!」とか「ぴぎゃ」とか叫んでくれますw



そして、このアプリのポイントは、70億匹のゴブリンを倒す!という設定なのですが、一人の力ではとてもじゃないですが不可能です。。。


。。。が、みんなの力を合わせれば可能かもしれません!

そうです、この「のこり 〜〜何匹」という表示は、全プレイヤー共通の数字となっており、リアルタイムで更新され続けます!

70億匹のゴブリンを、みんなで倒すのです!w

自分がゴブリンを倒していなくても、他のプレイヤーが倒すとこの数字は減っていきます。



また、ゴブリンを倒した数を競うために、各プレイヤーが倒したゴブリンの数ランキングを確認することができます!

Screenshot3_20150727.png

ランキングは二種類あり、「個人別のランキング」と、「都道府県別のランキング」があります。タップに自身のある方は、上位を目指してもいいかもしれません!


そして、このゲームには「神ゲージ」というものがあります。このゲージはゴブリンを倒していくと溜まっていき、MAXになると一時的に「神」の力を使う事が出来ます!

Screenshot2_20150727.png




気になった方は是非遊んでみてください〜♪U・ω・U


【アプリ情報】
■アプリ名
みんなで倒せ!70億のゴブリン!

■価格
無料

■iTunesリンク
https://itunes.apple.com/jp/app/minnade-daose!70yinogoburin!/id1021089523

■Google Play
https://play.google.com/store/apps/details?id=net.legendarymaniac.cproject

■キャラクターデザイン・CV
うにょ 様
https://twitter.com/unyopitti

■効果音・BGM
魔王魂 様
http://maoudamashii.jokersounds.com

■効果音
PANICPUMPKIN 様
http://pansound.com/panicpumpkin


Sponsored Links
テーマ: Unityゲーム制作 | ジャンル: コンピュータ

「空島大乱闘」キャラクター2の新・必殺技「巨大化」を追加しました!

伝説のマニアです♪U・ω・U


スマホゲームアプリ「空島大乱闘」をバージョンアップしました〜!!


【新・必殺技】
変更点はいくつかありますが、目玉はキャラクター2の新・必殺技「巨大化」追加です♪U・ω・U



Screenshot_2015-06-30-23-53-02.png


巨大化を発動すると。。。


Screenshot_2015-06-30-23-53-11.png


このように体が大きくなり、周りの敵をなぎたおしていきますw

巨大化時はほぼ無敵状態。。。





Screenshot_2015-06-30-23-54-28.png


巨大化時に倒れた時の存在感がやばいです。。。



気になった方は是非遊んでみてください〜♪U・ω・U



【アップデート情報】
バージョン
1.2.1

追加情報
・キャラクター2の必殺技を追加しました
・キャラクター2のスピードを少しアップしました
・ゲーム中に現在の接続数が表示されるようにしました
・その他いくつかの項目を追加しました

バグ修正情報
・キャラクター2の起き上がりに無敵判定とならないバグを修正しました
・キャラクター2の雷が当たらないバグを修正しました
・武器が取得できなくなるバグを修正しました


【リンク】
iPhone
https://itunes.apple.com/jp/app/kong-dao-da-luan-dou/id991719002

Android
https://play.google.com/store/apps/details?id=net.legendarymaniac.lproject


Sponsored Links
テーマ: Unityゲーム制作 | ジャンル: コンピュータ

「空島大乱闘」のオンラインの技術的なこと その4

伝説のマニアです♪U・ω・U

前回は、キー操作の同期化について概要を説明しました。今回は、キャラクターイベントの同期化について説明したいと思います。

【連載記事一覧】
「空島大乱闘」のオンラインの技術的なこと その3
「空島大乱闘」のオンラインの技術的なこと その2
「空島大乱闘」のオンラインの技術的なこと その1



【イベント同期化の重要性】
イベント処理は、出来る限り正確に同期化する
前回説明した、キー操作の同期化処理については、ある程度妥協した形で同期化する方法を取っていました。各プレイヤーから見た、他のプレイヤーの見た目が一致しない事が頻繁に起こるというものです。

しかし、キー操作と違って、キャラクターのイベント処理は重要な要素である事が多いため、出来る限り正確に同期化したい、と思いました。

ここで言うキャラクターのイベントとは、「プレイヤーが攻撃した」とか「プレイヤーがダメージを受けた」、「プレイヤーが死んだ」という処理の事です。



【イベントとして送信する情報】
空島大乱闘では、イベント情報として、以下の情報を他のプレイヤーへ送信しています。

・攻撃した・・・・・・(当たっていなくても)パンチ等を行った
・武器を取った・・・・キャラ1の落ちている武器を拾う処理(※武器取得の流れを後述します)
・武器を落とした・・・キャラ1の持っている武器を落とす処理
・必殺技を出した・・・キャラ2の(当たっていなくても)必殺技を行った
・ダメージを受けた・・敵から攻撃されて、ダメージを受けた(一瞬怯む動作)
・吹っ飛ばされた・・・敵から攻撃されて、ぶっ飛ばされる処理
・落ちた・・・・・・・空島から落下した
・ダウンした・・・・・ぶっ飛ばされた後にダウンした(必ずダウンするようになっています)
・死んだ・・・・・・・ヒットポイントが0となり、死んでしまった
・コインを取った・・・落ちているコインを取得した

イベント情報パケットについて
上記のイベントが発生した場合は、そのイベントを同期化するため、イベント情報パケットを送信する事になります。空島大乱闘では、イベント情報パケットは二種類あります。

一つ目は、プレイヤーの操作から発生したイベントで、「攻撃した」や「必殺技を出した」の処理になります。そのさいに送っている情報は、以下の通りです。

・プレイヤーID・・・・・ゲームサーバーより割り振られたID
・プレイヤー位置情報・・プレイヤーのワールド座標位置値
・イベントタイプ・・・・「攻撃した」「必殺技を出した」等の種類

このパケットを受信した端末では、「プレイヤー位置情報」へプレイヤーを強制移動し、「イベントタイプ」で指定されたイベントを必ず行います。

イベントを行ったプレイヤーがどの位置にいようとも、強制的にプレイヤーの位置を移動させ、今プレイヤーがどのような状況であったとしても、強制的にイベントタイプで指定された動作を行うようにしています(一部例外はありますが、稀なケースなのでここでは省きます)。

キー操作の場合だと、プレイヤーの位置はトゥイーンにより移動させていましたが、イベント処理は強制移動となっています。この辺は悩み所でしたが(ぶっちゃけどっちでもいいのですが)、キー操作よりも重要ということでこのようにしました。

二つ目は、プレイヤーが他から受けるイベントで、「ダメージを受けた」や「死んだ」、「コインを取得した」の処理になります。その際に送っている情報は、以下の通りです。

・プレイヤーID・・・・・ゲームサーバーより割り振られたID
・プレイヤー位置情報・・プレイヤーのワールド座標位置値
・イベントタイプ・・・・「ダメージを受けた」や「死んだ」等の種類
・パラメーター1・・・・4バイトの浮動小数点数
・パラメーター2・・・・2バイトの整数型

二つ目のイベントも、強制位置移動と、強制イベント処理を行っていることは、一つ目と変わりありません。

ただ、「どのくらい吹っ飛ばされたか」や「どのコインを取得したのか」は、イベントタイプ情報だけでは分かりません。なので、パラメーターを追加して汎用的に使うことで、情報を同期しています。例えば、以下のような情報を送っています。

→ダメージを受けて、吹っ飛ばされた場合
・プレイヤーID・・・・・ゲームサーバーより割り振られたID
・プレイヤー位置情報・・吹っ飛ばされた時のプレイヤーのワールド座標位置値
・イベントタイプ・・・・吹っ飛ばされた
・パラメーター1・・・・吹っ飛ぶキャラのrigidbody2D.velocityへ入れる値(x軸のみです)
・パラメーター2・・・・攻撃主(敵キャラ)のID

→コインを取得した場合
・プレイヤーID・・・・・ゲームサーバーより割り振られたID
・プレイヤー位置情報・・コイン取得時のプレイヤーのワールド座標位置値
・イベントタイプ・・・・コインを取った
・パラメーター1・・・・未使用
・パラメーター2・・・・コインのID

※因みに、なぜ攻撃主のIDが必要かというと、攻撃主から発する効果音を鳴らす必要があるからです。敵キャラによって、殴られた時の効果音が違うので、「どの敵キャラに殴られたか」という情報が必要になっています。

ダメージ処理について
上記のパケット情報を見てみると、どれだけのダメージを受けたか、という情報を送っていないことに気づきます。そうです、プレイヤーのダメージ値情報は同期化していないのです。

空等大乱闘では、協力プレイであるというのと、簡易的なダメージ処理システム(FPSでよくあるような、ダメージを一度受けても、一定時間ダメージを受けなければ回復するというもの)であるため、今自分のヒットポイントがどれだけ残っているか、というのは重要ですが、他のプレイヤーのヒットポイントが残りどれだけであるか、というのはあまり重要ではありません。

なので、プレイヤーが死んだのか、死んでいないのか、が分かればいいのです。むしろ、他のプレイヤーのクラスのメンバー変数として、ヒットポイント値を保持してもいませんw

実装としては、「is_death」という死んだか死んでいないかどうかの判定用の変数(bool)だけを用意し、「プレイヤーが死んだ」というイベントを受け取るとフラグをonにしているだけ、ということになります。

協力プレイということや、簡易なダメージシステムにより、この実装方法が成り立っているかと思います。これが対戦型や、複雑なダメージシステムだと成り立たないかもしれません。



【武器取得処理】
空島大乱闘では、上述のように、キャラクターイベント処理は、結構単純な情報で同期化されていることが分かると思います。

しかし、武器取得イベントについては単純にはいきません。

落ちている武器を取得出来るのは、自分だけではなく、他のプレイヤーも取得することが出来るため、武器取得イベントが被る事が考えられるからです。

例えば、プレイヤーAとプレイヤーBが、落ちている同じ武器を同時に取得するイベントを発生させた場合に、お互いに自分の端末では取得成功しているが、相手方(Aから見るとB、Bから見るとA)の武器取得情報をまだ受信していない場合です。

この場合、落ちている武器を自分が取ったはずなのに、他のプレイヤーも同じ武器を取った、というイベントを受ける事となってしまいます。


これを回避するため、空島大乱闘では、ゲームサーバーを介して以下の処理手順により同期化を行っています。

→武器取得処理が成功するまでの一連の流れ
(1)プレイヤーより、武器取得リクエストをゲームサーバーへ送信する
(2)ゲームサーバーより、武器取得リクエストが成功した、というパケットをプレイヤーに送信する
(3)プレイヤーは、武器取得成功を受信すると、実際に武器を取得する処理に入る
(4)プレイヤーより、完全に武器取得処理が成功したら、終わった事をサーバーへ送信する

通常通りうまくいけば、上の処理で武器取得は成功します。しかし、以下の場合だと武器取得処理は失敗します。

・パターン1
(1)〜(3)の間に、武器取得リクエストを送信したプレイヤーが敵からの攻撃を受ける等して失敗した場合
  →この場合、(4)で武器取得が失敗した事をサーバーへ伝える

・パターン2
(1)の処理が他のプレイヤーと被った場合
  →この場合、サーバー側へ最初にリクエストパケットを到達させたプレイヤーが勝ちですw
  →サーバーから、武器取得成功パケットと、武器取得失敗パケットを、それぞれプレイヤーへ送信します

※上記パターンは代表例で、実際のプログラムはもっと複雑です

基本的には、(1)でリクエストを受けたサーバーは、当該武器をロックし、以後他のリクエストが来てもこれを受け付けません。その後、最終的に(4)で成功が来ると、そのままロック、(4)で失敗が来ると、再度ロックを解除し受付できるようにしています。



【コイン取得処理】
武器取得処理についてはそれなりにちゃんと同期化していますが、コイン取得処理は、テキトーです。

ぶっちゃけ、コイン取得はイベント被りが可能となっていますw

プレイヤーAとプレイヤーBで同じコインを同時に取得した場合、両方ともコインを取得した事になりますw

この辺は、特にコインの取得処理が被っても問題はない、ということで妥協しています♪U・ω・U



【まとめ】
今回は、キャラクターイベントの同期化について説明していきましたが、言葉だけで説明しているため、ちょっと(結構)分かりにくいかもしれません。

私に図とか絵を描くセンスがあれば、それを駆使しまくって説明したいと思うところですが、あいにく皆無です(日本語もアレですが)。

。。。とりあえず、キャラクターのイベントは基本的に重要なのでしっかり同期化していますが、(コイン取得処理のような)重要ではない処理は同期化をある程度妥協していく、という方法で実装しています!!
テーマ: Unityゲーム制作 | ジャンル: コンピュータ