20190811のUnityに関する記事は4件です。

Unityエディターが落ちるとき

経緯

  • 安定していると思っていたプロジェクトで、エディターの更新を含む些細な複数の変更の後でエディターが落ちるようになり、パニクって解決までに無駄に時間を使ってしまいました。
  • エディターが落ちる場合に、最初に確認すべきことを記事に残します。

何処で落ちたのか

  • 落ちた後、再起動前に、Editor.logの終盤にあるスタックトレースをチェックします。
    • ログの所在は、マニュアルに記載があります。 ⇒ ログファイル
    • 見方は普段Consoleに出てくるの同じ、下から上に呼ばれた順で、一番上が最後に呼ばれたものです。
  • 今回はプラグイン(の使い方)が原因でした。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

uGUIのImageにGlowっぽい輪郭線を付けるスクリプトの改良

初めに

UnityのuGUIのImageにOutlineスクリプトを適用すると、画像に輪郭線を付けることが出来るが、Glowの様なぼやけた輪郭線を付けるのは難しい。
対応策としてはこちらのコガネブログさんでも紹介されているが、以下のGlowImageというプロジェクト内にあるC#とShaderコードを使うという方法がある。
http://baba-s.hatenablog.com/entry/2017/12/31/211500
GlowImageのGithub
https://github.com/SylarLi/GlowImage

今回自分の勉強がてらこちらのコードを解読していた時に、「UnityのMask機能に対応していない事」と「シェーダーで最適化出来そうな所がある事」に気づいたので、改良してみた。

元コードのGlowImageで行っている事

箇条書きにすると以下のようになる
・Imageコンポーネントを継承したGlowImageクラスを作成
・GlowImageクラスのパラメーターから、既存Imageにアウトライン用の頂点とメッシュを追加する
・シェーダーでアウトラインを描画しつつガウシアン処理でぼかす
・最後に通常のImageを描画して行い終了

UnityのMask機能に対応させる

UnityのMask機能は、canvasRendererに登録されているマテリアルからマスク処理が適用されているコードを選別して処理を行っている。
既存コードではcanvasRendererに登録する処理が抜けていたため、canvasRendererをオーバーライドして、Image.materialにマテリアルを格納してからGraphicクラスのmaterialForRenderingを呼んで対応した

        public override Material materialForRendering
        {
            get
            {
                if(m_Material == null)
                {
                    material = new Material(Shader.Find("UI/GlowImageImprovement"));
                }
                // ここでパラメーター設定行う
                material.SetFloat("_OutlineSize", m_OutlineSize);
                material.SetColor("_OutlineColor", m_OutlineColor);
                material.SetFloat("_OutlineStrength", m_OutlineStrength);
                string format = "QUALITY_{0}";
                foreach (var item in System.Enum.GetNames(typeof(ImageOutlineQuality)))
                {
                    material.DisableKeyword(string.Format(format, item.ToUpper()));
                }
                material.EnableKeyword(string.Format(format, quality.ToString().ToUpper()));

                return base.materialForRendering;
            }
        }

ガウシアン処理の最適化

既存コードのシェーダーだと通常の平滑化処理のため重み(3x3, 7x7など)の数が増えるほど、ループ数が9, 49などかなり顕著に多くなっている。
画像処理のぼかし処理でよく使われるガウシアンブラーを使用する時、xとyの要素を切り離して処理できる場合ループ数を抑えることが出来る。
今回は以下のサイトを参考にコードを組んだ。

【Unity】【シェーダ】ガウス関数を使ってブラーを掛ける
http://light11.hatenadiary.com/entry/2018/05/20/010105
Unityでガウシアンブラーを実装する
http://edom18.hateblo.jp/entry/2018/12/30/171214

サンプルプロジェクト

コード全文は以下のプロジェクトを参照してください
※Windows10 + Unity2018.4.0f1で動作確認済み。
※ImageのTypeが「Simple」のみ対応
https://github.com/madoramu/GlowImageImprovement

実行結果
ss.png

補足

UnityのOutlineは頂点と頂点カラーを追加しているだけなので元画像も含めて1passで描画しているが、今回のコードはガウシアン処理の関係上2passで描画しなくてはいけないので、処理的には少し重いかも・・・

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Unityでオンラインマルチプレイなゲームを作りたい その2 環境導入

前回、オンラインゲームを楽に開発するためのエンジンを選びました。前回の記事
今回はそのエンジンを用いて開発する準備を行いたいと思います。

前提

Unityをインストールし、触った経験がある

環境

Unity2019.1.0f2
Monobit Unity Networking(記事作成時の最新バージョン2.7.0)

今回の目標

とりあえずオンラインゲームを開発できるように環境を整えます。

導入

Unityの設定

自分が使ってるUnityの設定と、念のため合わせたい人向けにとりあえず記述します。(特に合わせる必要性を感じない人は飛ばしてOKです)
1. Unityを立ち上げ、File → Build Settings → Player Settrings → Other Settingsで以下の画像の通りに設定する。
2019_08_01_2.JPG
2. File → Build Settings → Player Settrings → Resolution and Presentationで以下の画像の通りに設定する。
2019_08_01.JPG

MUNを使用できるように準備

サーバーを準備

モノビットエンジンクラウド公式マニュアル
・こちらのサイトを参考に、アカウント登録を済ませ、サイトにログインします。
aaaaaaaaaaaaaaaaaaaaaaaaa.JPG
・ログインするとこんな感じの物が表示されていると思うので、画像上の赤で囲っている「アプリケーションID」と「MUN リゾルバ一覧取得エンドポイント」をコピーして控えておきます。

これで、クライアントのネットワーク接続先となるサーバーの準備ができました。

サーバーへ接続するクライアントの準備

MUN公式サイト
・MUNの配布しているサイトへアクセスします。
2019_08_01_3.JPG
・↑の画像内で黒丸で囲っているところをクリックし、MUNのアセットをダウンロードします。
・ダウンロードを終えたらUnityを立ち上げ、ダウンロードしたアセットをインポートします。

・インポートを終えたら、Assets/Monobit Unity Networking/Resources/内にある、MonobitServerSettingsをダブルクリックし
ャ.JPG
・↑の画像の通りに設定し、赤で囲っている「Endpoint Address」と「AppID」にサーバーの準備で控えておいた「MUN リゾルバ一覧取得エンドポイント」と「アプリケーションID」を入力します。

これでクライアントの準備ができました。

サンプルで環境導入ができたかを確認

RandomMatchingReconnectサンプル
こちらを使って確認しようと思います。

1.Assets/Monobit Unity Networking/Samples/Scenes/RandomMatchingReconnect/内にある「OfflineSceneReconnect」と「OnlineSceneReconnect」をFile/BUild SettingsのScenes In Buildに追加します。
2.Buildします。
3.Buildで作成されたアプリケーションを2つ立ち上げます。
4.立ち上げたうちの片方で、CreateRoomを押します。
gfdag.JPG
5.もう片方のアプリに、roomName(1)と書いてあるボタンが表示されると思うので、それを押します。
asdfghjkl.JPG
6.Create Roomを行った方のアプリに戻って、GameStartを押します。
zxcvfgt.JPG
7.立ち上がってる二つのアプリのどちらでもいいのでユニティちゃんを動かしてみてください。
qwxwrcx.JPG
もう片方で同じようにユニティちゃんが動いてるのが確認できればOKです。

以上でオンラインマルチプレイを開発する環境が整いました。
次回からは実際にゲームを作っていきたいと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

UnityのAddressableで暗号化したかった…

自己紹介

こんにちはゆずです。@Yuzu_Unity
自分はUnityエンジニア・3DCGデザイナーの学生です。(軸はエンジニア 4年ほど…)

初めに

Addressableが正式リリースした今
暗号化をさせたかった話

Unity2019.2.01f1
Addressable v1.1.7

Addressable Assets Systemと旧AssetBundleとの違い

内部システムでいえば正直何も変わらない
AssetBundleのワークフローを良く改善したのがAddressableであると自分は思います。
(Resourcesの代わりでもある)

Addressableをそのまま使う(少ないデータを暗号化には…)

※すべてのアセットに行うのは面倒なので基本的に暗号化したいファイルのみに行うことになってしまう。(仕方ない…)

・ファイルbyte[]を暗号化しTextAsset化しAdrressableで利用

ファイルごとにbyte[]から変換できる機能が必要
(VRMファイル等には有効かも?、プレファブ単位は厳しい)

・アドレス(プレファブ)1つの単位でのアセットバンドル化をし暗号化をしたものをTextAsset化しAdrressableで利用

アドレス名がアセットバンドルのアセット名になるため実装が楽になりそう(Addressableの恩恵を受けやすい?)
個別にアセットバンドルを作る必要、Load&Unload等の実装 が必要

・複数アドレス(プレファブ)単位でのアセットバンドル化をし暗号化をしたものをTextAsset化しAdrressableで利用

アセットバンドル内の参照を別でもつ必要がある
個別にアセットバンドルを作る必要、Load&Unload等の実装も含む

Addressable(ResourceManager)本体を改造編

全体を暗号化することが可能!

・Addressableからビルドされたアセットバンドルを暗号化

これはResourProviderの編集のみでできるかと思われた…

今回暗号化にはこちらを用います。
【Unity】暗号化したAssetBundleはLoadFromStreamでロードすればメモリに優しい

まずは
Addressable Assets SystemをPackageManagerからインストールします。

そのままでは改造できないため...

Library/PackageCacheフォルダからPackagesフォルダに移動します
この時移動するのは
com.unity.addressables@1.1.7
com.unity.scriptablebuildpipeline@1.5.2
の2つです
フォルダを移動しないと、‎Assembly Definition Filesの循環参照によって自作のResource Providerはつくれなさそうです。
追記 継承でOverwriteすれば問題ないです、すみません。

移動後
Assets\com.unity.addressables@1.1.7\Runtime\ResourceManager\ResourceProviders\AssetBundleProvider.cs
を開き編集します。

 m_RequestOperation = AssetBundle.LoadFromFileAsync(path, m_Options == null ? 0 : m_Options.Crc)

//暗号化したAssetBundleを取得
string password="設定したパスワード";
fileStream = new FileStream(path, FileMode.Open);
var uniqueSalt = Encoding.UTF8.GetBytes(Path.GetFileNameWithoutExtension(path)); // AssetBundle名でsoltを生成

// Streamで暗号化を解除しつつAssetBundleをロードする
var uncryptor = new SeekableAesStream(fileStream, password, uniqueSalt);
m_RequestOperation= AssetBundle.LoadFromStreamAsync(uncryptor,, m_Options == null ? 0 : m_Options.Crc);

に書き換え、ビルドしたアセットを暗号化しておけば
ローカルであれば動くことが確認できました!
ローカルであれば…ローカルであれば…

しかし、
リモートになるとキャッシュシステムがAssetBundleのキャッシュ機能を用いているので
ダウンロード等がそもそも行えません。(暗号化後はbyte[]なので)

キャッシュシステムを自前のシステムに変更することで可能であると思います。

・Addressableからビルドされたアセットバンドルを暗号化しTextAsset化しアセットバンドル化

上記同様アセットバンドルのキャッシュシステムのチェックによって容易にはできず。
キャッシュシステムの変更までは必要にはならないが都度2段階ビルドを行うことにもなるので微妙

まとめ&感想

ResourceProviderのちょっとした編集のみで暗号化はできないみたい

今後の更新もあるので、あまり編集したくない。

公式で暗号化実装してほしい…

暗号化を除けばAddressableかなり強い…

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む