のにっき

【Unity】AddListnerに引数が必要な場合の対処法

Unityでコンポーネントにイベントを設定するとき、AddListner()をよく使用します。
このAddListnerですが、
イベントの種類によっては引数が必要になる場面があるのをご存知でしょうか?
今回は、ラムダ式でイベント設定する時の注意をまとめたいと思います。

ボタンにイベントを設定する

/***********************************************************************
【メイン】ボタンにイベントを設定する関数
***********************************************************************/
public void SetBtnPushEventListner()
{
    // 【引数なし】ボタンイベント設定
    Button btn_Set;
    btn_Set = this.transform.Find("設定するオブジェクト名").GetComponent<Button>();
    btn_Set.onClick.AddListener(() => { SetBtnPushEvent_NoHikisuu(); });
    // 【引数あり】ボタンイベント設定
    Button btn_Set02;
    btn_Set02 = this.transform.Find("設定するオブジェクト名").GetComponent<Button>();
    btn_Set02.onClick.AddListener(() => { SetBtnPushEvent_Hikisuu("引数"); });
}

/***********************************************************************
【Ev】ボタン押下イベント ※引数なし
***********************************************************************/
public void SetBtnPushEvent_NoHikisuu()
{
    Debug.Log("押されたよ, 引数なし");
}
/***********************************************************************
【Ev】ボタン押下イベント ※引数あり
***********************************************************************/
public void SetBtnPushEvent_Hikisuu(string SetHikisu)
{
    Debug.Log("押されたよ, 引数あり:"+SetHikisu);
}

上記の書き方で、ボタンコンポーネントにクリックイベントを設定できます。

btn_Set02.onClick.AddListener(() => { SetBtnPushEvent_Hikisuu("引数"); });

この部分がイベントを設定する部分なのですが、
設定するコンポーネントの変数.イベント名.AddListener(() => { 関数名; });
という書き方で、ボタンに限らず大体のコンポーネントのイベントを設定できます。

イベント自体に引数がある場合

onClickイベントはイベント自体に引数が無いので、
イベントの引数を意識せずにAddListenerで設定することが出来ます。
しかし、イベント自体に引数がある場合は関数設定時にイベント引数を設定する必要があります。
Sliderのイベントを例に設定方法を記入します。

/***********************************************************************
【メイン】スライダーにイベントを設定する関数
***********************************************************************/
public void SetSliderChangeEventListner()
{
    // 【引数なし】ボタンイベント設定
    Slider setSlider;
    setSlider= this.transform.Find("オブジェクト名").GetComponent<Slider>();
    setSlider.onValueChanged.AddListener((value) => { SetChangeSlider_Vol((int)value); });
}

/***********************************************************************
【Ev】スライダー更新
***********************************************************************/
public static void SetChangeSlider(int SetVal)
{
    Debug.Log("スライダーの値が変更されたよ:" + SetVal.tostring());
}

上記の書き方で、スライダーコンポーネントにクリックイベントを設定できます。
onClickイベントとの違いは、AddListener((value) => { SetChangeSlider_Vol((int)value); });
この「value」の部分ですね。 これは、「 onValueChanged 」イベント自体の引数です。
value=変更されたスライダーのvalueになります。
このように、イベント自体の引数が存在する場合は、
ラムダ式の左辺に任意の変数名(例の場合はvalue部分)を記述する必要があります。

イベント名から引数があるか判定する方法

①.実際に記入してエラーで判別

イベント自体に引数があるかないかの判定は簡単です。
onClickイベントの記法で、引数が無いものとして記述してみる。
この方法で記述して、
・ビルドエラーなし・・・イベント引数ない
・ビルドエラーある・・・イベント引数あり

これで一発です。
引数がある場合は、以下の方法で引数の内容を確認しましょう。

②.Googleで検索

後はインターネッツにおまかせ! 「 Unity イベント名.AddListener
で検索しましょう。
これで大体のイベントの引数は検索できます。
私がSliderの引数の内容で詰まった時は、「 Unity onValueChanged.AddListener 」で検索しました。

ラムダ式でイベント追加を行うと、 イベント引数を簡単に持ってこれるのでとても便利です。

【C#】色々な型の複数要素を1つの文字列に「1行で」変換する方法まとめ

色々な場面で必要になる文字列変換ですが、
まとめたい型ごとにやり方は異なってきます。
今回は、色々な型のやり方をこのページにまとめたいと思います。
※なるべく1行で完結できる方法をまとめてます

様々な型の文字列化

配列、リスト

string setValue = "";
//配列を文字列に結合
string[] a_Get = new string[10];
setValue = String.Join("\r\n", a_Get);
//リストを文字列に結合
List<string> l_Get = new List<string>();
setValue = String.Join("\r\n", l_Get);

配列やリストは、「 String.Join( "区切り文字", "まとめるリストや配列" )
の関数を使えば1行で完結できます。

Dictionary

//Dictionaryを文字列に結合
Dictionary<string, string> dic_Get = new Dictionary<string, string>();
setValue = String.Join("\r\n", dic_Get.Keys);   //全てのKeyを文字列に
setValue = String.Join("\r\n", dic_Get.Values); //全てのValueを文字列に

Dictionaryは、キーと値は「 Dic変数名.Keys 」「 Dic変数名.Values
で配列としてまとめて取得することが出来ます。あとは、配列と同じく
Join関数を使えば1行で完結できます。

自作クラス等のクラス内変数

/*******************************************
   コピー対象の自作クラス
********************************************/
public class TestClass
{
    public int _Id;
    public string _Name;
    public string[] _Array01;
}

/*******************************************
   文字列化方法
********************************************/
List<TestClass> lcls_Get;
string setValue = "";
//string型メンバ変数を取得
setValue = String.Join("\r\n", lcls_Get.Select(x => x._Name));
//int型メンバ変数を取得
setValue = String.Join("\r\n", lcls_Get.Select(x => x._Id.ToString()));
//配列メンバ変数を取得
setValue = String.Join("\r\n", lcls_Get.Select(x => String.Join("\r\n", x._Array01)));

自作クラスのリストから変数を抜き取る場合は、
結構For文を使いがちですが、LINQを使えば1行で完結できます。
細かな条件分岐もWhereでできますので、LINQをお勧めします。

記入欄とかに次々追加する時

List<string> l_Get = new List<string>();
for (int iRow = 0; iRow < l_Get.Count; iRow++)
{
    TextBox.text += l_Get[iRow] + "\r\n";
}

上記の感じで、for文で1つの文字列化する時にありがちな書き方です。
この書き方だと大きな問題が!?
末尾に要らない改行文字が残っちゃいます。。。

これを取り除くために判定を書くのもいいですが、1行でスマートに行きましょう!

List<string> l_Get = new List<string>();
for (int iRow = 0; iRow < l_Get.Count; iRow++)
{
    TextBox.text = (TextBox.text + l_Get[iRow] + "\r\n").Trim();
}

これで解決!手順は簡単。
毎回 Trim() したら先頭・末尾に余計な文字は無くなるで!
の法則です。長年のモヤモヤだったのですが、最近発見して驚愕しました。。。

以上です。
文字列化は常に付きまとう事なので、
なるべく少ないコードで見やすく組み込みたいですね。

アプリ開発向け素材サイト紹介 ※個人でアプリ開発するプログラマー必見

個人開発の罠を紹介

今回はプログラミングとは全く関係ない話です。
ですが、個人でアプリ開発をやってみよう!と思う方は必ず通る挫折ポイントです
私の実体験ですので、これから始めようと思っている方は見て損はないと思います。

プログラミングができても絵は描けない

タイトルの通りです。私たちはプログラミングができる、または学びたい。
その成果としてアプリを作りたい!と思っている人が多いと思います。
※なので、プログラマーの挫折点です。
組み込み後術やプラットフォーム操作等は、
勉強して成長する事が出来るので挫折にはならないです。
しかし、問題なのはデザインサウンドです。
どんなにソースが綺麗で多機能なアプリを作っても、
見た目がきちんとしてないものはアプリになりません。
しかし絵なんて上手に書けないし、勉強する気にもなりません。
わしゃわしゃソース書いて色んなライブラリ使いこなしてぇんです!
だったらどうするか。。。フリー素材様のお力を借りましょう!
以下で、私が挫折した時に大変助かった
アプリ制作者向け!商用利用可能な素材サイトをご紹介します。もちろん無料です

※. 紹介するサイトによってはクレジット等の細かな規約がたまにあります。
 サイトごとの利用規約をよく読んで注意してください。
※. 2020/06現在の利用規約では商用利用可能なサイトのまとめになります。
 今後、規約が変わるかもしれませんのでご注意を!

【音系】素材サイト紹介

まずは音系の素材サイトから。
BGM,SE,ボイスとアプリには欠かせない音素材を使用させていただけるサイトをご紹介

◆ 魔王魂...BGM、SE

言わずと知れたBGM素材を大量に置いてくださっているサイトです。

◆ 効果音ラボ...SE、ボイス

こちらも言わずと知れたSE素材を大量に置いてくださっているサイトです。
汎用性のあるボイスも使用できるので、ゲームで使用できるボイスもたくさんあります。

◆ DOVA-SYNDROME...BGM、SE

こちらのサイトは、楽曲を公開しているだけではなく、
楽曲の作成依頼やボイス収録依頼を出すこともできます。
もちろん素材も大量にあるので音ゲーを作るときにとても助けていただきました。

【画像系】素材サイト紹介

次に、画像系のサイトです。
基本的にGoogleで「○○○ イラスト フリー 商用利用可」で検索します。
いいのが無かったら下記のサイトを参考にしてみてください。
※アプリに関連する画像を扱うサイトのみに厳選しました。

◆ ICOOON MONO...アイコン、UI用

このサイトは、豊富な種類のピクトグラムのような画像を扱っているサイトです。
UI用の素材としてはピッタリの画像が見つかると思います
▼【使用例】ボタン画像は全て、ICOOON MONO様の画像を組み合わせて作ったものです
メニュー下部_パネル.png

◆ イラストAC...何でもそろう

人の画像から物の画像から背景から何でもそろうのがこのサイトです。
欲しい画像を検索すればピッタリな画像が見つかると思います。
▼【使用例】イラストAC様の画像を組み合わせて作ったものです
背景_Clear.png

◆ ぴぽやブログ...エフェクト、RPG用

エフェクトというのは、複数の画像を連続で表示することで、
1つのアニメーションのように見せる素材のことです。
その中でも、なんかぶわっとしたものがエフェクトです。
▼【使用例】閃光が飛び出すエフェクト
エフェクト例.gif
例えば、上記のエフェクトをキャラの右手から出して「ロッ●バスター!」とか言うと、
ゲームにものすごくカッコよさが付加されます。
エフェクトを使うようになると、一気にゲームっぽくなるのでぜひご活用ください。

【3D系】素材サイト紹介

3Dモデルは素材だけでは使えない要素があるのですが、
絶対に知っていて損はないサイトをご紹介。(多分みんな知ってる)

◆ ユニティちゃん...キャラモデル、2Dキャラ画像、ドット絵

このサイトには本当にいつもお世話になっております。
ユニティちゃんというキャラクターに始まり、様々な3Dモデルや立ち絵、ドット絵等
どのジャンルのゲーム製作にも対応できる豊富な素材があります。
リズムゲーからスロットシュミレータからシューティングまで、
私が作成したアプリには大体出演頂いてます。

【ツール系】見た目改善サポートアプリ紹介

Illustratorなんていらんのですよ!高いのですよ!!!
という方にお勧めする、画像編集や3Dオブジェクト作成ツールをご紹介。
もちろん無料です

◆ パワーポイント(Office)

はい。パワポです!私はアプリ用の画像はほとんどパワポで編集しています。
画像を細かく編集するのではなく、素材を合体させたりするだけなら
パワポはとても使い勝手がいいです。
もう一つの利点は、
自然とパワポの扱いに慣れるので会社のプレゼン資料作成の効率も上がっちゃいます。

◆ GIMP(ギンプ)...画像編集

こちらは、細かい画像編集を行う際に非常に使いやすいツールです。
よく使う機能は、取ってきた素材の背景を切り抜くことが出来ます。
しかも、クリック一発で切り抜いちゃうので簡単で便利!
GIMPで素材を編集してパワポで組み合わせる。というやり方で画像編集することで、
難しいことを覚えなくてもそこそこのクオリティの画像が出来上がります。

◆ blender...3Dオブジェクト編集

何で無料なのか分からないほど多機能らしい3Dオブジェクト作成(編集)ツールです。
正直扱いはとても難しいです。
そもそもオブジェクトを作るというのは難しいことだから仕方ないのですが。。。
私はこのツールで行っていることは、
キャラ用ステージや背景など、簡単なオブジェクトを作成するほか、
キャラ用にアニメーションを作ることも行っています。
オブジェクトに関する操作は大体何でもできる奥深なツールですが、
やりたい事だけやり方を調べればそこまで難しくは無かったのでお勧めします。
※0知識の自分でもがんばればSDキャラを作れるぐらいにはなれましたのでご安心を!

【作成例】無料神サイトにおんぶにだっこでここまでできた

こちらは、
全て上記サイトの画像・音・3Dオブジェクトを使って作成したアプリの広告用動画です。
特化プレーヤー
→ 特化PLAYER...よかったらプレイしてみてね

全部無料でデザイン技術が無くても、頑張ればゲームっぽく見せることはできます。
アプリ開発する上で、デザイン面の負担は大きいものがありますが、
素材サイト様のご加護を受けて楽しく開発していきましょう。
皆様の知る穴場オススメ素材サイトとかあったら
コメント等で教えていただけると泣いて喜びます!

最後にCM

◆ ライムまにあ

リズムゲーとクイズを融合させた新感覚リズムゲームです。
こないだ公開して誰もプレイしてくれないので寂しいです。
良かったら見てみてください。
広告1.png

Windowsの右クリックとタスクバーを侮るな

 最近、社内で流行ってきている問題があります。

デスクトップ汚い問題です。

この問題はPCが生まれた時からの永遠の問題だと思います。

皆さんはどのように対応しているでしょうか?

やれランチャーアプリだ、やれフォルダに押し込めだなんだと騒いでいませんか?

違うんです!そもそも

開きたい物へアクセスする手段の知識が少ない

これが大きな問題でもあるんです。

Windowsはまだまだ皆さんの知らない便利機能があるんです。

今回は、簡単に開きたいものを開くための小技をご紹介します。

Windowsのお話ですのでMaccerの方はお帰りください

※誰でも知っている系のお話ですので、過度な期待はしないでください 

タスクバーはただのショートカット機能じゃないぞ

 画面下に黒いバーがあると思います。名を「タスクバー」といいます。

こいつにフォルダやアプリをドラッグ&ドロップすると

アイコンが保存され、クリックすると開ける。という

ショートカット機能があるのは皆さんご存知のはず。

しかし、このタスクバーのアイコンに他の機能があるのをご存知でしょうか?

まずはアイコンを右クリック!

f:id:apuridasuo:20200613202052p:plain

図:アイコン右クリック時の挙動

上図のようにアイコンから表示が出ると思います。

表示をよく見ると「ピン留め・最近」の2つの項目があります。

・ピン留め・・・自分で設定できる。右クリックで必ず表示される項目

・最近・・・直近でアクセスした項目が表示される

この右クリック機能があれば、

常によく使うフォルダをピン留めする。

一時的によく使う項目はピン留めしなくても「最近」でまかなえます。

しかもこの機能、

フォルダだけじゃなく大体のアプリに使えます。

VisualStudioはもちろん。Windowsアプリは必ず利用可能ですし、

他社アプリも有名なものは基本的に対応しています。

ですので、

エクセルでアクセスしたいものはエクセルのアイコンで右クリック。

メモ帳でアクセスしたいものはメモ帳のアイコンで右クリック。

この運用方法で大体のファイルに一発でアクセスできます。

 

どうでしょうか?

この右クリックの機能は使用アプリごとに簡単に管理できる。

というものが大きな利点です。

そこらのランチャー機能と違って、アクセスしたいファイルのリンクが

登録等の手順が必要なく、かつ一発で実行できるので超便利な機能だと思います。

 

自分の仕事のやり方と他人のやり方を見ていると、

業務改善だなんだと言う前に、意外と知らない便利な機能を教えあったほうが

絶対業務が早くなるだろ!と心の底から思うのですが、

「じゃあまとめてなー ※まとめても見ないけど」

の一言で終了するのが目に見えているのでブログにかいちゃいました。

 

アクセス方法の知識を深めて、無駄なリンクをデスクトップに置かない

スッキリPCを目指してみてください!

 

 

会社へのヘイトを糧に独学で学び始めて約1年たった奴の成果

 

 

【成果①】Androidアプリ作ってみた

勉強した成果の大きなものは、Androidアプリでしょう。

私の開発欲求をぶつけれるのは無限の可能性を秘めたゲーム作りしかない!

そう思って、参考書を買いあさって死ぬほどネットサーフィンして

C#、Unityを勉強しました。その成果をアプリと広告費でご紹介!

脳トレ! マッチde計算

play.google.com

ダウンロード数:50~100

記念すべき1作目のアプリ。

Unityの使い方を学びながら、デザインってムズ! 

とゲーム作りの難しさをこれでもかと思い知らされた作品でした。

すいません降ります 

ダウンロード数:50~100

電車を出るために人混みを避けるスクロール避けゲー

このゲームでUI管理、Animation管理が板についてきた気がします。

原因不明のポリシー違反で削除中。。。(´;ω;`)

ジョギング用音楽プレーヤー RUNテンポプレーヤー

play.google.com

ダウンロード数:50~100

再生する音楽を、自分の走るテンポに合わせたリズムに変化させる音楽プレーヤー

ジョギングした時に、走るテンポと曲のサビが一致した時の

グルーブ感(適当)が最高だったので作ってみました。

機能は新しいと思ったので受けるかなと思ったのですが、

やっぱり音楽プレーヤーは凄いいいものばっかりあるので伸びなかったです。

お手軽!対戦ミニゲーム

play.google.com

ダウンロード数:500~1000

みんなで遊べるパーティーゲームを詰め合わせたものです。

正直、作ったとにしょうもな。。。と思ってお蔵にしようと思ったのですが、

出すだけ出してみたらそれなりにダウンロードされて嬉しかったのを覚えています。

沖ドキ モード予測

play.google.com

ダウンロード数:500~1000

一番開発に時間がかかっていないのに、

一番評価が高かった(収益が高かった)アプリです。

やっぱり自分が欲しいものは一定数の需要があるんだな。と思いました。

スロット 特化ゾーン プレーヤー ONLINE

play.google.com

 ダウンロード数:500~1000

このアプリは、私の勉強したものの集大成でした。

オンラインスコア、3Dオブジェクト作成、キャラアニメーション作成、

エフェクト、オブジェクトデザイン作成、動画広告などなど、

プログラミング以外のアプリ制作に必要な要素を頑張りまくった一品でした。

出来た時は自分の成長を感じてすごく嬉しかったし、

レビューで高評価をもらった時はもっと嬉しかったです。

ライムまにあ リズムゲーとクイズの融合

play.google.com

ダウンロード数:0! 笑

つい最近公開したアプリです。

リズムゲーにクイズの要素を追加したらリズムゲー下手な私でも楽しめるかな?

と思って作ったアプリです。よかったらぜひプレイしてみてください

その他載せる価値のないアプリ2品

その他2品のアプリを含む、計9個 が公開できるまで作成できたアプリ達です。

こいつらの陰にはたくさんの未完成アプリの屍があるのですが、

頑張った証が残っているのはそれだけでやる気が出ます。

一年間の広告収益

直近一年間で作成したアプリの広告収益ですが、

ちゃんと調べてみたら、5万円でした。

※3か月ぐらい謎のポリシー違反でアカウント凍結くらって広告収益0円だったので、

実際は「 2019 / 8月 ~ 2020 / 5月 」までの収益になります。

全然ダウンロード数は無かったのですが、意外と貰えたほうだなぁと思いました。

(時給に換算するとえげつない低収入ですが・・・笑)

副業といえるにはおこがましい収入ですが、

会社では実感できないユーザーに向けた開発を目指して成長できる。

という事が私には得難いことなので個人的には満足な結果です。

 【成果②】テックブログやってみた

こっちは収入とかじゃないんですが、完全に暇つぶしです。

きっかけは、Androidアプリに広告を付けるには

プライバシーポリシーのリンクが必要でした。

そのためにブログを開設してサイトを作ったのですが、

ついでに自分の備忘録として使ってみるかーという事で始めたブログです。

アクセス解析

f:id:apuridasuo:20200529141528p:plain

図:ブログアクセス解析

 総記事37、総アクセス数2186

多いのか少ないのかは分かりませんが、

記事数は改めてみると少ないなー!という感想でした。。。

なぜなら、こんなクソブログでも記事1つまともに書くのにすっごい大変です。

ソース、画像、構成etc素人なりに色々考えて記事にしてるので、

この1年で、結構ブログ書いたよなー。って思っていたのですが

まさかこんなに少なかったとは。。。

まぁブログにするほどのことがあまりない日常が悪いですね!

【感想】独学の限界を感じ始めてる今日この頃

この1年、がむしゃらに勉強して色々な知識を浅く広く学んでいったのですが、

独学で学ぶという事の難しさ、というか幼稚さを思い知りました。

自分で考えて開発する。という事はとても自由度のあることだと思います。

しかし、私一人の発想力の殻をいつまでも破れない、狭い自由でした。

どれだけゲーム作りで成長しても、

この成長はちゃんとアプリの会社で働いてる人達の

成長に比べたらゴミなんだろうなぁ・・・という事実。

「こんなアプリが作りたい!」という発想はあっても

一人でデザインから音から何から何まで作成しなければならないため、

どうしても規模が小さくなってしまう歯がゆさ。

会社というしがらみから抜け出した開発は、色々な壁が見えてきた開発でした。

しかし、それこそが開発の奥深さであり楽しさだと思ってます。

現状は一人では打破できない課題ばっかりでてんやわんやですが、

その壁を越えられないと私の開発欲求を満たせる私の作りたいゲームが作れないので

色々な方向から勉強させていただき、ゆっくり進んでいこうと思います。

新たな一歩・・・SNSやってみよう

とりあえず新たな一歩として、

自分の発想の外側の人たちの感性がすごい知りたくなりました。

そこで、アカウントだけ作って放置してたSNSを始めようかなーと思ってます。

正直、ネットで人とつながるとかよく分からないし好きじゃないのですが、

食わず嫌いではよくないと思ったので、

積極的に似たような立場の方々とかかわってみようと思います。

右上のプロフィール欄にTwitterアカウント乗ってるので、

良かったらフォロー?リツイート?してやってください!!

 

本来はこういった自分語りをネットに書くのは好きじゃないんですが、

その辺のネクラ気質も直していきたいので、1年後くらいにまた成果報告という名の

自分語りやっていきたいなーと思ってます。

【C#】ネットワーク共有フォルダへの接続待ち対策

会社でツールを作っていると結構起こる問題だと思ったのですが、
意外とネットに乗ってなかったので自己解決した内容をまとめます。

ネットワークフォルダにアクセスできなかったらどうなる?

C#で指定のフォルダにアクセスする際に、必ずフォルダ存在判定を行うと思います。 System.IO.Directory.Exists()
この関数を使うのが一般的だと思いますが、Exists関数に限らず(System.IO)クラスの
メソッドでフォルダにアクセスすると、厄介な挙動をします。

Exists関数で様々な条件のフォルダを判定した時の挙動

A)ローカルフォルダ
→ 存在する=true、存在しない=false を返す
B)ネットワークフォルダ ※アクセス可の状況
→ 存在する=true、存在しない=false を返す
C)ネットワークフォルダ ※アクセス不可の状況
20秒以上接続待機(停止)し、エラーを返す
厄介な挙動はもちろんC)の状況ですね。
これではアクセス待機のせいで処理が以上に遅くなってしまいます。
今回は、この接続待ちの時間を短縮させて
ネットワークフォルダのアクセス可否判定を行う方法をご紹介します。

並列処理で時間を計って勝手にタイムアウト判定を行う

接続待ちの時間を短縮させる方法は調べても見つかりませんでした!
ですので、並列処理を使って
自分で指定の時間が過ぎたら処理を中止させる関数を作りました。

/// <summary>
/// フォルダ存在判定【タイムアウト付き】
/// </summary>
/// <param name="path">検索されるフォルダパス</param>
/// <returns>検索結果( True = 存在する )</returns>
public static bool IsFolderSonzai_Out(string path)
{
    int i_Wait = 150;   // この値【ms】だけ処理待ち
    bool exists = true;
    Thread t = new Thread
    (
        new ThreadStart(delegate ()
        {
            exists = Directory.Exists(path);
        })
    );
    t.Start();
    bool completed = t.Join(i_Wait);
    if (!completed)
    {
        exists = false;
        t.Abort();
    }
    return exists;
}

上記関数がタイムアウト付きのフォルダ存在判定処理です。
1.別スレッド(t)でフォルダ存在判定を行う
2.指定時間(i_Wait )の時間だけスレッドの完了待ちを行う
3.指定時間経過後(もしくは処理終了後)、スレッド(t)が終了していなかったら
  スレッドを強制終了。アクセス不可と判定して「false」を返す

こんな感じの処理を行う関数になってます。

以上です。 並列処理は高速化でよく使われますが、今回のように
処理待ちのタイムアウト判定で使う事もできるので、より深く理解すると
組み込みの幅が広がる感覚があって楽しくなります。

【Unity】Androidアプリの起動が遅い時の対処

ちびちび作ってたアプリがようやく完成間近の段階になってブラッシュアップ中の事。
改善必須の厄介な現象につかまりました。
検索しても出てこなかったので色々試行錯誤して、やっと解決したのでまとめます

環境と現象

Androidアプリでの現象
実機デバッグを行った際に、起動後に「Unityロゴ」が出てから
タイトル画面の表示が描画されるまでに「15秒」もかかった

f:id:apuridasuo:20200512150908p:plain
図:表示するタイトル画面の構成
今回は、上記の遅すぎる起動をどのように解決したかまとめていきます
※今回は、対応としては設定1つの変更で解決したのですが、
解決までの過程で色々対応してどんな効果があったのか、ためになったので紹介します。
※解決法だけ知りたい方は以下の「解決法(結論)」の項目だけお読みください

解決法(結論)サウンドの読み込みによる遅延

遅延の原因は、オブジェクトの描画でも、Startイベントで行っている
オブジェクトキャッシュ処理でもありませんでした。
アプリ起動時にサウンドデータを読み込む処理が遅かっただけでした。
サウンドデータをバックグラウンドで読み込むことで解決します

f:id:apuridasuo:20200512152019p:plain
図:サウンドデータの設定方法
上図のように、サウンドデータを選択して、
「Load In Background」にチェックするだけ!
これで起動が「 15秒 → 1秒未満 」に改善されました
音ゲー作ってたので大量の音データの読み込みに時間がかかってたみたいです。。。

※タイトル画面で使用する音(すぐに出力するBGM等)は、
チェックを入れると音の出力が遅れてしまうのでチェックを入れないように!!

(過程)以外と起動の遅延には関係なかった者たち

遅延と聞いて原因を予想する時、何を考えるでしょうか?
今回の様に、サウンドデータのことを思いつく人なんて天才かよ!?って感じです。
私はまず「Startイベントのキャッシュ処理」「3Dオブジェクトの描画」
この2点が原因で起こった遅延だと思っていました。
(そのせいで、解決するまでクソほど遠回りしちゃいました泣)
そこで行った対応が以下になります
・3dオブジェクトを非表示にしてビルド
・3dオブジェクトを削除してビルド
・Startイベントを全てコメントアウトしてビルド

この3つの対応をすれば、とりあえず起動は早くなるだろうから
そこから原因を深堀していけばいいや・・・と思っていました。
結果は、起動時間は全く変わりませんでした
以外だったのは、少しも速くならなかったことです。

◆Startイベントって起動の遅延に影響ないの?

改めて、Startイベントのタイミングを調べてみたのですが、
Unity - マニュアル: イベント関数の実行順
上記サイトの記入では
▼ Startイベントのタイミング
スクリプトインスタンスが有効になると、最初のフレームのアップデート前に呼ぶ
との事でした。
最初のフレームのアップデート前という事は、
やはりStartイベントの内容は描画前に呼ばれているイベントだと思います。
実際はキャッシュ処理で起動が遅くなっているのでしょうが、
まったく気にしなくていいぐらいの遅延だったのでしょう。
以外とキャッシュ処理って起動に影響しないんだ。。。とビックリしました

◆3Dオブジェクト大量においても遅延ないの?

3Dオブジェクトの描画で起動時間が遅れることはないのか!?
気になったので、今のタイトル画面にUnityちゃんを102体設定してビルドしてみました

f:id:apuridasuo:20200512155954j:plain
図:51vs51のラップバトル
実際のタイトル画面です。ラップバトルをイメージしたタイトル画面なのに
ちょっとした戦争ものみたいになっちゃいましたw
実際に起動したときの挙動は、
・起動時間は0.5秒→3秒ぐらいに長くなった(遅延した)
・起動の遅延よりも起動後の操作遅延がえぐかった
・0.5秒でBGMはなったので、Startイベントの処理は描画の遅延に関わらず終わった
こんな感じでした。
やはり、3Dオブジェクトの描画は起動の遅延にも影響があるみたいですね
ただ、オブジェクトの描画による遅延は今回のデータ読み込み遅延と違って
Startのイベントはすぐに完了する
という部分が大事だと思いました。
処理的には終わってるけど描画が追い付いていないって感じなんでしょうね
A. Startイベントはすぐ終わる起動遅延=オブジェクト描画が原因
B. Startイベント終わってない起動遅延=データ読み込み等の他の原因

こんな感じで、起動遅延の原因追及がなんとなく調べやすくなりました!!

以上です、アプリが出来たら下にリンク張るので是非遊んでね!

この問題を経て作ったアプリ

やっとやっとできたので紹介します!
リズムゲームの要素で、押すボタンがクイズになってる感じです。
操作自体は簡単なので、ぜひプレイしてみてください。
play.google.com