UMLについて
オブジェクトモデリングの世界標準ツールとして
UMLというものがあります。
情報系の資格などでも、問題として出てくるので
少しは知っていたのですが、
具体的な使い方がいまいちつかめないという感じでした。
ただ、「体験オブジェクト指向 はじめるUMLモデリング」を読んでみたところ、
UML自体は、劇的に開発効率を上げるツールというわけではなく、
漠然とした抽象的な仕様を具体的な仕様に起こしていく為の
補助ツールって位置づけなのかなぁという印象を受けました。
UMLは書き方に規格がありますが、何をどこまで書くかというのは
利用者に委ねられます。
書きすぎたら、時間が膨大に必要になり、資料も多すぎて読みにくくなります。
書かなすぎたら、結局どんなシステムなのか把握ができなく、設計の意味を成さなくなります。
なので、何をどこまでどの図を用いて書くのか
という、UML自体を使いこなすスキルが必要になりそうです。
ただし、漠然とした仕様を図で整理したり、
プロジェクト内でシステムの構成を共有できるという大きなメリットもあります。
デザインパターンもクラス図で書かれてたりするので、
そういった資料も読めるようになりますね。
使いこなすまでには多くの実践が必要そうなので、
実際のプロジェクトに取り入れたりしながら
勉強していこうと思います。
- 作者: 山田正樹
- 出版社/メーカー: 技術評論社
- 発売日: 2003/05
- メディア: 単行本
- クリック: 2回
- この商品を含むブログ (2件) を見る
サウンドを途中から再生する
音楽を途中から再生する方法について、
ネットで検索しても、情報を見つけれなかったので
念のため記事にしておきます。
途中再生自体が余り需要がないのかな??
詳細
手続きは簡単です。
AudioSourceにtimeという再生時間についてのプロパティが有ります。
これは、現在の再生時間を知ることができますが、
値を設定することも出来るので、再生したい時間を設定します。
audioSource.clip = audioClip; audioSource.time = 5f; audioSource.Play();
1.audioSorce.clip に AudioClipをセット
2.audioSorce.time に 再生時間(秒)をセット
3.audioSource.Play() で再生
以上で、設定したAudioClipをtimeで指定した時間から再生できます。
超簡単ですね。
time値は参照すれば、現在の再生時間がとれるので、
たとえばRPGなんかで
マップの移動中に戦闘が発生して、
戦闘終了後にさっき再生してたとこからまた再生したいって時は、
戦闘前にtime値を保管しておいて、
戦闘終了後に、保管していたtime値を再設定してやれば
続きから再生できます。
時職人の作り方 (2)- オブジェクトの並べ方
時職人作り方2回目です。
今回はストップウォッチ部を解説予定でしたが、
メニュー部にまだネタがありそうだったので、
もう少しそちらを説明していきます。
構成
今回は、アイコンの並べ方のロジックについてです。
以前も軽く触れましたが、アイコンメニューは実行時に
自動生成し、戻るアイコンはEditor上で予め配置しています。
よって、実行前と実行後は以下の様な感じになります。
- 実行前
- 実行後
各ステージは、エリアという単位でくくられていて、
全7エリアの、12ステージでゲームが構成されています。
アイコンの数分ループ
アイコンの作り方としては、
エリア と ステージ のループで回して、
その中でアイコンのオブジェクトを生成していく形です。
ただし、画面表示の都合上、4ステージ毎に
アイコンの折り返しをしています。
そのため、ステージをさらに行と列のループに分けています。
const int ICON_COL_NUM = 4; const int ICON_ROW_NUM = 3; void IconLayout () { for (int areaNo =0; areaNo<_areaNum; areaNo++) { for (int y=0; y < ICON_ROW_NUM; y++) { for (int x=0; x < ICON_COL_NUM; x++) { CreateIcon (areaNo, x, y); } } } }
areaNoのループがエリアのループ。
ステージが増えても良いように、ループ回数はメンバ変数としています。
その中で、y座標と x座標に関してループしています。
列と行は、変えるつもりはなかったのでconstです。
今回は_areaNumは7なので、
エリア(7) * 行(3) * 列(4) = 84
で全84ステージ分のアイコンをCreateIconで実体化させています。
個別アイコンの位置決め
先ほどのループで、どのアイコンを作るかというところまで
確定しているので、あとはそこから詳細な位置を導き出します。
略以降はアイコンの色変化とかをさせてますが、
アイコンパターンが幾つかあり煩雑なので、
次回の説明に回します。
以下、位置情報確定のコードです。
void CreateIcon (int areaNo, int x, int y) { int posX = x * 148 + (int)(Icon.transform.localScale.x / 2) + OFFSET_X + (areaNo * Constants.DISP_W) + ICON_OFFSET_X; int posY = (-y * 148) - (int)(Icon.transform.localScale.y / 2) + ICON_OFFSET_Y; var obj = (GameObject) Instantiate ( Icon, new Vector3 (posX, posY, 1), Quaternion.identity ); 〜〜 以下略 〜〜 }
久々に紐解いてみましたが、
やや複雑な計算ですね…
自分で作ったのに、どこで何しているのかよくわからないです。
148ってなんだよ…
リファクタリングがきちんとできていない証拠ですね(--;
x座標
まずはposXの座標をどう求めてるか見ていきます。
x * 148
148はアイコン部分の基本幅になります。
なので、単純に並べるだけなら、この部分だけでOKで、
148の値を適当に調整すればなんとなくの位置に並べることも可能です。
(int)(Icon.transform.localScale.x / 2)
Iconは、Iconのオブジェクトになります。
アイコンとアイコンの間隔をアイコンの大きさの半分に
したかったみたいです。
OFFSET_X
5000で設定されていました。
前回説明してましたが、アイコン部分と情報説明部分を
別のカメラで描画しており、それぞれが間違って被らないよう
Xを遠くに設定していたようです。
Yで距離をつけたほうが、Editor上で近くなるし、
今回はX位置を決めるのが煩雑だったので
ちょっと設計ミスだったかもです。
(areaNo * Constants.DISP_W)
エリアごとの幅調整をしています。
1エリアと、2エリア目は画面スクロールで別画面になるため、
アリア内でのアイコン幅より若干広めに取っておく必要があります。
ICON_OFFSET_X
今表示されてる画面の左からどれくらいオフセットを取るか
という数値です。
以上を足すことにより、X座標が求まりました。
一応、全部目的があって複雑になってたようです。
y座標
y座標は大分シンプルです。
また、x座標で既にでてきた考えと同様なので、簡潔に行きます。
(-y * 148)
基本位置。
ただし、Unityのワールド座標のy値は
標準のカメラの位置では、画面下がマイナスになってるので、
マイナスを掛ける必要があります。
いつもこの辺がややこしいなぁと感じているんですが、
よく考えたら、カメラを上下反転させれば、
感覚的なy値と実際のy座標をあわせれるのでは!?
と今思いつきました。
今度やってみます。
(int)(Icon.transform.localScale.y / 2)
アイコンの高さ間隔
ICON_OFFSET_Y
画面上部からのオフセット値
オブジェクト生成
var obj = (GameObject) Instantiate ( Icon, new Vector3 (posX, posY, 1), Quaternion.identity );
予め計算したx,y座標位置に、オブジェクトを生成。
今回は2D画面を想定してるので、z値は固定です。
座標を決めるのも意外と大変でした。
次回は、アイコン部分の生成です。
過去のシリーズ
SpriteRenderer、とりあえずの隣接ドット対策
2DのSpriteRendererで、Multiplueを使用して画像を区切った際、
例えばマップチップ的な使い方をしてると、縮尺によっては、線が入ってしまう時がある。
■線が入った状態
■本来はこう表示したい
ピクセル数が完全に決まってる画面なら、
ピクセルがずれないようにカメラの設定をしておけば問題ないが、
スマホ向けだと画面サイズと比率がまちまちなので、どうしても縮尺とピクセルが
うまくあわない可能性が出てくる。
今回は、この現象に対する1つの対処方法について。
ちなみに、この現象の線の部分というのは、
どうも隣のドットが表示されている様子。
2Dとはいえ、仕組みとしては、オブジェクトに
テクスチャを貼り付けてる仕組みだと思うので
多分このズレは防ぎようがなさそう。
そこで、隣のドットを表示されることを諦めて、
1ドット余分に画像を書いておくという対処が考えられる。
ただし、本来表示したいものと別に1ドット余分になるので
元の画像のサイズが8で割れない数字になったり、
単純に書き込み作業が面倒だったりと、結構大変そう。
なので、何か他に良い方法がありましたらコメントいただけると
助かります!!
って事で、1ドット余分な画像を作る作業はちょっと
片手間ではできないので、現在の画像をひと回り小さく利用する形で
やってみました。
どういうことかというと、今マップチップが
16ドットで構成されているんですが、
それを14ドットとみなすことで、
上下左右1ドットを余分な部分とするということです。
早速やってみました。
まずは、Pixel To Units を現在16で設定しているので、
これを14にします。
そして、Sprite Editorを開きます。
現在は、こんなかんじです。
ちなみに、透明部分はGridでスライスした時に、
Sprite対象外になってしまうので、一時的に背景にダミーの塗りつぶしを設定しています。
スライス後に背景を非表示にして保存しなおせば、透明部分も
Sprite対象にできるので、画像の並び順に意味を持たせたいときには便利です。
・・・
次に、Slice設定を変更します。
PxcelSizeを14にしました。
画像には、上下左右位置ドットの余白をつけてるつもりなので、
Offsetでxy、1ドットずつ
Paddingは、自分の1ドットと、隣の1ドットの距離があるので、
2,2で設定します。
そうすると、こんなかんじになりました。
これで、Gameビューの縮尺を色々変えてみても、
線が入る事はなくなりました。
時職人の作り方 (1)
前回の記事で、「時職人」を軽く紹介しましたが、
このアプリがどういった仕組みで構築されているかを
少しづつ紹介していこうと思います。
今回は、ステージ選択画面について。
ステージ選択画面は以下の様な構成になっています
・上部:ステージを選択するためのアイコン、
・中部:エリアの番号表示とエリア切り替えのためのボタン
・下部:ステージ情報表示
また、以下2つのカメラでそれぞれの表示部分を
分けて表示しています。
サブカメラ:アイコン選択部分用カメラ(上部)
メインカメラ:2ステージ情報&エリア切り替えUI用カメラ(中部、下部)
メインカメラの方を手前に表示して、その後ろに
サブカメラの画面を投影している形です。
この使い分けによって、サブカメラだけ移動させて、
部分的にスクロールするという表現をしています。
また、ステージ情報は、全ステージ分一気に描画しておき、
そこをカメラが左右に移動する仕組みです。
これにより、後はカメラ移動させるだけで、スクロールが表現できます。
場合によっては、メモリの節約のために、
移動時に、移動先を描画し、移動前のところを消して…
などの処理が必要になると思いますが、
今回はそんなにオブジェクトの数もないため、
この仕組にしています。
また、メニューの一番左は、タイトルに戻る為のホームボタンになってるのですが、
あらかじめカメラの移動先の左端にエディタ上でボタンを設置しています。
今回のつくりの場合、今どこをスクロールしてるかを判断し、
描画するオブジェクトを変える処理がいらないので、ボタンの変更があっても
エディタ上の処理で済むので楽です。
ちなみに、カメラの移動にはiTweenを利用して、
スクロールを滑らかにしています。
複数のカメラを使うと、移動させたくないUIと
移動する画面を切り分けれるので便利です。
次回は、ストップウォッチを止める部分の処理を紹介予定です。
時職人の紹介記事はこちら
最初のアプリリリース
icocAppsとして、Unityを使って開発をはじめて、
ようやく一年近くになります。
最初のアプリリリースは、時職人という、
指定時間でストップウォッチを止めるというゲームで、
AppStoreに並んだのが、去年の11/2でした。
去年の今頃から開発をはじめて、リリースまで一ヶ月半くらいかかっています。
最初なので、ライブラリの構築や、
広告を入れる仕組みがわからなかったりで、
単純なゲームな割には時間がかかってましたね。
というより、最初なので企画の流れとかもわからないで
この単純なゲームのアイデアを出すのにも一週間くらいかかってた気がしますw
当時はいiPhone5Sが発売され、さらにiOS7がリリースされて
フラットデザインというのが流行っていたので、ゲームもそれに合わせたスタイルにしていました。
最近はフラットデザインって言葉をネットで見る機会があんまりない気がするんですが、
単なる一時期のはやりだったんですかね?(^^;
■icocAppsの時職人紹介ページ
[001] 時職人 〜Time Artisan〜 | icocApps
CEDEC 2014に参加してきました
9/2〜9/4にかけて、
パシフィコ横浜で開催された
CEDEC2014に行ってきました。
今回は、以下の講演に参加してきました。
9/2
- ロジカルにゲーム企画をやろう! ~題材からのゲーム企画手法~
- 日本と海外のモバイルアプリ、ゲームのトレンド
- IGDA 2 ゲームを作るだけじゃない! 謎解き型体験イベントとの相乗効果で新規市場を開拓しよう
- 脱「プランナー」〜ゲームデザイナーの仕事〜
一日目は、長崎からの移動日でもあったので、午前中の講演を見ることができませんでした。
ネットの記事を見てると、冲方丁さんの基調講演が素晴らしかったみたいで、
拝見できなかったのがすごい残念です。
今回は市場や企画についての情報を中心に講演を選択していきました。
AppAnnieの桑水さんが海外のアプリ市場の統計データを色々紹介してくださったのですが、
以下の様なことが印象的でした。
・海外でも課金市場が伸びてきている
・メキシコとブラジルで無料アプリDLのすごく増えている
・売上の割合はアプリ内課金が9割。 有料アプリは1割にも満たない。
・日本はかなりiPadでの売上が少なく、iPad市場自体がさほど成長していない。
9/3
- ウェアラブルコンピューティングの動向とウェアラブルゲームへの展開
- 「楽しさ」の設計と評価~我々はどこで失敗し,どこへ向かうのか
- 事前登録者数45万人を獲得した施策『フライングゲットガチャ』 良策を連発する為の異業種協業体制とは!?
- 海外カジュアルゲーム市場の最前線報告
- 中国ゲームビジネス最前線2014~第一線を見つめてきた経営者と研究者の視点からみる中国進出成功の鍵~
二日目も海外市場の講演。
新清士さんによる、フィンランドゲーム市場のお話。
・フィンランドには「クラッシュ・オブ・クラン」、「アングリーバード」等、アプリ市場で大施工している企業が存在
・アングリーバードの会社は、新しいヒットアプリを生み出せていない
・アングリーバードは冬季オリンピックの開催が重なり偶然ヒットが広がった可能性が見られる ※
・売れてるアプリは50%は運が作用している感じ
アングリーバードはすでに売上が頭打ち状態みたいで、アプリ売り切りスタイルでは
やはり伸びという部分で厳しい面があるようです。
※ 正確には冬季オリンピックである選手がインタビューでアプリ名を発言したのが発端みたい
http://www.macotakara.jp/blog/report/entry-15084.html
9/4
- これからのゲームとゲームクリエイター
- ゲームの海外進出で成功する方法を考えよう!~市場動向・マーケティングから開発まで~
- 地方から世界に発信する初音ミクとコンテンツの未来
- どこまで使えるMBAAS?ゲームで利用する注意点と効果について
最終日。
この日も移動日で、最後の方の講演は見れませんでした。
基調講演は、龍が如くの名越さん!!
ゲーム雑誌やネットでもよく見かけていて、
特に龍が如くの開発に関わってから、見た目がガラッと変わったというのが印象的で
非常に興味がある方だったので、楽しみにしていた講演でした。
講演内容は、どうもTOKYO GAME SHOWで忙しい時期らしく、
資料などは用意されていなかったのですが、
コンシューマーの第一線で活躍されている中での経験談を色々話されていて
非常に面白かったです。
ネタ的な話になりますが、新人にある企業向けの企画書を書かせたら、
「ある企業名」「企画書」っていうのをネットで検索しだして、
すごい衝撃をうけられたそうです。
あまりにも衝撃過ぎて、怒っていいかもわからず、
それでいい企画書が上がってくるんならそれはそれでいいんだけど…
みたいな感じでどう対応していいか困ることも多いんだとか
三日間、色んなクリエイターのお話や調査結果などを見聞きできて
すごく刺激になりました!!
関連リンク
第22回 Unity勉強会に登壇してきました
先週の金曜日にTechBuzzSpaceにて開催された、
第22回 Unity勉強会 へ登壇者として参加させていただきました。
発表内容は、以前このブログでも紹介していた5日間連続アプリリースを元にした、
「Unityを使って1日でアプリを完成させるためには」という内容です。
5日間連続リリース、まとめ。 - Unityゲーム開発日記@長崎
発表内容をslide shareの方にアップしましたので、興味がある方は
御覧ください。
GameObjectの表示と当たり判定の設定を行う(親子階層構造対応)
GameObjectには、Active状態を切り替える
SetActive
というメソッドがあります。
こちらでActive状態をfalseにした場合、対象オブジェクトのコンポーネントが全て無効となります。
この場合、例えばそのオブジェクトがAudioSouceなどを持ったオブジェクトだと、
再生中のSEも途切れてしまうため、場合によっては表示と当たり判定のみを無効にしたい事が
あると思います。
そこで、SetActiveSoftというメソッドを考えてみました。
public static void SetActiveSoft(this GameObject me, bool val){ var tr = me.transform; for(int i=0; i<tr.childCount; ++i){ SetActiveSoft(tr.GetChild(i).gameObject, val); } if(tr.renderer != null){ tr.renderer.enabled = val; } if(tr.collider2D != null){ tr.collider2D.enabled = val; } if(tr.collider != null){ tr.collider.enabled = val; } }
まず、SetActiveと同様に、GameObjectのメソッドとして利用できるように
Extensionで拡張しています。
Extensionについては、過去記事を参照下さい。
クラスのメソッドを拡張するExtensionの使い方 - Unityゲーム開発日記@長崎
対象GameObjectに対し、bool値を渡し
trueなら、全オブジェクトのコリジョンとレンダラーをtureに設定しています。
また、transformに紐づく子を再帰で全走査しています。
コリジョンに関しては、collider2Dやcolliderのコンポーネントがあるかを確認し
存在すれば、enabled値を設定します。
Tiled map editorのxmlデータをクラスに流し込む
いま製作中のゲームで、マップの製作が必要なため、
フリーのマップ作成ツールで比較的高機能な
Tield map editorというのを使ってみました。
Tiled map editor
http://www.mapeditor.org/
今回は、このツールで出力したxmlデータを
Unityに取り込む為の手続きについてです。
最終的に画像と対応させるまでとなると、
画像とマップチップ番号を対応させる仕組み等も必要なので、
とりあえずは、Tiled map editor のxml形式を
プログラムで読めるようにするというところまでの段階の説明になります。
Tiled map editorで作ったデータをtmx形式で保存すると、
中身はxmlデータとなります。
ただし、unityでは、拡張子をみてTextAssetかを判断してるので、
「tmx」を「xml」に変更しておく必要があります。
また、ListとXml関連のクラスを利用するので
以下をusingしておいて下さい。
using System.Collections.Generic; using System.Xml.Serialization;
そして、まずxmlを指定した型に流し込むクラス
public class XmlReader { public static T LoadFromXml<T> (string path) where T : class { var xml = Resources.Load( path ) as TextAsset; if(xml == null){ return null; } var ser = new XmlSerializer (typeof(T)); var stringReader = new StringReader(tmx.text); var obj = ser.Deserialize(stringReader); var retClass = (T)obj; return retClass; } }
これは汎用的に利用できるクラスですが、
pathで指定されたResourcesフォルダにあるxmlファイルを
そして、今回読み込みたいxmlファイルはこんな感じ
<?xml version="1.0" encoding="UTF-8"?> <map version="1.0" orientation="orthogonal" width="10" height="10" tilewidth="16" tileheight="16"> <tileset firstgid="1" name="char_16" tilewidth="16" tileheight="16"> <image source="../../StageEdit/char_16.png" width="128" height="512"/> </tileset> <tileset firstgid="257" name="map_16" tilewidth="16" tileheight="16"> <image source="../../StageEdit/map_16.png" width="512" height="512"/> </tileset> <layer name="layer_map" width="10" height="10"> <data> <tile gid="258"/> <tile gid="258"/> <tile gid="258"/> <tile gid="258"/> <tile gid="258"/> 〜 省略 〜 <tile gid="260"/> <tile gid="260"/> <tile gid="260"/> <tile gid="260"/> <tile gid="260"/> </data> </layer> <layer name="layer_actor" width="10" height="10"> <data> <tile gid="0"/> <tile gid="0"/> <tile gid="0"/> <tile gid="0"/> <tile gid="0"/> 〜 省略 〜 <tile gid="0"/> <tile gid="0"/> <tile gid="0"/> <tile gid="0"/> <tile gid="0"/> </data> </layer> </map>
data内のtile要素は 10 x 10 = 100 個あるので省略してます。
そして、これをclassとして読み込みたいのですが、
このxmlに対応した構造のclassをあらかじめ作成しておかないといけません。
そのclassが以下の様な形になります。
[XmlRoot("map")] public class Map { #region class public class TileSet { [XmlAttribute] public int firstgid; [XmlAttribute] public string name; [XmlAttribute] public int tilewidth; [XmlAttribute] public int tileheight; public Image imgae; } public class Layer { [XmlAttribute] public string name; [XmlAttribute] public int width; [XmlAttribute] public int height; public Data data; } public class Image { [XmlAttribute] public string source; [XmlAttribute] public int width; [XmlAttribute] public int height; } public class Data { [XmlAttribute] public string encoding; [XmlElement()] public List<Tile> tile; } public class Tile { [XmlAttribute] public int gid; } #endregion #region public property [XmlAttribute] public string version; [XmlAttribute] public string orientation; [XmlAttribute] public int width; [XmlAttribute] public int height; [XmlAttribute] public int tilewidth; [XmlAttribute] public int tileheight; [XmlElement()] public List<TileSet> tileset; [XmlElement()] public List<Layer> layer; #endregion #region public method public int[,] GetLayerData(string name){ var oneLayer = GetLayer(name); if(oneLayer == null){ return null; } var w = oneLayer.width; var h = oneLayer.height; var tiles = oneLayer.data.tile; var grid = new int[w, h]; for(int y=0; y<h; ++y){ for(int x=0; x<w; ++x){ var tileNo = x + (y * w); grid[x, y] = tiles[tileNo].gid; } } return grid; } #endregion #region private method private Layer GetLayer(string name){ foreach(var l in layer){ if(l.name == name){ return l; } } return null; } #endregion }
なんか、結構複雑な構成です(^^;
xmlを見ながらクラスを逆構築していく作業は結構大変でした。
この変を自動化するツールとかないのかなぁ…
とりあえず、簡単に説明すると、
xmlの根になる要素がmapなのでMapクラスとしました。
そして、そこが根ということを示す為に
[XmlRoot("map")]
を宣言しています。
そのあと、#region class
内が、各要素の構成です。
アトリビュート項目は
[XmlAttribute]
で宣言します。
LayerやTileSet等、複数回登場する可能性のある要素は
[XmlElement()]
で宣言します。
また、重要な点として、変数名は
要素名と同じでないといけません。
とりあえず、構造だけあればデータは流し込めますが
ほとんどの場合、欲しいデータはレイヤーの情報だと思うので、
レイヤ名称を指定したらそのレイヤの数値データをintの配列で返す
GeetLayerData関数を用意しています。
以下は作成したクラスを実際に使って、
レイヤーの情報をDebug各値をDebug出力するサンプルです。
public void ReadMap(){ var path = "stageData"; var map = XmlReader.LoadFromXml<Map>(path); var grid = _map.GetLayerData("layer_actor"); foreach(var g in grid){ Debug.Log(g); } }
とりあえず、今回はここまでです。
後は、複数のタイルを利用していた場合、
レイヤ内の値が全タイルでの通し番号となるようなので、
TileSetのfirstgidを使って番号を調整する必要がありそうです。
また、現段階では、オブジェクトレイヤーに対応できていないので、
その辺の追加などができたらまた修正版の記事を上げたいと思います。
Hashtable(ハッシュテーブル)をスッキリ書く
iTweenを利用する場合、Hashtableの記述がほぼ必須になってくるかなと思います。
単純に書いた場合は以下の様な感じですかね。
iTween.MoveTo(gameObject, iTween.Hash("speed", 1f, "x",10f, "y",10f, "easeType", iTween.EaseType.linear));
ただし、こう書いた場合、
キーとバリューが横一列に並んでちょっと見づらいです。
(後ろ、既に見えてないし(^^;)
そこで、Hashtableを予め作成しておいて、
それを第二引数に渡すという手もあります。
var hash = new Hashtable(); hash.Add("speed", 1f); hash.Add("x", 10f); hash.Add("y", 10f); hash.Add("easeType", iTween.EaseType.linear); iTween.MoveTo(gameObject, hash);
こうするとキーとバリューの対比がはっきりして
後で修正するときもやりやすいかなと思います。
しかし、初期化時に既に値が決定しているなら
以下の様な記述でnewの部分で値を設定するということもできます。
var hash = new Hashtable(){ {"speed", 1f} , {"x", 10f} , {"y", 10f} , {"easeType", iTween.EaseType.linear} , }; iTween.MoveTo(gameObject, hash);
こうすると、記述量も減り、ぱっと見もスッキリするので
個人的には初期化の時はだいたいこういう書き方をしています。
ちなみに、enumや普通の配列の定義同様、最後の項目のカンマはつけたままで良いです。
ちなみにListやDictionaryも同様に初期化できます。
詳細についてはあたもこさんのサイトで紹介されいていました。
VisualStudioでの話ですが、C#の記述は同様なので
上記での2008バージョンの初期化が利用できます。
コードのフォーマットを自動で整形する
前回は、簡単にコメントを切り替える方法を説明しましたが、
今回は、コード全体のフォーマットを自動で整形する方法についてです。
検証環境:MonoDevelop 4.0.1
たとえば、以下の様にタブ幅がグチャグチャなコードが有るとします。
(普通にやってたらまずこんなインデントにはならないと思いますが(^^;)
そして、
・編集 > フォーマット > ドキュメントをフォーマット
を選択します。
すると、以下のように、コードがきれいなインデントで揃えられます。
ちなみに、こちらのフォーマットはファイル全体に影響します。
また、フォーマットの基準となるタブ幅の設定については、以下の記事を確認下さい。
MonoDevelop 4.0.1のドキュメントフォーマットでタブ幅が正しく設定されない時の対処 - Unityゲーム開発日記@長崎
MonoDevelopを使っていれば、改行時にインデントを揃えてくれるので、
フォーマットを揃える必要がある機会はそんなにないと思いますが、
どっかからコピペで持ってきたコードのインデントが異なってた際などには、
こちらの機能を利用すると便利だと思います。
選択範囲をまとめてコメント化。 その機能をショートカットに割り当てる。
今回は、コメントアウトの手続きをちょっと楽にする方法を紹介します。
まとめてコメントアウト
最近の統合開発環境にはだいたい搭載されていると思いますが、
MonoDevelopには選択範囲をまとめてコメントアウトするという機能があります。
検証環境:MonoDevelop 4.0.1
手続きは簡単です。
・まずコメントアウトしたい場所を選択
・編集メニュー > フォーマット > 行コメントをトグル
を選択します。
・選択範囲がコメントアウトされます。
また、トグルとは、切り替えって意味なので、
上記手続きで既にコメントアウトされた箇所を再度選択して
行コメントをトグルを選ぶと、コメントアウトが解除されます。
/*
*/
でもまとめてコメントアウトできますが、
入れ子になるとうまく行かなかったりするので、
この機能のほうが使いやすいかなと思います。
ショートカットに割り当て
また、この機能をショートカットで割り当てておくと
さらに便利になります。
ショートカットへの登録手続きは以下の通り。
・MonoDevelop-Unity > Preferences
を選択
・設定メニューが開く
1. 「キーバインディング」を選択
2.「検索」欄に「トグル」と入力し、右のハケ?ボタンを押す
*「かな」ボタンをおすと、入力になってしまうみたいなので、
どこかに一度「トグル」と入力した文字をコピペで貼り付けて下さい。
3.「行コメントをトグル」が表示されていると思うので、選択
4.「バインディングの編集」欄で、コマンドを入力し、「適用」を押す
*ちなみに、自分は「Command + Option + C」に割り当てています。
後は、まとめてコメントアウトの手続き同様、コメント化したい範囲を選択し、
先ほど割り当てたショートカットキーを押すと、コメントアウトされます。
これを登録しておくと、かなりコーティング時に楽になるかと思うので
是非試してみてください〜。
新規作成時スクリプトのテンプレートファイルを編集する
Unite2014の「Editor拡張 マニアクス2014」にて
安藤圭吾さんがUnityで新規作成した時に作成される
スクリプトのテンプレートファイルの編集について紹介されていました。
今回は、その手続きについての記事です。
概要としては、Unityアプリの中にテンプレートファイルのtxtがあるので、
それを編集するだけです。
まず、Finderで、Unity.appがインストールされている場所へ移動して下さい。
自分の場合は
Macintosh HD > アプリケーション > Unity > Unity.app
としています。
Unity.app上で右クリックメニューを表示すると、
「パッケージの内容を表示」
とありますので、これでapp内のファイルを表示させて下さい。
その後、「Contents」というフォルダが表示されると思いますが、
そこを、以下の通りたどっていって下さい。
Contents > Resources > ScriptTemplates
すると、80〜84までの頭数字がついたtxtファイルが表示されると思います。
そこで、自分が利用している言語のテンプレートファイルを修正すれば、
UnityやMonoDevelopでスクリプトファイルを新規作成した際に、
ここで編集したテンプレートの状態のものが表示されると思います。
訂正:MonoDevelopで新規作成した場合は、反映されませんでした。
ただし、元の状態に戻せるよう、念のため編集前のファイルの
バックアップをとっておくことをおすすめします。
また、C#のテンプレートの書き方について以前投稿していますので、
ご参考にどうぞ。
regionとコードのテンプレート - Unityゲーム開発日記@長崎
iTweenで動作しているオブジェクトを一括制御する
オブジェクトの移動を物理制御ではなく、
決められた位置に移動させたい場合に便利なのが
無料で公開されているAsset、iTweenです。
自信で制作してるゲームも2D系では
物理動作を利用しない場合が多いので、
iTweenを多用しています。
iTweenの使い方については、
ActionScript入門Wikiさんの
以下のページにわかりやすくまとめられています。
ActionScript入門Wiki - Unity - トゥイーンライブラリiTweenを使用する
先日リリースしたまっすぐ勇者は、
ゲーム開始後自動で勇者が移動するという仕様で、
iTweenを使ってマス移動をしているのですが
今回はゲームを停止させるためのPAUSE機能を実装しました。
そこで、利用したのが
iTweenを利用しているオブジェクトの一括制御です。
PAUSEを押した時に、一時的にiTweenを利用している
オブジェクトの制御を止め、
PAUSEを解除した時に、iTween制御を再開するというのをやりたかったのですが、
それぞれの個々のオブジェクトに対して、停止を掛ける必要はなく、
iTweenの下記staticメソッドで一括制御が出来ました。
// 一時停止 iTween.Pause(); // 再開 iTween.Resume();
ちなみに、iTween.Stop()でも停止はできるのですが、
こちらは完全停止という形になり、再開はできなくなります。
また、一点注意があるのですが、
iTween.Pause()
をかけたままオブジェクトを削除したり、シーンを遷移したりすると
オブジェクトへの参照が残るのか、次回iTweenの制御をした際に
エラーとなる場合があります。
なので、iTweenでの制御中にオブジェクトの削除、またはシーンの遷移をする場合は
オブジェクト削除前にiTween.Stop()をかけるようにしましょう。