Maya パーツの一部がfbxに出力されない
Unityなどにfbxとして出力した時に、例えば人間の足だけが消えて出力されてしまったりする時が時々あった。
この時はだいたい、出力時にエラーを表示してくれます。ヒストリを削除するとこのエラーが消え、fbxもしっかり全て出力されます。
以上、ただのメモでした。
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に時間を当てました。
地味にですが着実にモデリングのコツはつかめてきているかもしれません!
今回気をつけたところは、、、
・なるべく立方体か円柱からパーツを作成したこと
・パーツごとにレイヤーを作って適宜非表示にしたりする癖をつけようとしたこと
・X軸を基準として、まず半分を作成しそれをミラーして全体を作ったこと
・頂点の無理な移動によってありえないねじれ方をしたフェースを作らないようにしたこと
・もちろん自分なりに少ないポリゴン数を目指したこと
・絵を参考にしてモデリングをすること
特に、絵を参考にした場合、輪郭を決める際も非常に役に立ちました!なので次回からもこの方法を使用してく
効率が上がりますね!(初めからやれよ笑)
明日は、色を塗ってみてからアニメーションをばばばばっと作ろうかなと思います。
これ、Rigつけるの大変そうだ。。ではでは!
雑談 Unity系でちらほら今まで気にしなかった裏の処理の話
ドローコールを少なくする
【Unity】簡単明快なdrawcall削減の例 - Qiita
簡単な例になってしまうが、同じオブジェクトを使用する場合、まとめて呼び出すとそのぶんドローコールが少なくなるらしい。ほんの一例だけれど、すごいワクワクする話じゃないですか!
そもそもシェーダーとは
Unity のシェーダの基礎を勉強してみたのでやる気出してまとめてみた - 凹みTips
上のサイトさんの方が細かく書いてくれていたけれど、途中から僕の頭はついていけなかった。なんかCSSみたいな感じですねとしか言えないのが不甲斐ない。。逆に、そうやって特性を与えていると考えれば理解も早いのかな?!
ミップマップって結局なんなんだ
描画を細かく正確に行っていたら重くなっちゃうし時間もかかる。細部はどうせ見えないのだから、荒くしてしまえ!あらかじめアンチエイリアスみたいに潰しておけば、描画処理は早いよ!って感じですかね。これを意図しなくても勝手にやってくれる設定になっていることろも、unityは便利ですね!全く知らずに成長していくところでした。
雑談
全体的に、実装どうこうという話ではなく、どれだけその機能を理解して、いかに処理を少なくスマートにするかという話。
今まで目に見える部分のみを作ろうと必死で勉強してきたけれど、こういう見えていない部分を調べて本当に効率のいい実装を探るもの本当に面白そうだなと思った!え、今までと同じ見た目なのに、処理が軽くなるってなんかロマンの塊すぎる!早く制作終わらせてそういうことを突き詰める時間が欲しくなったり笑 しっかりどっちもやらないとそれこそunityの便利機能に依存しまくった人間になってしまう。。。今日はとてもいい経験をさせてもらった!そういう環境にずっといたい。
Unity Time.timeSinceLevelLoad WaitForEndOfFrame など時間の計算系で調べたこと
みなさんご存知のこちらの大変頼りになるブログを参考に、シーンのフェード遷移機能を自分なりにいじっていた際、少しよくわからないメソッドをたくさん使用していたので、書いておきます。
今回いじろうと思った場所
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内の計算では、新しいシーンでの時間で計算されていました。これがシーン遷移時のフェードがうまくできなかった原因かなと思います。
追記
このスクリプトのフェードインとフェードアウトって逆に実装されている気がする。フェードインって徐々に画面が映る手法で、フェードアウトが徐々に暗転していくようなものだと思っていた。さてどちらが違うのか!笑