Text
AddComponentMenuで整理整頓
こんにちは、中村です。最近ファミマの餃子まんを食べたのですが、おいしかったです!
さて、今回はAddComponentMenuを使ってスクリプトを取り出しやすくするお話しをしようと思います。
経緯
そもそも、今回このお話をしようと思ったのは前期特別制作でチーム制作をしていた際、チーム内にファイルの中を整理できない人がいて、そのことで苦労をすることがあったからです。
ファイルの中がちゃんと整理されていないと、人の書いたスクリプトは名前だけでは何に使われているのかわからないし、 自分が作ったものもどこにあるのかわからなくなり、探すのに時間をロスをしてしまったりと、制作中に無駄なことに時間をとられてしまうことも増えてしまいました。
だけど、ファイル整理をすることで、どこに何があるのかわかり、さらにもう使わなくなったものも見つけることができ、よりファイル内が見やすくなりました。その際、AddComponentMenuを使うことによって、スクリプトを探すときの時間を短縮することができたと思ったので今回このお話をすることにしました。
AddComponentMenuとは?
AddComponentMenuとはUnityの標準で使えるエディター拡張機能の一種で、Componentメニューにメニュー項目を追加する機能です。
実用例
例えば、敵のスクリプトを複数作った時そのままでは他のスクリプトと混ざって見づらくなってしまいます。
そこで、AddComponentMenuを使用すると、
このように、機能ごとに分けれるようになりました。
まとめ
AddComponentMenuで作ったメニュー項目と同じにファイル内にフォルダを作れば、ファイル内もきれいに整頓できるのではないでしょうか?
それでは、今回はここまでで終わりたいと思います。ありがとうございました!
2 notes
·
View notes
Text
Collisionとの衝突位置に応じて処理を分ける
お久しぶりです。 英雄伝説の最新作を時間を見つけては プレイしている中島です。 今回は見出しの通りCollisionとの衝突位置を取得して 衝突位置に応じて処理を分けていきます。
Collisionとの衝突位置の取得
まずは衝突した位置を取得するところから始めましょう。 CollisionのContactPointから取得することができます。 スクリプトにすると以下のようになります。
// Collisionと衝突した際の座標 Vector3 hitPoint; void OnCollisionEnter(Collision collision) { foreach(ContactPoint contact in collision.contacts) { // 衝突した座標を取得 hitPoint = contact.point; } }
これでCollisionとの衝突位置を取得することができました。
衝突した位置に応じて処理を分ける
先程の工程で衝突した位置の取得はできたので ここからは実際に処理を分けていきましょう。 今回は衝突したオブジェクトが自身の上か下かで 処理を分けていきたいと思います。
// Collisionと衝突した際の座標 Vector3 hitPoint; void OnCollisionEnter(Collision collision) { foreach(ContactPoint contact in collision.contacts) { // 衝突した座標を取得 hitPoint = contact.point; } // 衝突した位置が自身よりも上の場合 if(hitPoint.y > transform.position.y) { // 相手を削除 Destroy(collision.gameObject); } // 衝突した位置が自身よりも下の場合 if(hitPoint.y < transform.position.y) { //自身を削除 Destroy(gameObject); } }
今回は赤色のキューブを自身として、 上から当たったオブジェクトは消えて 下からオブジェクトに当たった場合は自身が消えます。 これで1つのCollisionで様々なあたり判定を実装できますね!
今回は以上で終わりたいと思います。 ありがとうございました。
2 notes
·
View notes
Text
【Unity】エディタ再作成によるステージ制作フローの改善【Android】
こんにちは!松元です。
夏休みも終わり、前期特別制作の発表に向けてマルチタスクな日々を送っています…!
宣伝 : TGS2017に学生スタッフとしてビジネスデーから参加します。是非、ブースまで遊びに来てください!!!
さて、今回は日本ゲーム大賞に応募した作品「Tentacroom」のエディタを改めて作った経験談をします。ですので、マネジメント寄りの話題になりますが、お聞きください。
プロジェクト概要
開発人数 : 応募時点では5人
タイトル : Tentacroom
ゲーム概要 : 「触手で爆弾をはさんで、穴に落とすパズルゲーム」
プラットフォーム : スマートフォン / Android
ステージ数 : 応募時点では24
緑色のブロック(触手ブロック)から触手をはやします。そのはやした触手たちで爆弾をはさみ、右下の穴へ運んで落としたらクリアといったパズルゲームとなっています。
旧エディタの作成経緯
ゲーム性はともかくとして、マップは特定のチップを並べるだけのシンプルな作りになっています。ですので、エディタは容易に作ることができました。(メンバーにその仕事を割り当てました)
ちょうど 似たようなものを授業で作成していたので、改変して作らせました。そのエディタが、いわゆる「旧エディタ」です。
左のエリアからマップチップを選び、クリックで配置していくエディタとなっています。
旧エディタを使用した制作フロー
先ほどのエディタを使用して制作したステージの確認までのフローがこちらになります。青枠がPCで行う作業。赤枠は実機で行う作業です。
旧エディタの問題点
このように、ステージを作成してから、実際にプレイするまでの道のりが長いです。このゲームではマルチタップを使用するので、実質、実機でしか確認できません。確認後に修正が入った場合は、最初のフローからやり直しになります。
バグなどもありましたが、応募まではこのエディタを使いました。しかし、公開までにステージ設計の修正を行う必要がありましたので、タイトルにある通り、 ステージ制作フローの改善を試みました。
新しいエディタの要件定義
新しいエディタは旧エディタより使いやすく、制作フローが早くなる必要があります。つまり、実機ですべてできれば良いのです。少なくとも、確認さえできれば大幅なフローの短縮につながるはずです。
ただし、ビルドはPCなので、PCでも実行可能なものにする必要があります。このプロジェクトでは、全員がUnityでプロジェクトの内部データに干渉できたので、Unityのプレビューでも制作できるようにします。
新エディタを使用した制作フロー
以上の要件でエディタを作成した場合のフローがこちらです。
順番が逆転し、作成してから実機で確認するまでの工程が短くなりました。これまでボトルネックであったビルドが 作成->確認 ループの外になったので、見た目以上に高速化できました。
新エディタ紹介
ということでできたものがこちらになります。
Unity上で動いている状態のものです。実機で制作するので、ボタンは大きく配置し、キャンバスはピンチ操作で拡大縮小が可能になっています。
画面上部の「Play」をタップすることで、すぐに実際のステージ上でプレイできます。
(あと普通に操作してて楽しい)
後書き
いかがでしたか?
内容のブラッシュアップも大事ですが、作業フローの見直しも大事です。旧エディタのままで制作していた場合、ステージのクオリティがあまり上げられなかったことでしょう。
ですが、旧エディタの存在は大きいものでした。エディタ作成コストが安く、作っておいて損はないものでしたので、メンバーに頼むことができました。
最初から新エディタの方針で作り始めていたら、完成はしなかったでしょう。
その関係もあって、このプロジェクトは2つのエディタが存在します。珍しいかと思いますが、参考になれば幸いです。
技術系の話題については、TGS2017にビジネスデーからいますので、是非お声をかけてください!(宣伝)
2 notes
·
View notes
Text
もしも君が「cocos2d-x フルスクリーン デバッグ」で検索したら。
どうも、野津です。
8月中、北海道にいました。涼しくもありましたが、電車の中は微冷��微風で人口密度もかなりあって汗だくな暑さでした。
もうすぐ涼しさから寒さにフェードインする季節になりますが、今年も長袖のシャツを着るのはきっとないでしょう。(※あくまで個人の予想です)
さて、タイトルに書いた、
「cocos2d-x フルスクリーン デバッグ」で検索したら。っていうの。
あれね、”とあること”をしたくて検索したのよ。
それはね、何もしてないと画面が変わってなんか動くやつ。
スクリーンセーバー!
え、しょうもなっ!(※個人の感想です)
「まず自作でできるの?」「それで使うの!?」(※始める前の疑問です)
できるそうです。簡単に。
windowsではスクリーンセーバー用の拡張子は.scrですが.exeと同じなので.exeを.scrに書き換えてインストールして設定するとできると・・・
そんな感じでできます。
で!
タイトルで検索してもフルスクリーンにする方法がAndroidOSやiOSに向けてのフルスクリーンにする設定しかかかれてなかったんですよ。
俺がしたいのはWin32だ!(※ぷんすこ)
調べた中でOpenGLレベルでいじるとかどうとかあったりしてわかる範囲でやってみたけどわからない…
ふと、AppDelegade.cppのGLViewlmpl::createWithRect()の部分ってほかの関数ないのかな的な感じで候補変換見たら…
GLViewImpl::createWithFullScreen()
ほう・・・・・・これじゃん!?
できました。これに書き換えるだけで。
これでスクリーンセーバーがつかえるぜー^^
こんな感じのができました。
花びら的な図形がふわってしてますね。

こっちはgifファイルじゃないから動かないけど円がじわぁ~って大きくなりながら消えるやつ。
//反転合成を使うための白い下地 Layer* la = LayerColor::create(Color4B::WHITE); addChild(la); //透けて背景としてみたい画像 Sprite* background = Sprite::create("testbackground.png"); background->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT); background->setPosition(0, 0); la->addChild(background); //反転合成 BlendFunc negativeBlend = { GL_ONE_MINUS_DST_COLOR, GL_ZERO }; background->setBlendFunc(negativeBlend);「
的なのをシーンかどこかにおいてパーティクルをおいてあげる。
まぁ、上の画像の場合は画像じゃなくてDrawNodeクラスで描画した図形だけど…
とりあえず、だ!
スクリーンセーバーできたからOK。
ただ、
反転合成の使い方あってるかわからない。
パーティクルにSpriteクラスを使えばもっと合成の関係性が楽になりそうになるのではと考えたけ、そのほうがいいのかな。
でも画像をただおくだけだとこんな複雑な図形を変形させながらおくのは大変そう。

ちなみに背景に使われている画像は昔に撮った二条城(京都)の庭園です。
(※何で北海道で撮った写真を使わないんだ)
ではは。
0 notes
Text
Unity Anima2D使ってみた
こんにちは、最近犬にぶつかられた中村です。
今回は日本ゲーム大賞アマチュア部門向けに制作をしている時にすごくお世話になったAssetの一つ、Unity Anima2Dについて紹介したいと思います。
Unity Anima2Dとは
Unity Anima2Dとは、2Dスケルタルアニメーション(ボーンアニメーション)を作るためのアセットです。つまり、これを使えばUnity上で画像にボーンをあてて、そのボーンに従って画像を動かすことができるようになります。
利点
では、UnityAnima2Dの良さはなんなのかと言いますと、まずテクスチャサイズの合計を小さくできるところです。今までのUnity2DのアニメーションはSpriteを複数用意して、そのSpriteを切り替えて表示することで表現していました。
しかし、UnityAnima2Dを使えば、腕や足の画像を用意してボーンをあてて動かすことで走ったり、ジャンプする動作を表現することができます。
これによって、後から新しい動作を付けたくなったとき、今までのアニメーションでは新しくSpriteを用意しないといけなかったのが、ボーンを動かすことで表現できるようになりました。
それに、Spriteを切り替えて表示するわけではないので、より動きがなめらかに動くようにもなりました。
機能
Unity Anima2Dには以下の機能が備わっています。
2D Bone
スプライトをメッシュへ
Sprite Mesh Editor
自動ウェイト
IK (Inverse Kinematics)
ポーズの保存と読み込み
Unityのアトラスと互換
ボーンにアニメーションをベイク
オニオンスキン
アバターマスクの作成
実践
実践
それでは実際に、キャラクターを動かしながらUnity Anima2Dの使い方を説明していきたいと思います。
まずは、AssetStoreからUnity Anima2DをImportします。
Importできたら使いたい画像を用意します。ここではUnity Anima2Dのデモにあるティラノサウルスの画像を使ってやっていきます。
画像を入れたら、Texture TypeをSprite(2D and UI)、SpriteModeをMultipleに変更して、Applyします。
そしたら、Inspector上からSpriteEditorを開いてSliceを押しTypeをAutomaticにしてからSliceしてApplyします。
Spriteを分割できましたら、Spriteからメッシュを作ります。やり方はProjectの中から対象の画像を選択した状態で、右クリック > Create > Anima2D > SpriteMeshをクリックします。
そうするとメッシュが作れます。
次は、メッシュにボーンをあてていきましょう。
Projectから先ほど作ったメッシュをドラッグし、Sceneビューにドロップします。
そしたら、Hierarcyから今配置したものを選択し、右クリック > 2Dobject > Boneをクリックします。これで、ボーンを作れますので、あとはボーンの位置と長さを調整してください。位置は最初のボーンはその画像の中で最も動かないところ、中心(今回の足で言うと太ももあたり、体で言えば腰のあたりなど)に配置してください。長さはInspectorの2DBoneの中にあるLengthから調整できます。
Scene上でボーンをあてましたら、次はメッシュを分割していきます。
分割はSpriteMeshEditorで行います。SpriteMeshEditorを開くには、Projectの中のメッシュを選択して、Inspector上のEdit Sprite Meshをクリックしてください。
SpriteMeshEditorを開けましたら、SpriteMeshEditウィンドウのSliceを選択して、枠をSpriteの大きさに合わせて調整し、Applyをクリックするとメッシュを分割で���ます。
このとき、Tessellationの値を大きくするとより細かく分割されます。
頂点を手動で調整したいときは、SliceToolを閉じてからマウスで操作できます。
移動‥‥頂点を選択してドラッグ 削除‥‥選択してDeleteキー 追加 輪郭内‥‥ダブルクリック 輪郭上‥‥Shift + クリック 次はウェイトを付けていきましょう。
まずは、Hierarchyから先ほどボーンをあてたメッシュを選択し、Inspector上に表示されたSprite Mesh InstanceのSet bonesの中に、一番上にあるボーンを入れます。そうすると、SpriteMeshEditor上にもボーンが表示されました。(表示されない人は左上の「ボーンと目」が描かれたマークのチェックが外れいるかもしれません。)
ボーンが表示されましたら、SpriteMeshEditウィンドウのBindをクリックしてください。そうしますと、Weight toolが右下に表示されます。
Overlay‥‥パーツにかかってい重さを色で表示する Pies‥‥頂点ごとの重さを円グラフで表示する Auto‥‥自動で重さを振り分ける
Autoで重さを自動で振り分けましたら、Applyをクリックしてください。
これで、Meshがボーンに合わせて動くようになりました。
このままでは、動かすときにボーンを一つ一つ動かさないといけなくなるのでIKをつけていきます。IKには2種類あってIK Limb 2DとIK CCD 2Dがあります。IK Limb 2Dは腕や足といった四肢に使われ、IK CCD 2Dは尻尾など四肢以外のところに使われます。
Create > 2D Object > IK LimbでIKを作ります。そうしたら、IKの位置をBoneの向かせたい位置に配置してください。そうしたら、IK Limb 2D(Script)のTargetに対象にしているボーンを入れます。このとき関節の曲がる方向を変えたい時はFlipのチェックボックスをクリックしてください。
これで、ボーンを動かしやすくなりました。では最後に、Pose機能について説明したいと思います。
Unity Anima2Dには現在のボーンの向きなどの情報を保存し、読み込む機能があります。
使い方は、一番親の階層にPoseManagerスクリプトをアタッチして、Create new poseを押すと名前を付けてPosesの中に登録できます。そして、Boneを動かしてSaveを押すとそのボーンの状態を保存できます。読み込みた��ときはLoadを押すことで保存したポーズを読み込むことができます。
今回は以上で終わりたいと思います。ありがとうございました。
0 notes
Text
ContextMenuを使って作業を効率化
みなさん初めまして!今年からGPU_RETURNSに参加しました中島です。 今回紹介させていただくのはContextMenuに項目を追加して、 Inspecter上からメソッドを実行させるというものです。 それではやっていきましょう。
ContextMenuとは
まずは、ContextMenuの説明からしたいと思います。 ContextMenuはInspecterのComponentの以下の歯車のアイコンを クリックすると出てくるメニューのことです。
それではここに項目を追加していきましょう。
ScriptにContextMenu属性を追加する
Scriptの自分が実行させたいメソッドに以下のように ContextMenu属性を追加します。
[SerializeField] GameObject Sphere; [SerializeField] Material Red; [ContextMenu("Test")] void Cnotext_test() { Sphere.GetComponent<MeshRenderer>().material = Red; }
このScriptをオブジェクトにAddComponentをして、 ContextMenuを開いてみると以下のように項目が追加されます。
項目が追加されたら準備は完了です。 さっそく実行してみましょう。
実際にビュー上で確認してみる
準備は整いました。あとは実際に確認するだけです。 以下のシーン上にあるSphereの色を変えてみましょう。
このようにゲームを起動しなくてもメソッドが 正常に動いているか確認できます。
本日はこれで終わりたいと思います。 ありがとうございました。
ContextMenuを使って作業を効率化
ContextMenuとは
ScriptにContextMenu属性を追加する
実際にビュー上で確認してみる
Expand allBack to topGo to bottom
ContextMenuを使って作業を効率化
ContextMenuとは
ScriptにContextMenu属性を追加する
実際にビュー上で確認してみる
Expand allBack to topGo to bottom
var markdown = $(".markdown-body"); //smooth all hash trigger scrolling function smoothHashScroll() { var hashElements = $("a[href^='#']").toArray(); for (var i = 0; i < hashElements.length; i++) { var element = hashElements[i]; var $element = $(element); var hash = element.hash; if (hash) { $element.on('click', function (e) { // store hash var hash = this.hash; if ($(hash).length <= 0) return; // prevent default anchor click behavior e.preventDefault(); // animate $('body, html').stop(true, true).animate({ scrollTop: $(hash).offset().top }, 100, "linear", function () { // when done, add hash to url // (default click behaviour) window.location.hash = hash; }); }); } } } smoothHashScroll(); var toc = $('.ui-toc'); var tocAffix = $('.ui-affix-toc'); var tocDropdown = $('.ui-toc-dropdown'); //toc tocDropdown.click(function (e) { e.stopPropagation(); }); var enoughForAffixToc = true; function generateScrollspy() { $(document.body).scrollspy({ target: '' }); $(document.body).scrollspy('refresh'); if (enoughForAffixToc) { toc.hide(); tocAffix.show(); } else { tocAffix.hide(); toc.show(); } $(document.body).scroll(); } function windowResize() { //toc right var paddingRight = parseFloat(markdown.css('padding-right')); var right = ($(window).width() - (markdown.offset().left + markdown.outerWidth() - paddingRight)); toc.css('right', right + 'px'); //affix toc left var newbool; var rightMargin = (markdown.parent().outerWidth() - markdown.outerWidth()) / 2; //for ipad or wider device if (rightMargin >= 133) { newbool = true; var affixLeftMargin = (tocAffix.outerWidth() - tocAffix.width()) / 2; var left = markdown.offset().left + markdown.outerWidth() - affixLeftMargin; tocAffix.css('left', left + 'px'); } else { newbool = false; } if (newbool != enoughForAffixToc) { enoughForAffixToc = newbool; generateScrollspy(); } } $(window).resize(function () { windowResize(); }); $(document).ready(function () { windowResize(); generateScrollspy(); }); //remove hash function removeHash() { window.location.hash = ''; } var backtotop = $('.back-to-top'); var gotobottom = $('.go-to-bottom'); backtotop.click(function (e) { e.preventDefault(); e.stopPropagation(); if (scrollToTop) scrollToTop(); removeHash(); }); gotobottom.click(function (e) { e.preventDefault(); e.stopPropagation(); if (scrollToBottom) scrollToBottom(); removeHash(); }); var toggle = $('.expand-toggle'); var tocExpand = false; checkExpandToggle(); toggle.click(function (e) { e.preventDefault(); e.stopPropagation(); tocExpand = !tocExpand; checkExpandToggle(); }) function checkExpandToggle () { var toc = $('.ui-toc-dropdown .toc'); var toggle = $('.expand-toggle'); if (!tocExpand) { toc.removeClass('expand'); toggle.text('Expand all'); } else { toc.addClass('expand'); toggle.text('Collapse all'); } } function scrollToTop() { $('body, html').stop(true, true).animate({ scrollTop: 0 }, 100, "linear"); } function scrollToBottom() { $('body, html').stop(true, true).animate({ scrollTop: $(document.body)[0].scrollHeight }, 100, "linear"); }
0 notes
Text
―― apkの起動が遅くなってしまった時の対処法 ――
こんにちは!
カラオケでテンションが上がってヘドバンをしていたら、眼鏡が吹っ飛んでいき、レンズが少しだけ欠けたさいとぅーです!

一歩外を出たら汗が止まらない時期になってきてしまいましたね…。
この時期は暑いしジメジメしていて、外に出歩きたくなくなってしまいます。
が。
その一方でお祭りなどといった、楽しいイベントもたくさん開催される時期です!
お祭りなどの催し物は、"人を楽しませる"とはどういうことなのかを学ぶことも出来るので、積極的に参加していきたいですね!
私も先日、日本ゲーム大賞アマチュア部門の応募が完了したので、心置きなくイベントなども含めて色々と楽しみたいと思います!
さて、では前置きはこの辺にして本題に入っていきましょう。
うわっ…私のapk、起動遅すぎ…?
それは、私が開発しているゲームをapkにして、実機でテストプレイしようとしたときのことです。
今までは普通に、スプラッシュスクリーンからタイトルまでの流れがさくっと進んでいたのに、何故か急にタイトル表示までに、30秒から1分ぐらいの間が出来てしまいました。
タイトルまで時間がかかるのはさすがにやばいと思い、血眼になって調べること半日。
原因と対処方法を見つけることが出来ました。
Load in Background
原因はオーディオデータのロード時間でした。
Unityはデフォルトだと、シーンが再生される前にすべてのオーディオデータがロードされるという設定になっているようです。
今回の場合はその再生前のロードに時間がかかり、結果的にタイトル表示が遅くなってしまっていました。
では、どうすればいいのか。
対処法をご紹介したいと思います。
オーディオデータを選択した状態でインスペクターに表示される
「Load in Background」
という項目にチェックを入れます。
これにチェックが入っていると、音を再生するタイミングになってからオーディオデータをロードするらしく、ロード時間を短くすることができました。
ただし、ロードするまでに若干のラグが出てしまうそうなので、それも防ぎたい…!
ということで、そちらも対処法を書いていきたいと思います。
音ズレ解消
Edit->ProjectSettings->Audioを選択、
AudioManagerのDSPBufferSizeをBest Latencyに設定。
そうすることで、少し音が劣化してしまいますが、音ズレは回避することができます。
モバイルのゲームを作っていると、ちょくちょく音ズレしてしまう場合がありますので、こちらはいつも設定しておくと安心ですね。
今回は以上で終わりたいと思います。
0 notes
Text
cocos2dxにADX2LEを導入した話 音データ作成からcocos2dxでの再生まで その3
こんにちは 佐藤です。投稿が遅れ申し訳ありません。
前回は、ADX2LEの導入までやりました。
こちらは3回目ですので、1回目、2回目を見てからご覧ください。
http://gpu-returns.tumblr.com/post/161349191529/cocos2dxにadx2leを導入した話-音データ作成からcocos2dxでの再生まで-その1
http://gpu-returns.tumblr.com/post/161459569884/cocos2dxにadx2leを導入した話-音データ作成からcocos2dxでの再生まで-その2
今回は、音を「 HelloWorldScene 」で再生したいと思います。
ソースの読み込み
前回、プロジェクトのClassesフォルダに「 AtomUtil.cpp 」「 AtomUtil.h 」
「 main.h 」を入れたので、こちらをVisual Studioに読み込みます。
ソリューションエクスプローラー→src右クリック→追加→既存の項目から
読み込みます。
ADX2LEの初期化・終了処理
ADX2LEの初期化処理・終了処理を行うため「AppDelegate.cpp」を
書き換えていきます。
初期化処理
register_all_packages();の下あたりに、
criadx2le::initialize();と入力します。
終了処理
AppDelegateのデストラクタ内に、
AppDelegate::~AppDelegate() { criadx2le::finalize(); }
これで初期化・終了処理は完了です。
音を鳴らす
いよいよ音を鳴らしていきたいと思います。
音を鳴らすために「HelloWorldScene.cpp」と「HelloWorldScene.h」に
処理を記述していきます。
HelloWorldScene.h
「AtomUtil.h」と「 main.h 」をincludeします。
#include “ AtomUtil.h ”
#include “ main.h ”
「HelloWorldScene.h」はこれで完了です。
エラー!
あとは「HelloWorldScene.cpp」に再生処理を書けば鳴るのですが、
自分はここでエラーがでてしまいました。
なぜか 「AtomUtil.h」内の #include <cri_adx2le.h> がincludeできないと
言われてしまいました。
おかしい... ちゃんと設定したはずなのに...
対処法を記述していきます。※エラーが出てない方は飛ばしてください。
adx→include→pcの中にある.hを全てコピーし、プロジェクトのClasses内に
張り付けします。
そして読み込みます。
これでエラーが取れているはずです。試しにビルドしてみましょう。
またエラー!
大量のリンクエラーが出てしまいました。
「HelloWorldScene.h」内の #include “ main.h ” の下あたりに
#pragma comment(lib,"../adx/libs/pc/x86/cri_ware_pcx86_le_import.lib")
と入力します。
ビルドしてみます。音は鳴りませんがビルドできました。
では、ついに音を鳴らす処理を記述していこうと思います。
HelloWorldScene.cpp
criadx2le::loadAcbFile("(作ったacbファイル名)", "(作ったacfファイル名)"); currentPlaybackId = criadx2le::playCueById(自分の曲のID);
自分の曲のIDは 「main.h 」内の
上の赤枠で囲った部分です。
ここまでできたらビルドしてみましょう。
音はなりましたか?音が鳴ったら成功です。
自分もADX2LEはまだ音をループでならせるぐらいしか使いこなせませんが、
使いこなせたらゲームのクオリティもアップすると思うのでぜひ
使ってみてください。
長くなりましたが、これで終了します。
ありがとうございました。
0 notes
Text
WindowsPCでiPhoneのUnityRemote5を扱う
はじめまして!
今年から(飛び入りで)GPU_RETURNSに参加しましたしげやまです。 といっても昨年から同じ学年のGPUメンバーの方々と放課後の残って制作を行ったり、何故かGPUのイベントに参加させていただいたりとなかなか変なポジションにいました。
閑話休題
今回はUnityRemote5について少しだけ話させていただきます。 それも「スマホ向けのゲームを開発してるけどパソコンはWindowsで使ってるスマホはiPhoneだから手軽にテストできないよー」という方向けの随分と的を絞った話になります。 実際僕もその一人で、学校から支給されているパソコンがWindows、スマホはiPhoneです。(こういう人割と多いのでは?)
そもそもUnityRemote5ってなんぞや
UnityRemote5とは、Unityでビルドしなくても再生するだけでスマホでテストプレイができるようになるアプリです。 シンプルですがこれによって作業が止まらず効率がかなり上がります。
用意するもの
UnityRemote5を利用する際に事前に準備しておくものがいくつかあります。
iPhoneにUnityRemote5をインストールする
パソコンにiTunesをインストールする
iOS Build Supportをインストールする
上記の中で分かりにくそうな3つ目のインストール方法についてです。 いくつか方法はありますが、Unityのインストーラーを起動して、iOS Build Supportの部分にチェックをいれてインストールを行う が一番簡単ではないかと思います。
Unity上の設定
まずはiPhoneをパソコンに接続します。(初回だとデバイスのインストールが始まります。)
接続出来たらUnity上でBuildSettingsを開きます。 まずPlatformの設定をiOSに変更します。(iOSを選択して左下のSwichPlatformをクリック) 次に再生したいシーンをセーブしておきます。(これ忘れがちです。)
次にUnity上で Edit>ProjectSettings>Editor と開いてください。 するとInspectorでUnityRemoteの設定を画面が開きます。
Device
自身の使っているiPhoneを選択
Compression
PNG設定のほうが画質は良くなるが処理は重くなる
Resolution
Downsize設定のほうが若干処理が軽くなる
JoystickSource
そのまま
ここで一回再生してみます。
すると表示はされますがcubeが潰れてしまっています。
そこできれいに表示されるようにします。
BuildSettingsを開いてPlayerSettingsをInspectorに表示させます。
Settings for iOSの中の Orientationで縦表示、横表示を設定できます。
横表示はDefaultOrientationをLandscapeRightまたは、LandscapeLeftに設定します。
縦表示はPortraitに設定します。
この横表示か縦表示かによってアスペクト比を設定します。
僕の場合はiPhoneSEを使用しているので、
横の場合は、iPhone 5 Wide(16:9)
縦の場合は、iPhone 5 Tall(9:16)
に設定します。
この状態でもう一度再生すると
きれいに表示されました。
使用してみて
数フレーム遅延が発生しているように思いますが簡単なテストプレイであれば問題なく動いてくれます。
冒頭でも話しましたが作業効率が段違いに上がるので機会があればUnityRemote5使用てみてはいかがでしょうか?
今回の記事はこれで終わります。
最後まで読んでいただきありがとうございました!
0 notes
Text
【UNITY】【C#】NULL許容型でタッチ座標を取る
こんにちは!まつもとです。じわじわと暑くなってきた今日この頃、いかがお過ごしでしょうか?
私は、暑い外と寒い部屋に挟まれながら生きてます。関係ないですね。
ここから本題です。GPUの上級生はだいたいC++、私たち2年生と1年生はC#といった絶妙なバランスのゼミですが、ここでがっつりC#の記事を投下したいと思います。
(これで、C#もええやん勢が増えてくれるといいなぁ、ふえてっ)
ただC++のNULLとC#のnull、割と違うと思いますので、C#のnullから解説していきたいと思います。知っている方は飛ばしていただいて構いません。
C#のnullのおさらい
C#は学習コストは高いですが、逆に学べば学ぶほど使えるスルメのような言語です。まずはC#におけるnullをおさらいしておきましょう。
class Program { /// /// デモ用の意味のないクラス /// class Demo {} static void Main(string[] args) { //初期値にnullを代入 Demo demo = null; } }
C#でのnullはnullです。C++で言うところのnullptr的なところでしょうか。理解してほしいのは、0ではなく"存在しない"ということです。
null許容型とは?
null許容型とは、その名の通り"通常の値 + null"が入る型です。C++系の人には違和感抜群だと思いますが、C#では実装できてしまいます。
早速コードを見てみましょう。
class Program { static void Main(string[] args) { //変数iをnull許容のint型で定義 int? i = null; } }
このようにして使うことができます。?マークを添えるだけなので簡単ですね!
今回の仕様
今回の仕様は、タッチしているかも検出したいし、座標も知りたかったので、Vector2のnull許容にしました。
さらに、androidの仕様でタッチ情報は10個取れるので、一気に全部取ることにします。
こちらが私が実際に使っているUnityのコードです
/// /// すべてのタッチ入力を取る /// /// out 位置(null許容) /// 一つでもあればtrue public static bool GetInputAll(out Vector2?[] pos) { //初期化 pos = new Vector2?[10]; //エディタ上かどうか判定 if(Application.isEditor) { /* エディタの時の取得方法は省略 */ } else { //入力されているTouchをすべて回す foreach(var t in Input.touches) { pos[t.fingerId] = t.position; isTouchArray[t.fingerId] = true; } } bool ans = false; foreach(var p in pos) { if(p != null) { ans = true; break; } } return ans; }
Vector2?の初期値がnullであることを利用して、見つかったタッチ情報だけ代入しています。
これにより、入力があるかどうかをnullで判定し、nullでなかった場合は座標がそのまま入っていることになるので非常にコンパクトです。
おわりに
よくint型の変数に-1を入れておくことで、値が入っていないことにする処理を見かけます。しかし、マイナスも利用する場合使えないです。これをnull許容型にしてしまえばnullを代入するだけでよくなり、コードの可読性も上��ります。なので、使いどころがあればぜひ使うべきだと思います。
今回はnull許容型でしたが、C#は他にもいっぱい機能があるので、興味のある方はぜひ調べてみてくださいね!(C#いいぞ~勢増えろっ)
0 notes
Text
時間はなくとも”エディタ”は作る。
さぁ、記事を書いていこう。
3年の「のづ」です。少し前に久しくアーケードの音ゲーをやったのだが、気付いたことがあった。
(……あれ?目と体が追いつかない!?)
ずいぶんと下手になってる…。
あと自分のやり方が雑になっていて、やっていた頃の俺はどうやっていたんだろうと聞きたいところだ。
それと、いつもゲームをやりながら考えている。
音ゲーって譜面データたくさんあるよなー。と。
一つの曲に難易度が3つか4つある。
例えば
難易度が「easy」、「normal」、[hard]の3つがあるとする。
譜面のデータには0から9までの1桁の数字が入るとすると
こんな感じのデータをプログラマが決めた法則に基づいた文字の並びでテキストファイルもしくはバイナリファイルとしておいておき、ゲーム画面で読み込む。
のような流れになる。
ここで考えることがある。
・譜面のデータを変える時はどうするか
・法則の知らない人(作った人以外)がそのデータを変更したりするのか
昔の俺はこう考えた。
1つ目に関しては、わかるなら、そのデータを開き、書き換えることができるなら、書き換えればいい。
2つ目は、決めた法則を変更する人に教えて、できるようにすればいい。
昔の俺「よし、これで問題はなくなった!!」
今の俺「………まてまて!!問題は解決していないぞ!!!」
この方法でいざ作っていくと、easyの3つ目は5から8に変更するから、初めの文字からいち、にい、さん、ここを書き換える、と。
次はhardの34こ目を9から3にするから、えーと、どこが34こ目なんだ?
さらに0から9までならまだしも、アルファベットも変更するものだったりするならもう訳が分からない。このままいくと、難易度が3つある1つの曲を作るのにどれだけの時間がかかるのだろうか。
さらに言うと、一つの曲では、作ったゲームもその曲を聴くだけの音楽プレイヤーと化してしまうので、振り返ると、意外と無駄な時間を使っていたんだと感じる。
で、だ。
この膨大にかかりそうな時間を減らそうではないか。
そう、エディタ(ツールとも言える)で!
あ、ようやく本題です。
今年の1月ごろに作ったゲームで、
ブロックの上を走り続けてジャンプしながらゴールに進むゲーム作ったんだけど。
これね、1ステージがそんなに長くないから、たくさんのステージが必要だったんだよね。
さっきの音ゲーの話にすると、緑のブロックが「N」で黄色のギザギザブロックが「#」みたいな感じで、
こんな感じで作ってた。
一行目のはレベルとか全体の幅と高さとか基本情報のデータが入ってる。
(これを制作した後に知ったがtxtファイルは扱いづらいらしい)
これを書き換えて行くとステージも変わるんだけど、見てて本当の画面にNとかTとかでないからわかりにくい。
それがこうなるとどうなる?
なんかゲームの画面に近くなった。
マウスの操作でステージが作れる。
これだけでもだいぶ楽になり、作業効率もよくなる。
このエディタは、VisualStudioのC#言語で使える、Windowsフォームアプリケーションで作ったのだが、基本さえ押さえておけばすぐに作れる。
VisualStudioから新しいプロジェクトを開いてC#のWindowsフォームアプリケーションを開くとこんな感じの画面が出てくる
この中央の小さなウィンドウが今回のエディタの画面になる。
左側にある、ツールボックスから、いろいろなものをこのウィンドウにつけることができる。
画面の大きさを変えて、テキストを入力するところを置いて、ボタンを置いて…
うん、いい感じ。
追加したのは
「TextBox」が1つ、「Button」が2つ、
そしてデータの読み込みを行う「OpenFileDialog」と「SaveFileDialog」のみ。
ここからがコーディング。
読み込むボタンをダブルクリックすると、クリックしたときに処理されるメソッドが作られるので、そこに処理を書く。
保存するボタンも同様に書いていく。
using System; //テキスト読み込みに使う using System.IO; //プロジェクト>参照の追加>アセンブリ>フレームワーク>Microsoft.VisualBasicをチェックで使用可能 using Microsoft.VisualBasic.FileIO;namespace test { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void 読み込むボタン_Click(object sender, EventArgs e) { openFileDialog1.FileName = "ChoseFile"; openFileDialog1.InitialDirectory = "C:\\"; ; openFileDialog1.Filter = "バイナリファイル(*.bin)|*.bin|テキストファイル(*.txt)|*.txt|すべてのファイル(*.*)|*.*"; openFileDialog1.FilterIndex = 2; openFileDialog1.Title = "開くファイルを選択してください"; if (openFileDialog1.ShowDialog() == DialogResult.OK) { TextFieldParser tf = new TextFieldParser(openFileDialog1.FileName, System.Text.Encoding.GetEncoding("shift_jis")); tf.TextFieldType = FieldType.Delimited; //データの読み込み string loadText = tf.ReadToEnd(); tf.Close(); //読み込んだデータをほしい場所に入れてあげる。 textBox1.Text = loadText; } } private void 保存するボタン_Click(object sender, EventArgs e) { saveFileDialog1.Filter = "バイナリファイル(*.bin)|*.bin|すべてのファイル(*.*)|*.*"; saveFileDialog1.FilterIndex = 0; saveFileDialog1.Title = "保存先のファイルを選択してください"; if (saveFileDialog1.ShowDialog() == DialogResult.OK) { StreamWriter sw; //Excelで開けるようシフトJISで保存 sw = new StreamWriter(saveFileDialog1.FileName, false, System.Text.Encoding.GetEncoding("shift_jis")); sw.Write(textBox1.Text); sw.Close(); } } } }
こうして、ここにテキストを入れてください。と書かれたところを保存することができる。
簡易的にコマンドを保存するエディターだとするとこうなる。
あとは、ゲームに必要な物を盛り込んでいって、よりよいものにしていくとよい。
画像を描画したり、モード変更のボタンを用意したり……
必要性について
エディタがあるといいことは
・時間の短縮になる
・直接値を変えることがないのでゲームで読み込むときに読み込みエラーを起こさなくなる。
だと思う。
ただ、さっきからエディタエディタと言っているが、悪く言うと、本来のゲームには出てくることのないものである。
なら、なぜ必要か?
それは時間短縮がされ、作業効率が良くなる。という部分が大きい。
(個人的に直接データの値を書き換えているとイライラする)
作り方によっては、1時間で1つのマップを作るより、10分で2つ作れるといったものもできる。
そのようなことを実現させるなら、ある程度ゲームができてきたときに、一息、エディタを作ってみてはどうだろうか。
1 note
·
View note
Text
JavaScriptの変数について
はじめまして、かすがいです! 今年度からGPU_RETURNSに新しく参加させてもらっています。
技術系の記事はQiita以外で投稿したことがないので、さて何を書いたものか・・・ 過去の投稿を見たところUnityとCocos2dxの記事が多い印象でしたが、私は普段その2点を使わないので、初心者ながら言語について書いていこうと思います。
プログラミングを始めてすぐの人には伝わり辛いと思いますが、世のプログラマー各位は複数の言語を使えるかと思います。 複数の言語を扱えることは個人にとって将来的な選択の幅を広げるだけでなく、学習面においても深い理解のキッカケになりやすいので強く勧めたいと思っています。
私はというと、多く使用するのはC++とJavaScriptの2つです。 よく間違えられるのですが、私が一番好きな言語はJavaScriptだったりします。
JavaScriptは近年ものすごい成長を遂げている今超ホットな言語なのですが、しばしば誤解をされていることが多いです。
ローカルファイルを扱えない(FileAPIで少しずつ解消されています
サーバサイドが出来ない(Node.jsで解決可能です)
Javaの知り合い(名前が似てるだけで仕様は一切違います)
遅い(・・・)
等々、他にも色々ありますが、一番よく聞くのは変数についてでしょうか。 今回はJavaScriptでよくある誤解の一つ、変数について書いていこうと思います。
○型について
まずは基礎の基礎である型について軽く説明していきます。 C++やC#などの言語を使ってる人は以下のコードが読めるかと思います。 int i = 10; char c = 'a'; bool b = true;
これをJavaScriptで書くとこうなります。 let i = 10; let c = 'a'; let b = true;
少し違和感がありませんか? letという型の中に何から何までごちゃまぜで入っているように見えますが、JavaScriptはこれが正解なんです。 では、JavaScriptの型はletしかないのか?と言うと少し違います。 JavaScriptには内部的に
数値型(C++でいうdouble)
文字列(C++でいうstring)
真理型(C++でいうbool)
の3つの型が存在します。(正しくは3つではないのですが、とりあえず3つと言うことで話を進めます) しかし、型の指定は自動でやってくれるんです。 さすが!超ホットでクールなJavaScriptは気遣いも完璧ですね!!
冗談はさておき、JavaScriptも内部ではしっかりと型を持っていることはまず最初に意識してほしいです。 他言語でもお馴染みの等価演算子(==)もJavaScriptにはもうひとつ存在します。以下を見てください。 let a = 10; let b = "10"; let c = (a == b); //true let d = (a === b); //false
cには同じ数値を比較した結果のtrueが入っています。 しかし、dのように=が3つ並んだ場合は数値が同じでも内部の型が違う為falseが入ります。
dをtrueにしたい場合はどちらかを型変換しないといけないので以下のように書くといいでしょう。 let d = (a === Number(b)); //bが数値型に変換されているためtrue let d = (String(a) === b); //aが文字列に変換されているためtrue
型については以上です。 もう一度言いますがJavaScriptにも型はあります。ただ、見えないだけなんです。
○変数の宣言方法について
さて、JavaScriptを少しでもやったことのある人なら今までの件で疑問に思うことがあるかも知れません。
私はこれまで変数を宣言するときに「let」を使ってきました。 しかし、今日のJavaScriptでは変数を宣言するときに「var」を使う人が圧倒的に多いです。
(変数の宣言方法としてはもう一つ、他のプログラミング言語でも比較的メジャーな「const」もあります)
では、「let」と「var」、「const」の違いとは何かというのを紹介していきます。
少し行儀が悪いですが、以下のC++のコードを見てください。 int a = 10; { int b = 10; } cout << a << endl; //出力:10 cout << b << endl; //error
まず最初にaを宣言し10で初期化しています。 次に無名スコープ内でbを宣言し10で初期化しています。 最後の2行で2つの変数をそれぞれ出力しようとしていますが、bはスコープ内で宣言された為にエラーになってしまいますね。
それでは今度はJavaScriptのコードです。 { var a = 10; let b = 10; const c = 10; } console.log(a); //出力:10 console.log(b); //error console.log(c); //error
C++のように無名スコープを作成し、その中で3種類の方法で変数を宣言しています。 そして同じようにスコープ外でそれぞれを出力しています。(console.logは出力演算子のようなものだと思ってください)
さて、これで少なくともvarの正体は分かったはずです。 ものすごく浅く簡単に言い表すと、varにはブロックスコープが効かないんですよね。 if文やfor文の中で宣言したものでも外からアクセス出来てしまう事態だって発生します。 その点letはvarと違い、他言語の変数の挙動とほぼ同じです。 他の言語を使ったことがある人にとってはletこそが普通の宣言方法で、それがletを使うべき最大の理由だと私は思います。
私はよくWeb上に存在するホームページのソースを見ているのですが、letの普及はまだ半ばといった感じです。 他にもletを勧める記事は多く存在しますが、それでも全体で見ればごく少数です。なので、少しでも早く一般化されるようにと思い、私も書くことにしました。
ちなみにconstは以下のように、再代入・再宣言が不可なletです。 const a = 10; a = 20; //error
変数宣言については以上です。 先で私は「letを使いましょう」と勧めましたが、人によってはconstを優先的にと言う人もいます。 それに関してはインクリメントの前置後置派閥のようなものなので個々で決めても大丈夫だと思います。
本当ならこの何倍も書きたいところなのですが、読み返してみると思ったより長くなってました。 文章量を少なく、コードを多くして解説するのって難しいですね・・・
今回はJavaScriptに関してでしたが、それに限らず色々な言語を試してみるとできることの幅もきっと広がると思います。 身近に同じ言語を使える人が増えると技術共有もしやすいですし是非2つ目、3つ目…と試していってみてはどうでしょうか?
0 notes
Text
cocos2dxにADX2LEを導入した話 音データ作成からcocos2dxでの再生まで その2
こんにちは。佐藤です。こちらは2回目の投稿ですので、
1回目を見ていない方は、見てからご覧ください。
http://gpu-returns.tumblr.com/post/161349191529/cocos2dxにadx2leを導入した話-音データ作成からcocos2dxでの再生まで-その1
今回は、cocos2dxにADX2LEを導入と
前回作成した音データをcocos2dxで再生してみたいと思います。
ADX2LE導入&音データ配置
cocos2dxのプロジェクトは作ってあるものとします。
まず、cocos2dxのプロジェクト直下に「adx」というフォルダを作成します。
次に、Cドライブに配置したcriフォルダの中のcocos2dxフォルダの中に
「docs」「include」「libs」「samples」の4つのフォルダがあると思います。
この中から、「include」「libs」フォルダをコピーし先ほど作成した
adxフォルダ内に張り付けします。
プロジェクトフォルダ→adx→libs→pc→x86→cri_ware_pcx86_le.dllを
コピーしプロジェクト直下に張り付けします。
プロジェクトフォルダ→proj.win32→Debug.win32内にも張り付けします。
※Debug.win32がない場合は一度ビルドすると出てくると思います。
ここまでできたら、音データを入れていきたいと思います。
音データは、「Frog.acf」「Frog_acf.h」「main.acb」「main.h」の4つが
ありますが、今回使うのは 「Frog.acf」「main.acb」「main.h」の3つです。
「Frog.acf」「main.acb」 をプロジェクトのResources内に入れます。
「main.h」 をプロジェクトのClassesに入れます。
これで、音データが入りました。
次にVisual Studioの設定をします。
Visual Studio設定
メニューバー→プロジェクト→(プロジェクト名)のプロパティを選択
このような画面が開くと思います。
構成プロパティ→VC++ディレクトリ→インクルードディレクトリ→編集
プロジェクトフォルダ→adx→include→pcまでパスを通します。
次に、構成プロパティ→VC++ディレクトリ→ライブラリディレクトリ→編集
プロジェクトフォルダ→adx→libs→pc→x86までのパスを通します。
リンカー→全般→追加のライブラリディレクトリ→編集
プロジェクトフォルダ→adx→libs→pc→x86までのパスを通します。
リンカー→入力→追加の依存ファイル→編集で
「cri_ware_pcx86_LE_import.lib」を追加します。
変更できたら、cocos2dxで音を鳴らしていきましょう。
音を鳴らす前に
今回、音を鳴らすにあたっての補足説明をします。
・音を鳴らすシーンは、cocos2dxのプロジェクトを作った時にできる
HelloWorldSceneとします。
・ADX2LEは使うときに初期化処理などをしなければいけないのですが、
今回は、ADX2LEをダウンロードした時についてくるサンプルの中に
初期化処理をしてくれるものがあるのでこれを使用します。
cri→cocos2dx→samples→criatom→programs→AtomSamples→Classes
の中にある「AtomUtil.cpp」「AtomUtil.h」をプロジェクトの Classesフォルダ
にコピーします。
今回はここまでにしようと思います。
音を鳴らすところまでやりたかったのですが、予想以上に長くなってしまった
ので申し訳ありませんが、次回紹介しようと思います。
ありがとうございました。
0 notes
Text
Cocos2d-xやろうよ!
こんにちは。なみせです。学年変わって初の投稿です。
新しく1年生も加わってこれからが楽しみです。
現在はそれぞれ制作を行っていますが、ゼミ内ではUnity率が高いのです。 私は1年の冬に先輩からCocos2s-xやC++について教わったので、私も「Cocos2d-xはいいのだよ。」ということを紹介をできたらと思います。
難しいプログラム用語等による正確さよりわかりやすさを優先し、 Unityについても交えて紹介していこうと思います。 ですので、細かい言い回しについては少しだけ目をつむっていただけたらと思います。
※ここではCocos2d-xのセットアップが終わったとして話を進めます。(Windows勢はそこで一度つまづくんだけどね。)
まずCocos2d-xでは、Scene, Layer, SpriteというNodeを “継承” したクラスを用いてプログラムを組みます。
Sceneはなんとなくわかるけど...他は?と思ったりするかもしれませんが、それについては後半で紹介していきます。
まずは、“継承” について説明しようと思います。
ゲームを作る際、Unityでは下の図のように...
移動用, Player用, Enemy用のスクリプトをそれぞれ書き、「Player」にはPlayer用と移動用の, 「Enemy」にはEnemy用と移動用のスクリプトをオブジェクトに当てていたと思います。
しかしCocos2d-xでは...(というよりC++では。ですが)
移動用スクリプトをそれぞれのスクリプトに『含めた』状態であるPlayer用+移動用スクリプトをオブジェクトに当てます。この、あるスクリプトにほかのスクリプトを『含める』ために用いるのが ”継承” です。
下のプログラムでは、Sceneを “継承” してGameSceneを作っています。
こうすることで、下のプログラムではパッと見GameSceneクラスに3つしか中身(関数)がないように見えますが、Sceneクラスという予め定義されていたクラス内の要素(変数、関数)も使えるのです。
class GameScene : public cocos2d::Scene { public: static GameScene* create(); bool init(); void update(float delta); }
さて、ここからはCocos2d-xでのScene, Layer等の用語や「UnityにとってのこれはCocos2d-xでは?」について、説明したいと思います。
クラス
・Sceneクラス
名前の通りSceneです。Unityと似たような認識でいいと思います。
TitleScene、GameScene等作ってゲームの進行により切り替えていきます。
・Layerクラス
UI(HPゲージ等)とキャラクター等の表示順(重ね順)を指定するために用います。
後から貼り付けたものが、画面の前に表示されます。(Layerに限らず)
・Spriteクラス
画像を表示するために用います。Player等は、このSpriteを継承して作ることで、画像の扱いがほんの少し楽になります。
・Nodeクラス
実は上3つのクラスはこのNodeを継承して作られているので、Nodeは基本的な要素が詰まったクラスです。
上のどの要素も必要でないようなマネージャー等を作るときに継承させます。
関数
・bool init();
bool GameScene::init() { if(!Scene::init()) return false; /* ここに処理を書きます */ return true; }
Unityでいうところのvoid Start()です。最初に呼ばれるので、初期化や定義は基本的にここで行います。(コンストラクタから呼ぶため、実はコンストラクタが先)
・void update(float delta);
void GameScene::update(float delta) { /* ここに処理を書きます */ }
Unityのvoid Update()と同じで毎フレーム行う処理をここに書きます。
まず、引数(括弧内)にfloat deltaと書かれていますが、float型の引数が必要です。この中には毎フレームの経過時間が入ってくるので、この値を足すことで時間を計算することができます。(多少の誤差あり)
しかし、Cocos2d-xではupdate関数を宣言, 及び定義しただけでは毎フレーム呼ばれません。(私はこれで時々つまづきます)
void GameScene::init() { if(!Scene::init()) return false; // ↓必ず必要な1文 this->scheduleUpdate(); return true; }
init()内で上のような1文を書く必要があります。これさえ書けば毎フレーム呼ばれます。
基本的な紹介はできたでしょうか。少し触ってみようかなと思っていただけたら嬉しいです。
このブログには他にもCocos2d-xを触っている人が記事を書いたりしていると思いますので、見てみてください。
最後まで読んでいただき、ありがとうございました。
この記事が少しでもお力になれば幸いです。
0 notes
Text
cocos2dxにADX2LEを導入した話 音データ作成からcocos2dxでの再生まで その1
こんにちは。佐藤です。今回はcocos2dxにADX2LEを導入したので、
その時の話と導入の方法を紹介したいと思います。
その前に、ADX2LEって何?という方がいると思うので紹介から始めます。
ADX2LEとは
CRI・ミドルウェア様が提供しているサウンドミドルウェアです。
ADX2LEを導入するメリットは
cocos2dxでは難しいイントロ付きのBGMの再生・途切れのないループや、
フェードイン・フェードアウトなどさまざまなサウンド演出を簡単に
表現できたりすることです。
今回の目標は、
「自分で作った音データをcocos2dxで再生する」
です。
では、本題に入ります。
開発環境
cocos2dx 3.10
Visual Studio 2015
ADX2LEインストール
まず、ADX2LEをサイトからダウンロードします。
http://www.adx2le.com/index.html
ダウンロードしたフォルダを解凍すると、「cri」というフォルダがあると
思うのでこのフォルダをCドライブ直下に配置します。
プロジェクト作成
手元に「かえるのうた.wav」があったので今回はこれを再生します。
先ほど配置したcriフォルダから
cri→tools→criatomex→CriAtomCraft.exeを起動します。
起動するとこのような画面が開くと思います。
プロジェクトを作成していきます。
メニューバーのファイルからプロジェクトの新規作成を選択します。
選択すると新規プロジェクトという画面が出てくるので、プロジェクト名を
変更しましょう。
今回はFrogにしました。変更したら新規プロジェクトと書かれた赤いボタンを
クリックします。
クリックするとワークユニットの追加という画面が出てきます。
ワークユニット名は、今回はプロジェクト名と同じにしておきましょう。
変更したら追加をクリックします。
これでプロジェクトの作成ができました。
次に、マテリアル(上の画像で赤く囲った部分)に
音声ファイル(今回はかえるのうた.wav)
をドラッグ&ドロップします。
入れることができたらマテリアルの上にあるワークユニットの中の
「CueSheet_0」を右クリック→名前の変更で「main」にリネームします。
そして、リネームしたmainを右クリック→新規オブジェクト→
「キュー「ポリフォニック」の作成」をクリックします。
右側のキューリストに「Cue_0」が作成されていれば成功です。
これも「bgm」にリネームします。
音データ作成の準備ができたので、作成していこうと思います。
音データ作成
ワークユニットの中のmain→bgmをクリック
クリックすると右側がタイムラインに切り替わります。
マテリアルの中の音声ファイル(かえるのうた.wav)をタイムラインにドラッグ&ドロップします。
青い部分が音の長さです。
ここまでできたら1回再生してみましょう。
再生ボタンを押して再生します。(上の画像で赤く囲った部分)
音は再生されましたか?
再生されれば成功です。
では、BGMなのでループの設定をします。
タイムライン上で右クリック→新規オブジェクト→マーカーの追加...を選択
選択するとこのような画面が出てくるので、タイプを「シーケンスループ」、
ループ設定を「無限ループ」にして、追加をクリックします。
緑色のマーカーが出現したと思います。
このマーカーの範囲内がループ範囲です。
今回はBGMをループさせるだけなので、マーカーを音の始めと終わりに
合うように位置を調整しましょう。
再生してみるとマーカーの範囲内が無限ループしていることがわかると
思います。
ここまでできたら、cocos2dxで使えるように書き出しをします。
書き出し
メニューバーのビルド→Atomキューシートバイナリのビルドをクリック。
この画面からビルドできるのですが、
なぜか自分は言語が「No Language」になっており言語が選択できない状態に
なってましたので、ビルドの前にこの場合の対処法を先に紹介します。
一旦キャンセルをクリックし、
「ワークユニット」の上の「プロジェクト/全体設定」の中の
言語設定右クリック→新規オブジェクト→言語設定の作成で言語をすべて
追加します。
では、もう1度ビルド画面まで戻ります。
言語が追加されました。
言語を全選択し、ACFバイナリ出力にチェックをいれビルドをクリック。
ビルドを完了しました。という画面が出たら成功です。
確認してみましょう。
ワークユニットの中の、
mainを右クリック→
「Atomキューシートバイナリ出力先フォルダをエクスプローラーで開く」
を選択。
するとmain.acbとmain.h、1つ上の階層にFrog.acfとFrog_acf.hが
作成されていると思います。
長くなりましたが、今回はこれで終了します。
次回は、cocos2dxにADX2LEを導入と先ほど作成した音データをcocos2dxで
再生してみたいと思います。
ありがとうございました。
0 notes
Text
複数のクラスのメソッドを指定のタイミングで同時に行う【Unity】
こんにちは!お久しぶりです。
「しまだ」です。
久々のブログ投稿になります。
なのでちょっとだけ近況報告をします!
最近は、いろんなゲームイベントに参加しながら東京ゲームショウ アマチュア部門向けのゲームを作っていました。
先日は5/20・5/21の二日間で京都のみやこめっせで行われた
「A 5th of BitSummit」に遊びに行ってきました。
BitSummitには毎年遊びに行っているんですが、今年も面白いゲームが多く展示してあり、二日間会場を動き回りましたw
実際に制作者の方とお話することもでき、刺激を受けることが出来たので、ゲームショウに向けてゲームを作りこんでいきます。
さて、そろそろ本題に入りましょう!
今回の内容はタイトルにもある通り「複数のクラスのメソッドを指定のタイミングで同時に呼ぶ」です!
僕は普段Cocos2d-xを使用してゲームを作っていたのですが、今回のゲームはUnityで制作しています。
Cocos2d-xで制作をしている際、「あるタイミングで異なるクラスのメソッドを一斉に行いたい」という時に「シングルトンのmanagerクラスに、メソッドを受け渡して保存しておく」ことで解決していました。
今回はこれをUnityでも行いたいと思い実装しました。
問題の処理なのですが、Cocos2d-xで行っていた処理はこんな感じでした。
#pragma once #ifndef __Test__TestManager__ #define __Test__TestManager__ #include "cocos2d.h" //シングルトンクラス using namespace cocos2d; using namespace std; class TestManager { public: static TestManager *_instance; static TestManager *getInstance();//インスタンスを取得 bool init(); void update(float delta); void test();//登録した処理を呼ぶ処理 void addFunc(function<void()> func);//処理を登録する処理 private: vector<void()> _testFunc;//メソッド登録用の配列 }; #endif /* defined(__Test__TestManager__) */
.hはこんな感じで
#include "TestManager.h" TestManager *TestManager::_instance; //シングルトンにする TestManager *TestManager::getInstance() { //インスタンスが作られてなかったら作る if (_instance == NULL) { _instance = new TestManager(); _instance->init(); } return _instance; } bool TestManager::init() { // updateが毎フレーム呼ばれるよう登録 Director::getInstance()->getScheduler()->unschedule("TestManagerUpdate", this); function _update = [=](float dt) {this->update(dt); }; Director::getInstance()->getScheduler()->schedule(_update, this, 0.0f, -1, 0, false, "TestManagerUpdate"); _testFunc.clear(); return true; } void TestManager::update(float delta) { } //登録した処理を呼ぶ処理 void TestManager::test() { for (auto func : _testFunc) { func(); } } //処理の登録用メソッド void TestManager::addFunc(function<void()> func) { _testFunc.push_back(func); }
.cppはこんな感じです。
メソッドを登録したいときは、登録したいメソッドを持っている側で
function<void()> func = [=]() { log("test"); }; TestManager::getInstance()->addFunc(func);
のように処理してあげることで登録しています。
function<void()> func = [=]() { test(); }; TestManager::getInstance()->addFunc(func);
もちろん、ここで中身にメソッドを入れてあげることで、メソッドの登録もできます。
そして、本題となるこれをUnityで実装した方法なのですが
考え方自体はそのまま使用することができました。
変更するのは、配列とメソッドの引数だけです。
実際のソースはこちらになります。
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; public class TestManager : MonoBehaviour { public static TestManager _instance; //処理を登録するための配列 List<Action> _testFunc = new List(); void Awake() { //インスタンスが作られてなかったら作る if (_instance == null) { _instance = this; _instance.init(); } } //シングルトンにする public static TestManager getInstance() { return _instance; } bool init() { _testFunc.Clear(); return true; } void Start() { } // Update is called once per frame void Update() { } //登録した処理を呼ぶ void test() { for (int i = 0; i < _testFunc.Count; i++) { _testFunc[i](); } } //処理を登録する public void addFunc(Action func) { _testFunc.Add(func); } }
まず初めに、配列を動的に使用したいので、配列ではなくListを使用します。
Listを使用するためには、ソースコードの一番上に
using System.Collections.Generic;
を入れてあげる必要があります。
そして、Listの宣言方法ですが、
//List<型> 変数名 = new List<型>(); List<int> _test = new List<int>();
という形になります。
そして、登録するためのメソッドの型ですが、調べたところAction型を使用することで解決できました。
Action型を使用するためにも、ソースコードの一番上に
using System;
を入れてあげます。
そして、Action型を持ったListを作成します。
List<Action> _test = new List<Action>();
次に、Listにメソッドを登録するためのメソッドを作成します。
//処理を登録する public void addFunc(Action func) { _testFunc.Add(func); }
こちらにも、同じようにAction型を引数にしておきます。
Listに要素を追加する際には、Addを使用します。
これで、メソッドを登録する準備ができました。
あとは、登録したいメソッドを持っている側のクラスで登録します。
Action func = delegate { test(); }; TestManager.getInstance().addFunc(func);
このように宣言することで、メソッドをAction型で受け渡せるようにします。
あとは、Manager側のクラスで
//登録した処理を呼ぶ void test() { for (int i = 0; i < _testFunc.Count; i++) { _testFunc[i](); } }
このメソッドを実行したいタイミングに合わせて呼んであげれば、指定のタイミングで異なるクラスの処理を一斉に呼び出すことができます。
僕は、Manager側にカウンタを作ることで、数フレーム毎に呼ばれる処理などに使用しています。
これで、今回のブログの内容は終了です!
ありがとうございました!
0 notes
Text
平成29年度前期GPU_RETURNS始動
こんにちは、船長のしろひげです。
先日新1年生のメンバー選考会が終了し、今年度は
3年生 5名
2年生 6名
1年生 3名
計14名でスタートすることとなりました。
各メンバーが今年1年間、どのような活躍をするか楽しみですね。
このブログもしばらく活動休止していましたが、
来週より、各メンバーが週一で更新していきます。
トップバッターは今年のGPU_RETURNSを引っ張っていく「しまだ」。
その後、続々と今年のメンバーの投稿が続きますので、お楽しみに( ´ ▽ ` )ノ
なお、インスタグラムも定期的に更新していくつもりですのでよろしければフォローしてくださいね。
https://www.instagram.com/gpu_returns/
0 notes