ラベル Unity-メモ の投稿を表示しています。 すべての投稿を表示
ラベル Unity-メモ の投稿を表示しています。 すべての投稿を表示

2018年9月16日日曜日

Unity2018で旧来のパーティクルがエラーになる

最近過去プロジェクトを Unity2018.2.7f1 で開いたところパーティクル関連でエラーが出るようになったので調べてみた。


エラーの概要 

エラーになるのはクラス ParticleEmitter や ParticleAnimator。
所謂 Legacy Particleコンポーネント。

これに代わる新しいパーティクルコンポーネント Particle System に完全移行が予定されているらしい。
Unity2018でいよいよLegacy Particleコンポーネントが使えなくなった、ということみたいです。


移行とUnityのバージョン対応はだいたい以下の通り。
  • Unity2017.4 以前
    Legacy Particleコンポーネント、Particle System 共に動作する。
    ※このUnityバージョンで移行作業を行うといずれも動作するのでやりやすい感。
    実際に動作してるパーティクル結果の比較もできるので。
  • Unity2018.1以降
    Legacy Particleコンポーネントは「今のところ」一応残っている。
    ただし各プロパティが Read Only でスクリプトから変更できない。
    ※近いうちに完全に消えるらしい。
    少なくとも 2018.3 では コンポーネントのクラスも無くなっている。C#ソースコードでコンパイルエラーが出る為、実質 Particle System への移行が必須になった様子。

従来この手のケースでは新しいバージョンのUnityでプロジェクトを開いた時、C#ソースコードの自動変換が走ってなんとかしてくれることが多かった。
(コンポーネントのプロパティ値変更がメンバ関数経由になった頃とか)
が、この件に関しては自動では変換できない。


対応方法概要

大まかに以下の2つの対応が必要。
  1. オブジェクトに付いている Legacy Particleコンポーネント を Particle Systemへ置き換える作業。
  2.  Legacy Particleコンポーネントを制御していたC#ソースコードを Particle System対応に修正する作業。

「1.」のコンポーネントの置き換えは自動変換できるEDITORスクリプトが公開されているのでそれを利用すれば楽ができる。
ただしUnity2018.3以降でしか利用できないと明記あるので注意。
※Unity2018.1~Unity2018.2では動作しないので注意。

「2 .」のC#ソースコードは手動で書き換えが必要。

コンポーネント自動変換手順

自動変換できるEDITORスクリプトをダウンロードして、シーン内の Legacy Particleコンポーネントを一括変換する。
  1. Unityフォーラムのココを開く
    https://forum.unity.com/threads/release-legacy-particle-system-updater.510879/
  2. ページ下の方のにある「Legacy_Particle_System_Updater.cs]をダウンロードする。
    ※Unityの中の人が作成したものらしいが、一応プロトタイプと明記されているので色々自己責任(?)で使用。
  3.  UnityのAssetsフォルダ内のEditorフォルダに入れる。
    無ければAssets直下にフォルダ名 Editor を作成してそこにドラッグ&ドロップで入れる。
  4. 一旦Unityを再起動。目的のプロジェクトを再度読み込む。
  5. ツールバーから、Assets>Upgrade Legacy Particles が新たに選べるようになっている。これを選択する。
  6. 「Upgrade Legacy Particles 」ダイアログが開く。
  7. 「Cleanup Mode」のプルダウンから
    ■「Disable Legacy Renderer」を選んだ場合:
    Legacy な Component は削除はされないがコンポーネントをDisableにする。
    とりあえず以前のパラメータ等確認目的で残しておきたい場合等。
    ■「Delete Legacy components」を選んだ場合:
    Legacy な Component は自動的に削除する。
  8. 「Upgrade Everything」ボタンを押す。
    シーン内の Legacy Particle コンポーネントのある個所に、新しい Particle System コンポーネントを自動的に新規追加してくれる。
    この際、Legacy Particleコンポーネントの各種設定パラメータを読み取って、新しく追加する Particle System コンポーネントを自動的に反映してくれる。
    ※Particle AnimatorのColor遷移の指定値なども引き継いでくれるので便利。


C#の制御コード書き換え

    これは手動で書き換えないとダメ。

    パーティクルのON/OFF制御

    とりあえずこんな感じで置き換えられる。

    ----- Legacy Particle コード-----
    void SetParticle(bool sw) {
        ParticleEmitter pe_FX = GetComponent<ParticleEmitter>();
        pe_FX.emit = sw; // パーティクルON/OFF
    }

    ----- 新Particle System コード-----
    void SetParticle(bool sw) {
        ParticleSystem ps_FX = GetComponent<ParticleSystem>();
        if(sw==true) {
            ps_FX.Play();
        }
        else {
            ps_FX.Stop();
        }
    }

    パーティクル色遷移制御

    Legacy Particle だと Particle Animatorコンポーネント に色変化を配列で持たせることができた。C#ソースコードからこれの書き換えも配列書き換えで安易にできた感。

    新Particle Systemコンポーネントだと Inspectorで見える各種モジュールの「Color over Lifetime」がこれに相当。
    「Color over Lifetime」にチェックを入れて、その中の「Color」にある時間遷移点
    (デフォルト5か所)のRGB(下部)とALPHA(上部)を修正すればできる。これをC#ソースからやれば良い。

    C#ソースからのやりかたは公式ドキュメントに記載あり。


    Unity DOCUMENT(2018.2): ParticleSystem.colorOverLifetime


    クラスGradientであらかじめ、

    • 時間遷移位置とRGB値群
    • 時間遷移位置とALPHA値

    を生成しておき、メンバcolorOverLifetime下のcolorに設定して反映する感じ。
    ※RGBとALPHAが個別指定できるようになった。

    サンプル
    GitHub: Sample_LegacyParticle_to_unity2018
    (https://github.com/maruton/Sample_LegacyParticle_to_unity2018)





    2016年10月22日土曜日

    リフレクションプローブ


    Unity5でリフレクションプローブ(ReflectionProbe)を使うメモ。

    使用環境:Unity5.4.2f1

    どんなことができるか

    室内において、金属などの反射オブジェクトの映り込みを調整したい場合等に有効。

    通常反射物は室内でもスカイボックスの影響を受けてしまう。
    (基本的にスカイボックスはシーン上のオブジェクトすべてに影響する為)。


    そのような際にリフレクションプローブを配置することで室内の風景を映り込ませることで解決できる。
    他、車が空下からトンネルに入った際などの映り込みの切り替えなど。



    リフレクションプローブ概要

    リフレクションプローブを置いた地点から360度視界のCubemapを内部で自動生成してくれる。
    Cubemapはスカイボックスで使われている6面ボックスのマップと同じ概念で、自分でCubemapを指定することも可能。
    Cubemap生成範囲は指定可能なので部屋の壁、床、天井などを範囲に設定すると良い感じ。

    あたかも部屋専用のスカイボックス=Cubemapがあるようになる(ただし実際にシーン上では見えない)。

    リフレクションプローブの有効範囲内にあるオブジェクトは、先のCubemapが映り込むようにできる。
    結果的に部屋内の景観(壁、床、天井、置物類)が映り込むような状態にできる。

    映り込み先の(反射する)オブジェクトは移動するものでも可。

    リフレクションの種類指定は3つでコンポーネントのTypeで指定。
    • Baked
      事前に設定されているリフレクション空間から静的な(映り込ませ用の)Cubemapを自動生成してくれる。ただし映り込む周囲景観オブジェクトはstatic限定。
      しかしその分軽量でモバイルでも使える可能性がある。
    • Custom
      ユーザが用意したCubemapを手動で指定できる。
    • Realtime
      static以外の周囲景観オブジェクトも映り込む。動的にCubemapを生成することになる為、負荷は上がる。

    主にBakedを使うことが多くなりそうな気がします。 


    リフレクションプローブ設置手順(Baked)

    リフレクションプローブの設置と設定


    部屋の中に設置すると仮定して、


    Empty Objectを作る。

    コンポーネント ReflectionProbe を追加する。

    コンポーネント ReflectionProbe のTypeはBakedにしておく。

    これを部屋の真ん中付近に置く。
    ※この置いた地点を中心に360度視点のCubeマップを自動生成してくれるようになる。
    ※あえて映り込ませたいようなオブジェクトアイテムがある場合はその中心に配置するとそこを中心にCubemapを生成してくれるので良い感じ。
    コンポーネント ReflectionProbe でCubemap生成範囲を設定する。
    図中#2ボタン押しでシーン内に調整点がでてくるので、それを掴んでドラッグで調整。



    映り込む側オブジェクトの設定

    部屋の壁、天井、床などの周囲景観として映り込ませたいオブジェクトの設定。

    オブジェクトを static に設定する。


    映り込まれる側オブジェクトの設定

    • Mesh Renderer
      Reflection Probes: BlendProbes
    • Material
      Shader: Standard シェーダー使用(リフレクションプローブ対応のシェーダー要)
      Reflections: チェック入れSmoothness: 1  ※1に近いほど映り込む。
      Metalic: 1 ※1に近いほど鏡面反射な映り込みになる。





    追加補足

    ・CubemapのBake(?)に結構時間がかかる。
    多分CubemapのBakeだと思われますが、生成に結構時間がかかる。
    Unityウィンドウ右下ステータスバーにさりげなく進行状況が出てくるのでチェック。
    その間もエディタは使えるし再生もできる。ただし再生してもまだ反映されてないので注意。
    Bakeが終わるまで気長に待つしかなさそう。
    ※作業中はいろいろ間引いて高速化は可能だが、最終微調整はどうしても時間がかかる。

    ・リフレクションプローブが複数ある場合、近い方が優先してブレンド。

    ・1つのリフレクションプローブだけ映し込みたい場合は、そのオブジェクトの Mesh Renderer の Anchor Override に そのリフレクションプローブのオブジェクトをドラッグ&ドロップする。ないしはプルダウンで選択する。

    ・映り込ませる(反射)オブジェクトは staticである必要はないので移動できる。
    ただし映り込み方に注意(Bakedの場合)。
    リフレクション空間に突入すると映り込むようになる。
    その際、そもそもリフレクションプローブのボックス6面に事前内部生成したテクスチャをリフレクションプローブの中心点で観測したように映り込ませる様子。
    なので映り込まされるオブジェクトは、リフレクションプローブ空間内のどこに移動しても同じように表面に投影されている。つまり位置による補正が無いので周囲の景観具合やまじまじ見るとおかしいのがバレてしまう可能性がある。
    ただカメラ視点変化での反射には追従してるので一見するとバレにくい。ここが軽量且つそれっぽくみせるコツかも。

    ・リフレクションしてるオブジェクトはさらに別なオブジェクトでリフレクションしない
    1. リフレクションプローブの効果で既に反射しているオブジェクトAがあるとする。
    2. その近くにもう1つ同じように反射しているオブジェクトBがあるとする。
    3. この時、オブジェクトBにオブジェクトAは映り込める位置にあるとしても、映り込まない。
    映り込みは1世代までみたいです(なので軽量とも?)。この辺は利用時注意。
    逆に意図的に「映り込ませない」ような演出にもできるかも?
    ※Blender等ではこのIllumination映り込みの反射回数指定みたいなのを有効化すると結局レイトレーシング計算していたような記憶。軽量化の為、反射ネスト1回まで演算はうなずけます。それでも結構な演算負荷に見えるので。

    サンプルプロジェクト

    簡単なサンプルをGitHubにアップロード。
    使用環境:Unity5.4.2f1。
    https://github.com/maruton/Sample_ReflectionProbe

    画面右の「Clone and download」からプルダウン内「Download ZIP」で落とせます。



    参考URL: リフレクションプローブリフレクションプローブの使用

    この記事では「ユニティちゃん」コンテンツを利用した画像を含んでいます。 © UTJ/UCL




    2016年8月30日火曜日

    Polygon Fill ~ SubStance Painter


    SubStance Painterの Polygon Fill機能と Quick Mask機能で簡単にメッシュ面を塗る方法。

    こんな感じのものを塗ってみます。




    メッシュのエッジ線を境目にちょっと塗りたい時に便利です。

    ■環境

    SubStance Painter2.3.0

    OS: Windows10pro バージョン1607(Build 14393.82)
    CPU: i7-6700K
    MEM: 32GB
    GPU: GeForce GTX960(4GB)

    ※Polygon Fill機能、Quick Mask機能はVer1.xでも同じだと思います。


    ■モデル

    Blenderで適当に作った以下のモデルを使って作業していきます。
    OBJ形式で出力しておきます。





    ■新規プロジェクト作成

    SubStance Painter2.2を起動。
    CTRL+Nで新規プロジェクト作成ダイアログを開く。
    Mesh の Selectボタンから先のOBJファイルを選択。
    他の欄も以下のように設定し OK で進む。



    以下のような感じになります。
    ここで最初からある LayersウィンドウのLayer1は削除しておきます。


    File>Save as... で適当なファイル名で保存しておきます。



    ■作業

    ベースのマテリアルを設定

    1. Fill Layerを作成(Fill Layer 1)。
    2. 作成したFill Layerを選択。
    3. Materialsウィンドウから、Plastic Glossy Pure を選択。
    以下のようにモデル全体が青のマテリアルで塗りつぶされます。



    Quick Mask、Polygon Fill で塗る色の準備


    前項と同じ要領で Fill layer を追加(Fill Layer 2)、マテリアルに SciFi PVC Plasticを設定。

    Fill Layer 2上で右クリック>Add black mask。
    マスクに何も描かれていない為この時点でモデルには Fill layer 1が反映されます。


    Quick Mask、Polygon Fill で塗る

    Fill layer 2のマテリアルで塗っていきます。

    1. Fill layer 2の black mask の四角をクリックして選択状態にします。
    2. 左上のツールアイコンから、Polygon Fill アイコンをクリックして有効にします。
    3. すると3D Viewのモデルにメッシュのエッジ線が見えるようになります。 
    4. さらにProperties - Polygon Fillウィンドウの Polygon Fillアイコンをクリックして有効にします。


    1. 塗る際はProperties - Polygon FillウィンドウColorスライダをめいっぱい右に寄せて1.0にします。(逆に消す時は左に寄せて0.0にして使う)

    2. 右クリック+ALTでだいたい真横からみえる位置に回転、さらにSHIFTも押下すると視点が正確に真横にスナップします。右クリック+ALT+SHIFTで視点角度が90度単位でスナップ)。
    3. 3D view上でTキーを押すと「Using quick mask」と表示されます。

      モデルの中央のみを選択するようにマウスでクリック&ドラッグで四角く囲います。
      囲ったメッシュ面がblack maskに自動的に書き込まれ、Fill layer 2のマテリアルが適用されます。
    4. このとき奥のメッシュも全て囲い対象になってしまう為、4隅のポールも一部選択されてしまいます。
      Properties - Polygon FillウィンドウColorスライダをめいっぱい左に寄せて0.0にします。
      4隅ポールの塗られてしまった部分をマウスドラッグで横長の四角で囲います。




    最終的に以下のように目的のメッシュ面のみに Fill layer 2を適用できる black maskが出来上がります。




    この要領で、

    • Fill layer + black mask
    • Polygon Fill
    • Quick mask
    を使うとSubStance Painter上の作業だけで任意のメッシュ面のみにマテリアルを適用できます。


    ちょっと塗りたい&メッシュ面境界で良い場合は便利です。



    以下、他も塗った状態。



    塗り絵感覚なのが簡単で良いですね。


    Unityにインポートするとこんな感じ。














    2016年6月25日土曜日

    UnityでCardboard SDK使用時エラー対処 ~ Failed to re-package resources.

    CardboardのSDKを使ってみたら、いきなりエラーでつまずいたので対処法をメモ。


    ■問題点

    Unity上でビルドすると、

     Failed to re-package resources. See the console. See the Console for details

    というエラーダイアログが出る。
     

    コンソールログはこんな感じ。



    ■開発環境


    Windows10 Pro (x64)
    Unity 5.3.5f1 Personal
    Android SDK Manager Revision 25.1.7

    アプリはこちらのをダウンロードして使用。

    EmergentVR cardboard-unity

    これに含まれる以下の2つのパッケージを空のUnityプロジェクトに放り込めばアプリの準備はOK。
    • CardboardDemoForUnity.unitypackage
    • CardboardSDKForUnity.unitypackage
    ※最新のCardbordのSDKはDaydream対応で名称が gvr-unity-sdk-master 等と変わっていたかも。とりあえずちょっとテストするには問題なし。



    ■原因

    Android SDK Build-tools が最新版(Rev.24)すぎるとまずい模様。
    Rev23以前を使えば良さそう。


    ■対処

    Android SDK Build-toolsのRev.24を削除して対処。
    Rev23以前を残すようにする。

    Android SDKのインストール先ディレクトリから SDK Manager.exeを実行。
    (例:インストール先ディレクトリ\android-sdk_r24.4.1-windows\SDK Manager.exe)

    起動したら"Tools">"Android SDK Build-tools"の Rev.欄を見る。
    Rev.欄が24の行が Installed になっていることを確認。


    "Android SDK Build-tools"の Rev. 24の行にチェックを入れて、右下の"Delete 1 package.."をクリックしてアンインストール。

    Not Installedになったことを確認。
    ※すぐ下のRev. 23.0.3 はInstalledになっていることを確認。なっていない場合は、チェックを入れて右下の"install 1 package"をクリックしてインストールしておく。



    これでUnity上でコンパイルが通ります。


    ■機材(おまけ)

    Cardboardはハコスコを購入。
    6000円位で買ったスマホ AcerZ200で実験。

    ちょっと画面サイズがずれたりしてますが、50fps位でていてそれなりにVRぽいです。
    (かなり非力なスマホなので激しい3Dアプリは厳しいですが)

    ちなみに7インチ以上のタブレットでは画面が大きすぎて両眼距離からかけ離れてしまいうまく見えませんでした。

    2015年10月17日土曜日

    オブジェクトのタグ名検索でハマったこと

    Unityでオブジェクトのタグ名検索でちょっとハマったのでメモ。

    結論からいうと、オブジェクトのタグ名検索があてにならない特定の状況&タイミング(?)があるので注意。
    ※ひょっとするとどこかに明記されてる(?)既知の仕様かもしれません。


    ■環境


    Unity 5.1.1f1 personal (C#使用)
    Windows7


    ■注意すべき状況&タイミングの概要


    タグ付け済みの子オブジェクトを含む親オブジェクトのプレハブがあるとします。
    そして既にシーン上にInitiate済みとします。

    説明の便宜上オブジェクト名、タグ名は以下とします。
    • 親オブジェクト名:ObjectA
    • 子オブジェクト名:ObjectC (タグ名:TagObjectC)


    問題(?)が起きる手順。
    1. タグ名(TagObjectC)で検索したものを GameObject型の変数に保存。
      ※特に問題なし。
       
    2. ※時間経過でフレームが進み、現在 n フレームとします。
       
    3. ObjectA を Destroyする。
      ※つまり子オブジェクト(ObjectC)も消えます。
       
    4. 同フレーム中にObjectAを再度Initiateする。
       
    5. 「1.」でタグ名(TagObjectC)検索&保存済みのGameObject型の変数の指すObjectCは既にDestroy済み。
      新たにタグ名(TagObjectC)で検索して保存しなおします。
      つまり「4.」で Initiate した ObjectA 内にて検索&結果が返ることを期待しています。
       
    6. ※時間経過で次のフレームに進み、現在 n+1フレームとします。
       
    7. 前フレームでタグ名検索&保存しておいた GameObject型の変数にて ObjectCを参照してみます。
      この時、この変数 はいつのまにか勝手に null になっています。

    ちょっとややこしいですが(;・∀・)

    注意する点の要約は、

    1. 同フレーム中に同名のプレハブをシーン上でDestroy &  Initiate した。
      ※シーン中に当該プレハブの同時存在は1つ。
       
    2. さらに同フレーム中にてタグ名検索をかけた。
      ※新たにInitiateしたプレハブのオブジェクト内で検索HIT&結果取得することを期待。
       
    3. Destroyした方のタグの付いたオブジェクトを返している&同フレーム中は null ではない。
       
    4. 次のフレームでいつのまにか null になっているので「アレっ?」となる。
      ※Destroy処理がタグ名の内部DB?Hash?にも反映された為?


    多分、同フレーム中での実際のオブジェクトのDestroyの処理が行われるタイミング、タグ名とシーン上のオブジェクトの関連性更新などのタイミングの差異問題だと思うので「そういう仕様になっている」ような気がします。

    ※上記処理の確認はUpdate()内で行っています。FixedUpdate内では未確認。こっちだとひょっとするとDestroy後タグ名の参照先更新(?)がされるかも?


    ■回避策


    今回の状況&タイミングにおいては、子オブジェクト名で検索をするように実装すれば回避できています。
    つまりオブジェクト名検索ではさすがに同フレーム中でもInitiateした最新の方をみてくれるようです。

    なので今回のケースではタグ名検索を使わなければハマらなかったわけですが(汗。

    前々からタグ名検索は便利そうな反面「何かありそう」なモヤっとした雰囲気を感じていたのが少し納得できた感じです。