セキュリティ系の勉強・その他開発メモとか雑談. Twitter, ブログカテゴリ一覧
本ブログはあくまでセキュリティに関する情報共有の一環として作成したものであり,公開されているシステム等に許可なく実行するなど、違法な行為を助長するものではありません.

Unity 公開されているUnity道場のスライドがすごくためになる!

 いかに面白いものを作るかではなく、どう効率よく実装するかも気になり始めているこの頃。とても素晴らしい資料を発見いたしました。

【Unity道場】パフォーマンス最適化の ポイント // Speaker Deck



 Unity道場なんていうイベントがあるんですね!ホームページへはここから飛べます。資料なんかも載っているので興味を引いたものは見ておいて損はないですね!素晴らしい!

 で、今回発見した上の資料はパフォーマンスの最適化について書かれていましたので、今の僕の興味範囲にドンピシャな内容でした!が、レベルが高くて全くついていけなさそう。基本的なことがわかっていればついていけるのかも?!ということで、僕のチンケな頭でも理解できるように、専門用語をとことん調べてここに書き出します笑 初心者丸出しな日記になるけど、自分の成長のためなら仕方ない笑 誰かの助けにもなればいいな笑



CPUとGPU
(ここからわからないんかい!とか言わないで笑)
Central Processing Unit と Graphics Processing Unit の略称です。CPU には汎用性でGPUには画像処理で活躍をしてもらっているらしいです。CPU は計算速度が早い、GPU は複数処理を一緒に処理できるがそれぞれの計算自体は CPU ほど早くはない。お互いに適材適所することで共存しているんですねきっと!
 スライドの最初に言いたいことは、「1フレームは CPU,GPU の処理が長い方に依存する。全体の性能としてバランスが取れている Unity エディタに対し、実際のプラットホームは CPU が弱い GPU が弱いなど性能差があるため、実機でテストをしながらやるのがトラブルを防ぐ手段だよ」って感じですか?

Unityプロファイラー
 パフォーマンスの確認ができるそうです。特に iPhone,Android の実機を繋げば、そのパフォーマンスを確認できるため便利そう!今度使ってみる!詳しくは下のリンクを参照。
Unity - マニュアル: プロファイラー ウィンドウ


GPUの負荷軽減〜LOD
 LODとはなんぞや!Level Of Detailの略だそうで、カメラから遠いオブジェクトのポリゴン数をその距離に応じて減らして表示しようという工夫!Unity 自体には元々組み込まれている機能なので、後は自分たちでそのアセットを準備し、設定してやればいいそうです!これにより描画するものが削減され、処理がそのぶん軽くなるとのこと!下に参考になるブログさんのリンクを貼っておきます!
【Unity】LODでパフォーマンスを向上させる - 藍と淡々


GPUの負担軽減〜Occlusion Culling
 オクルージョンカリングと読むそうです。カメラの領域外のオブジェクトのレンダラーを無効にすることをフラスタムカリングと言うそうですが、オクルージョンカリングはあるオブジェクトが他のオブジェクトに隠されていて現在カメラに映らないときに、オブジェクトのレンダリングを無効にする機能だそうです。これは自動では行われないので自分で設定する必要があり、少し手間がかかりそうですね笑 ダンジョンを探検するようなゲームではとても有効な手段のように思えます。詳しくは下のりんくから見てください。これは少しレベルが高そうです。ちなみに、このようにカメラから見てオブジェクトが二つ前後で重なっている状態をオーバードローと呼ぶそうです。いかにも無駄な処理っぽい名前。。。まぁ普通の英語ですが笑
Unity - マニュアル: オクルージョンカリング


アセットバンドルとは
 Sceneとかがまとめて入っているあれです。きっと
Unity - マニュアル: アセットバンドル


ScriptableObject
ScriptableObjectについて - テラシュールブログ


Create,Load,Clone
 Create は AddComponent の処理に時間がかかる。Load は値の流し込みに時間がかかる。Cloneは最速だが、親子関係を操作するのが大変?といった感じ。スライドではScriptableObjectを使用したLoadを解決用の一例にあげていた。


CPU~OnBecameVisible
 見えるようにするメソッド。上記の OcclusionCulling をしない場合などは有効だと書いてある。



 後は、localPositionを使うなど、比較的わかりやすいものだったかな。。ただ、アニメーションのfbxの部分だけはイマイチわからなかった。Mayaの使い方もしっかりは理解できていないので、この辺りは自分の中で改善できそうな点かなと新ためて思いました。

 ただ、OcclusionCullingや特にLODは自分の中で大きな収穫だったかなと思います!すごい良い資料に巡り会えました。

雑談 Mayaで鳥っぽいものを作った。

今年の予定を全て消化したのでようやく心にも時間にもゆとりがもてました!というわけで今日はMayaに時間を当てました。

f:id:thinline196:20161228011944p:plain


f:id:thinline196:20161228012117p:plain



地味にですが着実にモデリングのコツはつかめてきているかもしれません!
今回気をつけたところは、、、
・なるべく立方体か円柱からパーツを作成したこと
・パーツごとにレイヤーを作って適宜非表示にしたりする癖をつけようとしたこと
・X軸を基準として、まず半分を作成しそれをミラーして全体を作ったこと
・頂点の無理な移動によってありえないねじれ方をしたフェースを作らないようにしたこと
・もちろん自分なりに少ないポリゴン数を目指したこと
・絵を参考にしてモデリングをすること


特に、絵を参考にした場合、輪郭を決める際も非常に役に立ちました!なので次回からもこの方法を使用してく
効率が上がりますね!(初めからやれよ笑)
明日は、色を塗ってみてからアニメーションをばばばばっと作ろうかなと思います。

これ、Rigつけるの大変そうだ。。ではでは!

雑談 Unity系でちらほら今まで気にしなかった裏の処理の話

ドローコールを少なくする

【Unity】簡単明快なdrawcall削減の例 - Qiita

簡単な例になってしまうが、同じオブジェクトを使用する場合、まとめて呼び出すとそのぶんドローコールが少なくなるらしい。ほんの一例だけれど、すごいワクワクする話じゃないですか!


そもそもシェーダーとは

Unity のシェーダの基礎を勉強してみたのでやる気出してまとめてみた - 凹みTips

その1 UnityにおけるShaderとは?


上のサイトさんの方が細かく書いてくれていたけれど、途中から僕の頭はついていけなかった。なんかCSSみたいな感じですねとしか言えないのが不甲斐ない。。逆に、そうやって特性を与えていると考えれば理解も早いのかな?!

ミップマップって結局なんなんだ

ミップマップ - Wikipedia


描画を細かく正確に行っていたら重くなっちゃうし時間もかかる。細部はどうせ見えないのだから、荒くしてしまえ!あらかじめアンチエイリアスみたいに潰しておけば、描画処理は早いよ!って感じですかね。これを意図しなくても勝手にやってくれる設定になっていることろも、unityは便利ですね!全く知らずに成長していくところでした。




雑談

 全体的に、実装どうこうという話ではなく、どれだけその機能を理解して、いかに処理を少なくスマートにするかという話。
 今まで目に見える部分のみを作ろうと必死で勉強してきたけれど、こういう見えていない部分を調べて本当に効率のいい実装を探るもの本当に面白そうだなと思った!え、今までと同じ見た目なのに、処理が軽くなるってなんかロマンの塊すぎる!早く制作終わらせてそういうことを突き詰める時間が欲しくなったり笑 しっかりどっちもやらないとそれこそunityの便利機能に依存しまくった人間になってしまう。。。今日はとてもいい経験をさせてもらった!そういう環境にずっといたい。

Unity Time.timeSinceLevelLoad WaitForEndOfFrame など時間の計算系で調べたこと

tsubakit1.hateblo.jp

みなさんご存知のこちらの大変頼りになるブログを参考に、シーンのフェード遷移機能を自分なりにいじっていた際、少しよくわからないメソッドをたくさん使用していたので、書いておきます。

今回いじろうと思った場所
IEnumerator FadeinCoroutine (float time, System.Action action)
	{
		float endTime = Time.timeSinceLevelLoad + time * (1 - cutoutRange);
		
		var endFrame = new WaitForEndOfFrame ();
		while (Time.timeSinceLevelLoad <= endTime) {
			cutoutRange = 1 - ((endTime - Time.timeSinceLevelLoad) / time);
			fade.Range = cutoutRange;
			yield return endFrame;
		}
		cutoutRange = 1;
		fade.Range = cutoutRange;

		if (action != null) {
			action ();
		}
	}
各メソッドについて

Time.timeSinceLevelLoad
”フレームが開始された時間 (Read Only) 。最後のレベルが読み込まれてからの時間 (秒) です。”
WaitForEndOfFrame ()
”スクリーン上のレンダリングが完了するまで待ちます。”
とのことです。(スクリプトリファレンスより)あれ、以外と少なかった。


このコードが行なっていること

 このコードはフェードインの場面です。条件として、この状態ではシーンの遷移には対応できていません。

・最初の一行目 ”float endTime = Time.timeSinceLevelLoad + time * (1 - cutoutRange);” はtimeをユーザが自分で指定した遷移時間だとして、終わる時間を計算し変数に格納しています。


・次の行 "var endFrame = new WaitForEndOfFrame ();" varについては以下を参照。
連載! とことん C#: 第 10 回 型を書かなくても強い型付け! (var とジェネリック) in C#
varは"ある型の値を返すメソッド"として使用しているのかな?僕全くvarを使用しないのでわからないですが。endFrameを呼べば、new WaitForEndOfFrame ()が呼べる状態にしているのでしょうか?


・その後のwhileでは、割合でMaxを意味する1から、現在から終了までの時間を指定した遷移時間で割ることによって現在のフェード具合を算出、それを別メソッドであるフェードの具合を実際に表示するメソッドに託し、先ほどのvarで準備したレンダリング終了まで待機するメソッドを呼び出しています。(きっとそう)これで、フェードを表現しているのですね。

このコードがシーン遷移に対応していなかったワケ

  "Time.timeSinceLevelLoad"これだと思います。元々、今回使用させてもらっているスクリプトはシングルトンなものではなく、僕が無理やりDontDestroyなどをつけてしまっているのもありますが、シーンが変わったらこの値は絶対変化します。おそらく、endTimeを計算した最初の呼び出しでは遷移前のシーンの時間で計算されていました。その後の現在の遷移割合を計算しているwhile内の計算では、新しいシーンでの時間で計算されていました。これがシーン遷移時のフェードがうまくできなかった原因かなと思います。



追記

 このスクリプトのフェードインとフェードアウトって逆に実装されている気がする。フェードインって徐々に画面が映る手法で、フェードアウトが徐々に暗転していくようなものだと思っていた。さてどちらが違うのか!笑

Unity(雑談) バトルシーンにおける敵と味方のスクリプトについて

どうも!三日間寝込んでおりました。今日は一時間ほどunityに触ってリハビリといったところでしょうか笑 少しいじっていました。


ユーザが触るプレイヤーとその敵のスクリプト

 自分なりにしっかり考えてから制作を始めたつもりだったのですが、やはり詰めが甘いところがボロボロとありますね!どうもその見出しの二人のスクリプトが類似するんですよね。。いや、類似することなんてみんな承知なことなのですが、全てが同じわけではないわけで、僕はやはり今回は分けるべきだなと思ったんです。しかし、コーディングをしていると自分なりに「ここはこうしたほうが流用性があるな、、」って部分が出てくるわけで、そこをいい方向に修正していたら結果的に「あれ、この二人のコントローラほぼ同じになっちゃった」とか「同じコードを二つのスクリプトに追加してるよ」なんてなことがよく出てくるようになりました。

 コーディング中に修正をしていい形に持っていけるようになっているのは素晴らしい成長なんだと自分で思っています。なので、こうやって気づいたとこをここに書き残しておくことで次の制作の時に、さらにレベルアップのきっかけになるんじゃないかと思ってここに書き残します!(ポジティブに考えないとやっていけません!)

・アニメーションコントローラ及び、ダメージや魔法発動エフェクトは敵味方同じものを使用可能
 これは、人間しか登場しない紙芝居ちっくなものなら当然同じコントローラを使いまわせますが、戦闘シーンのようなものであっても攻撃モーションというものがそれぞれにあって、ノックバックのリアクションがあってそれの指示をアニメーターに渡すスクリプトなら使いまわせますねという考えです。使わないモーションを呼び出す関数は使用しなければいい話で。ただこの方法の難点は、関数にモーション名や技名を使用できないことです。つまり万人が一瞬で読んで理解できるスクリプトにはできないです。自分も見返した時に、メモが少なければ理解できない可能性もありますね。技1技2など、企画の時点でしっかりとそのキャラの技名と番号を対応させておくことで、これも回避は可能であると思うので、出てくるキャラやモンスターが多ければ多いほど、この案を僕は推すと思います。


・敵のコントロールスクリプトをまとめて一つのオブジェクトに貼り付け、流用する
 これは敵でなくてもたくさんの種類のモデルを用意して同じスクリプト群を同じように使用したい場合の方法についてです。Unityはpublicな変数にドラッグ&ドロップで直感的に紐付けができるので便利ですが、その操作をどこか一つでもやり忘れると読み込みエラーが起こります。(たまに何故かMissingになるけど)その例えを上げやすいのが、敵モンスターでした。
 で、僕は驚愕の事実を知りました。なんと、Animator は Avatar さえしっかり紐づけてやれば、子オブジェクトのモデルのアニメーション管理もすることができるのです。(これは教えて欲しかった) 何ができたかと言いますと、Animatorやそこに指示をだすアニメーションコントローラ、その他敵を操作するスクリプトは全てまとめて一つのオブジェクトに貼り付けてプレパブ化でもして、後はモデルごとにモデルをそのオブジェクトの子ノードに配置&アバターを紐付けしてあげると、なんといちいち全てチェックしながらスクリプトを貼り付けなくても、簡単に流用ができてしまった!
 少し前の僕は、モデルのオブジェクトに Animator やらスクリプトやらを全て貼り付け、それを新しいモデルのキャラを追加するごとに貼り忘れがないかチェックしながら作っていました。なので、これからはこれをぜひ使っていきたい!というか、偶然このダラダラの記事を読んでいる方がいたら、ぜひ真似してほしいです。


病み上がり&あいかわらずの国語力で、カオスな文になっているかも笑 まぁ、今日は親にLINEのフリーコインを貯めて上げて、ふなっしーのスタンプを購入させてあげることができたので、非常に満足です!(全く記事と関係ない)以上。早く体調良くなれ!!!