かずおの開発ブログ(主にRuby)

日々の開発のことを色々書きます。

getAppContextをActivityクラス以外から呼ぶ

内容は表題の通りです。

getAppContextメソッドをActivityクラス以外から呼びたいというかこれができないとActivityクラスがどんどん巨大になってしまいます。

調べたらすぐ出てきました。

やり方としてはApplicationクラスを継承したクラスを作成してstaticで呼べるようにしていまうというものです。

1. Android Manifestを編集する

まずAndroidManifestファイルを編集してこんな感じに書きます。

gist.github.com

com.aaa.bbb.ccc前の部分は作成中のアプリのmanifestタグ内のpackage名の部分になります。 Myapplicationの部分はこの後作るApplicationクラスの名前と同じであればなんでも構いません。

2. Applicationクラスを作成

続いて、MyApplicationクラスを作ります。

アプリが起動した際にgetAppContextが走りあとはこのクラスがContextを返してくれるようになるので

、ActivityクラスじゃなくてもどこからでもアプリのContextを参照できるようになります。

ちなみにこれはほとんど同じことがここに書いています。笑

Static Way to get Context on android? - Stack Overflow

クラス名の設定が若干はまったので備忘として

slimのhtmlタグ内でrubyのコードを使いたいとき

例えば

erbで

こんなのがあったときにslim初心者的には<%= %>のところをどう書いたらいいのかわかりません。 普通にいつもの通り=にしてしまうと当然うまくいきません。

結論としては

が正解です。

結局変数などと同じで"#{}"で囲んじゃえばいいみたいです。

Slimでsimple_formatは使えない

表題の通りですがRailsにはsimple_formatというとても便利な機能があります。

simple_format - リファレンス - - Railsドキュメント

内容はここに書いてある通りですが、改行のある長い文章をいい感じにマークアップをしてくれます。

で例のごとくそれをSlimに変換してやってみるかーと思ってやってみたのですが、見事にSyntax errorになります。

で調べてみたところ、同じことを聞いている人がいました。

github.com

ふむふむどうやらスマートモードを見なさいと言われてますね。

github.com

でスマートモードというのが|(パイプ)を使わないでいい感じにしてくれるというものでした。

結局Slimの性質上できないという結論にいたるようです。(Slimの人も君が作ってよ(otherwise I would suggest that you provide a filter similar to markdown)みたいなこと言ってるし。。。)

stackoverflow.com

本当はそのやり方を書きたかったのですが、できないという報告になってしまいました。

何かよいやり方を知っているかたいましたらぜひご教示ください。

新•Unity5の新しいAssetBundleSystemを使ってAssetをダウンロードする

前回のエントリーは不十分なところがかなり多かったので改めてUnity5におけるAssetBundleの使い方について説明したいと思います。

今回作るもの

動画 今回製作するものはこちらです。一見ただ顔がInstantiateされたように見えますが実際にはサーバーから落としてきたAssetからInstantiateされています。前回の不具合を治して、各OSに対応&参照も外れないようになっています。

下準備

下準備としてこちらのgitからコードを落としておいてください。 https://github.com/kazuooooo/Unity5AssetBundleSample.git

スクリプトをインポート

新しい空のプロジェクトを作成して、gitから落としたスクリプトの内AssetBundleMenu.csをEditorフォルダ(※必ずEditorという名前のフォルダにしてください。)に、残りの3つのスクリプトはScriptsフォルダにインポートしてください。

f:id:kazuooooo:20150826191915p:plain f:id:kazuooooo:20150826191926p:plain

続いてAssetBundleにするための何か適当なPrefabを作成します。

f:id:kazuooooo:20150826192454p:plain

今回はこんなかわいい顔を用意しました。 単純なCubeとかでもOKですが、参照情報が保持されていることを確認するために何か適当なマテリアルを貼り付けたりしておいたほうがベターです。

AssetBundleを作成

続いて先ほど用意したPrefabからAssetBundleを作成していきます。 まずPrefabを選択して右下に出てくるAssetBundleの右のNoneというところをクリックしてNewを選択します。

f:id:kazuooooo:20150826192928p:plain

ここでAssetBundleのタグを作成します。このタグが同じものが1つのAssetBundleファイルとしてまとめられます。 ちなみに/で区切ることで階層構造にすることも可能です。

f:id:kazuooooo:20150826193133p:plain

タグが設定出来たら、メニューからAssetBundleを選択(もし表示されていなければ、EditorフォルダにAssetBundleMenu.csが入っているか確認して下さい。)して、ビルドしたい対象のOSを選択してください。

f:id:kazuooooo:20150826193408p:plain

また、ここで設定したOSとBuildSettingの対象のOSが同じであることも確認してください。もし異なっていれば、SwitchPlatformで同じにしておいてください。

f:id:kazuooooo:20150826193525p:plain

最後にもう一度AssetBundleメニューを選択して一番下にあるBuildAssetBundlesをクリックしてください。ビルドするフォルダはデフォルト(Assetsと同じ階層)でいいかと思います。

f:id:kazuooooo:20150826195650p:plain

作成されたAssetBundleを確認

AssetBundleができていることを確認します。

f:id:kazuooooo:20150826194938p:plain

このようにAndroidとfaceという名前のAssetBundleが作成されていることが分かります。他のOSを設定した場合は その名前のフォルダが生成されます。

ちなみに少し説明するとこの(OSの名前).manifestというファイルが各AssetBundleの参照情報を保持している親玉的存在です。 Unity5でAssetBundleを用いる際には必ずこの.manifestファイルをロードしておく必要があります。

詳しくはこちらの動画を御覧ください。とても分かりやすく説明されています。 https://vimeo.com/125767164

作成したAssetBundleをサーバーにアップロード

上で作成したAssetBundleフォルダをサーバーにアップロードします。 今回はAndroidでビルドしたのでAndroidフォルダをアップします。 やり方についてはAssetBundleと直接関係ないのでここでは省略します。

シーンを準備

AssetBundleの準備が出来たので、検証するためのシーンを準備します。 まずヒエラルキー上にLoderという空のオブジェクトを作成します。 そこにインポートしたAssetManager.csとAssetBundleLoaderSample.csをアタッチしてください。

f:id:kazuooooo:20151003153526p:plain

続いてAssetManager.csのPath to Bundelsの項目に先ほどAssetBundleのフォルダをアップしたサーバーのURLを記載してください。このときの注意点としてOS名のフォルダ以下を指定するのでなくそのフォルダがある階層を指定するようにしてください。例えば×http://~/AssetBundle/Android/, http://~/AssetBundle/といった具合です。 理由としてはOS名の部分は環境に依存して自動的に補完されるからです。これによって、複数のOSに1つのコードで対応できます。

f:id:kazuooooo:20151003154253p:plain

最後にAssetBundleLoadSampleのBuldleNameにBundleの名前とロードしたいAssetの名前を記載します。 今回はBundleの名前がface、Assetの名前がFaceとなります。

f:id:kazuooooo:20151003154535p:plain

最後に本当にサーバーから落としていることを確認するためにもプロジェクトの中にあるFacePrefabは削除しておきます。

検証

準備が整ったのでシーンを再生してみましょう。 動画と同じように顔がinstantiateされたでしょうか?

スクリプトの細かい説明とかはしておりませんが、中を見ればだいたい分かると思います。 これはとても単純なものですが、このサンプルを参考に色々発展させてみてください!

Grove - Moistureセンサーを利用して湿度を取得

今回はこちらのMoistureセンサーを用いて植木鉢の土の湿度をはかるだけのシンプルなプログラムを書いてみたいと思います。

その他、今回必要なものはこちらです。

【永久保証付き】Arduino Uno

【永久保証付き】Arduino Uno

GROVE - 4ピン-ジャンパメスケーブル 20cm (5本セット)

GROVE - 4ピン-ジャンパメスケーブル 20cm (5本セット)

回路を組み立て

回路と言っても今回はただつなげるだけですね。 写真のようにArduino Unoにベースシールドを重ねて、PinケーブるをA0と書かれているところに挿し、その先に湿度センサをくっつけてください。 f:id:kazuooooo:20150809232716j:plain

スクリプトを作成

今度はスケッチを作成します。 こちらのスケッチをArduinoで新規作成してみてください。

実行

あとは検証、書き込みをしてみましょう。 水分センサの先を植木鉢などにぶっ挿してみてください。 Arduinoの右上の虫眼鏡アイコンをクリックすると出力を確認できます。 こんな感じで1秒に1回出力されたでしょうか。 f:id:kazuooooo:20150809233439p:plain

ここまでシンプルなものは日本語では見当たらなかったので書いてみました。 参考 : [http://www.seeedstudio.com/wiki/Grove-Moisture_Sensor:title]

全ての子要素を取得する(子要素の子要素の子要素の‥)

Unityで孫とかもひ孫とかも含めて子要素全部取りたいなってときあると思います。 今回はそれを作ってみたいと思います。 出来た動画はこのような感じです。

youtu.be

いい感じに全部取れていますね。(ただ動画は暗くなってうまく取れません笑)

スクリプトを作成

今回はスクリプトを書くだけで全てが事足りてしまいます。 まず、全ての子要素をとるためのGetAllChildrenスクリプトを作成します。

続いてテストスクリプトを用意します

実行

では一番親にテストスクリプトをつけて実行してみましょう! 動画のようになったでしょうか?

今回GetAllChildrenクラスはstaticクラスで作成していますので、プロジェクトのUtilフォルダとかに入れて使ってもらえれば うれしいです! ではまた!

Animatorを使わずにAnimation単体で再生する

UnityでそのGameObjectで再生させたいアニメーションが1種類だけ(例えばUIを点滅させるや爆発のアニメーションを起こすなど)のときにいちいちAnimatorをつけているとAnimatorのUpdateで処理が重くなってしまいます。かといってAnimation単体をつけただけではなぜか再生されない。今回はその悩みを解決するAnimation単体でAnimationを再生させる方法をご紹介したいと思います。

今回作るのはこちらです。

youtu.be

Animationのコンポーネントだけでアニメーションが再生出来ているのが分かる化と思います。

アニメーションを作成

まずは適当なアニメーションを作成します。(アニメーションの作成方法について本題とはそれるので割愛します) 今回は"AnimationComponentSingleAnim"という名前で上の動画のようなアニメーションを作成しました。アニメーション作成時に自動的にAnimatorコンポーネントがオブジェクトにくっついてしまいますが、それを削除して図のようにAnimationコンポーネントをアタッチし、作成したアニメーションをAnimationとElement1のところに登録しておきます。f:id:kazuooooo:20150802185925p:plain

  • アニメーションの設定を変更

このままだとAnimatorがないためにAnimationは再生出来ません。そこでAnimationコンポーネント単体でも再生出来るようにアニメーションの設定を変更します。まず、今回作成したアニメーションを選択して右上に小さく表示されている▼三マークをクリックします。そうするとプルダウンが出てくるのでDebugを選択してください。

  • f:id:kazuooooo:20150802190434p:plain
    Debugを選択すると以下のような画面になるのでそこでLegacyというチェックボックスにチェックをつけます

    f:id:kazuooooo:20150802190546p:plain

これで設定は完了です!

スクリプトを作成

続いてアニメーションを再生させるためのスクリプトを作成します。スタートと同時にアニメーションを再生させるシンプルなものです。

gist.github.com

これをAnimationコンポーネントをつけたオブジェクトと同じオブジェクトにアタッチします。

ゲームを再生

ゲーム再生ボタンを押してみましょう。アニメーションが再生されたでしょうか?一度しか再生されない場合はWrapModeをLoopにすることでLoop再生されます。また、今回はスクリプトの書き方を示すために、スクリプトを書いていますが、スタートと同時に再生させたい場合はPlayOnAwakeにチェックをつけることで、再生が可能です。Animatorは結構パフォーマンスのSpikeになっていることが多いのでこの方法は有効かと思います!お試しあれ!