unityでいってみよう!

unityがチョットワカル位の人のブログ

【2021年度版】UnityのTargetFrameRateについて

概要

TargetFrameRateとはアプリケーション全体の1フレーム(1ループ)を実行するのにどの位の時間をかけるかという目標時間です。 1フレームがこの時間より早く処理が終了した場合、目標時間が経過する迄待機してから次のフレームを開始します。 アプリケーションの1フレームの処理時間がこのTargetFrameRateに間に合わない場合、いわゆる処理落ちという状態になります。 TargetFrameRateを設定する意味は、1ループを更新する頻度を一定にするティアリングを防ぐなどの目的がありますが、ここではその説明は割愛します。 UnityではこのTargetFrameRateを設定する為の変数として名前そのもののApplication.targetFrameRateが存在しますが、実際にはApplication.targetFrameRateだけではなく、QualitySettings.VSyncCountの設定も影響を与えています。

QualitySettings.VSyncCountApplication.targetFrameRateの優先順位について

QualitySettings.VSyncCountApplication.targetFrameRateの優先度を比較した場合、QualitySettings.VSyncCount の方が優先度が高くなります。

QualitySettings.VSyncCount に0より大きい値が設定されていた場合

Application.targetFrameRateの値は無視されVSYNCをベースとした計算式が使用されます。

ターゲットフレームレート = Screen.currentResolution.refreshRate ÷ QualitySettings.VSyncCount

ターゲットフレームレートがリフレッシュレートによって変化していることに注意して下さい。 モバイルプラットフォームではリフレッシュレートが60[Hz]であることが一般的ですが、AndroidではSystem設定からリフレッシュレートを切り替えられる端末が数多く存在し、iPadProでも同様に60[Hz]<->120[Hz]を切り替えることが可能です。 フレームレートが上がれば、当然バッテリーの消費が上昇します。上記に記載したようにデフォルト値は60[Hz]になっている筈ですが、メーカーによっては120[Hz]が設定されていることがあり、それが問題になることもあるのでご注意下さい。

QualitySettings.VSyncCount に0以下の値が設定されていた場合

QualitySettings.VSyncCountの値は使用されなくなり、フレーム開始時からApplication.targetFrameRateの時間が経過する迄、フレームの末尾で待機します。 これは、VSYNC待ちを行わなくなるという意味にとれますが、一部のプラットフォームではそうでは無いことに注意して下さい。 例えば、プラットフォームがiOSの場合、ターゲットフレームレートが経過した次のVSYNCで次のフレームへ遷移します。 またこちらのフォーラムの内容をみるとUnity2021以降では、AndroidでもiOSと同じ挙動に合わせる予定があるようです。 Application.targetFrameRateの値が0以下の場合プラットフォームで処理が異なっています。

Application.targetFrameRateが0以下の場合

モバイルとそれ以外で挙動が異なります。

Android,iOSの場合

Android,iOSでは0以下の値を設定した場合、30となります。

ターゲットフレームレート = 30固定

その他のプラットフォーム

ターゲットフレームレート = Application.targetFrameRate

Application.targetFrameRateが1以上の場合

ターゲットフレームレート = Application.targetFrameRate

関連する過去記事

unityletsgo.hatenablog.com

unityletsgo.hatenablog.com

Luna Display for Window ファーストインプレッション

初めに

今回はUnityとは関係ないのですが、1年以上前にKickstarterでプレッジしていた Luna Display for Windowが届いたのでその報告です。

Luna Displayとは

Luna DisplayとはiPadを無線接続でセカンダリモニターと使用することが出来るガジェットです。

shop.astropad.com

Mac版は以前からあったのですが、今回はWindows版ということで申し込んでいました。 Super Early Birdで$49。送料が別途$9だったので、合計$58をクレジットカードで支払っています。

似たようなものにDuet Displayがありますが、こちらは有線(USB,Lightningケーブル)でPCとiPadを接続する場合は無料ですが、無線で接続する場合、年間2,200円~3,200円のサブスクリプションが発生します。

Luna DisplayはUSBアダプタを使用しますが、Duet Displayは必要ありません。 そういった意味ではDuet Displayの方に軍配があがります。

開封

f:id:kimukats:20210612141749j:plain f:id:kimukats:20210612141844j:plain

8.5cm x 8.5cmのとても小さな箱になっています。 猫のイラストも可愛いですね、彼女(?)がLunaでしょうか?

f:id:kimukats:20210612141959j:plain

蓋を開けるとメッセージが。「開始するには、に行く」 はあからさまな機械翻訳だと思われますが、日本語が2番目に来ていることには好感がもてます。この後、アプリを起動するとわかりますが、iOS側のアプリはキチンと日本語化されていました。

f:id:kimukats:20210612142814j:plain

メッセージカードを取り出すと本体が出てきます。 サイズ的にはBluetoothアダプタと同じ位です。

セットアップ

早速、メッセージカードに記載されていたwww,lunadisplay.com/startをブラウザーへ入力するとこちらへ飛ばされました。どうやらOSをチェックしているようで、OSに応じて異なるページへ飛ばされるようです。

f:id:kimukats:20210612143635p:plain

ここで、懸念すべき問題が現れてきました。 iOS側のアプリが正式版では無く、TestFlight経由でのインストールとなっています。 これは、個人的にはかなりの減点対象です。

f:id:kimukats:20210612144601p:plain 気を取り直して、TestFlightをインストール後、TestFlightを経由してLuna Display for Windowsをインストールします。

f:id:kimukats:20210612144642p:plain アプリを起動するとWindows側との接続待ち状態となりますが、何故か「MacでAstropadを起動」と表示されます。 不安になりますが、β版なので細かい部分は置いておいて、Windows側のセットアップを行います。

f:id:kimukats:20210612145135p:plain リンク先をクリックするとインストールが開始されます。信頼されたアプリとありますのでここは信頼するしかないでしょう。

USBアダプターをPCに接続します。 ここで、気を付けなければいけないポイントが一つ。アダプターはどこでも良いという訳ではなく、オルタネートモードに対応しているUSB Type-Cのポートに接続する必要があります。オルタネートモードに対応していないポートにアダプターを刺した場合、セットアップは進みますが、PCの画面が明滅を繰り返すだけで、セットアップが環境することはないのでご注意下さい。

f:id:kimukats:20210612163240p:plain

今回使用したPCはSurface Pro 6 (corei5) + Dock2ですが、リフレッシュレートは22FPSとなっています。 かなり要求スペック高いですね。iPad Pro 10.5の解像度は2224x1668ですが、最新のiPad Pro12.9の解像度は2732x2048であるため、そちらを使用する場合はさらに高いスペックが必要になりそうです。

f:id:kimukats:20210612150435p:plain

iPadとPCがリンクすると上記のダイヤログが表示されます。OKを押してセットアップを進めます。

f:id:kimukats:20210612150710p:plain この状態で何度かPCの画面が明滅を繰り返します。 先程も述べた通り、オルタネートモードに対応していないポートにアダプターをさした場合、ここから先に進みません。

f:id:kimukats:20210612151111p:plain この画面が表示されたら接続環境です。iPad側にもPCの画面が表示されている筈です。

各項目の機能は下記の通りです。

Arrangement * Left:PCの左側にiPadの画面が配置されます。 * Right:PCの右側にiPadの画面が配置されます。 * Custom:設定->システム->ディスプレイが表示されます。

Retina Resolution * Disable:iPad側の解像度が縦横半分になります。 * Enable:iPad側の解像度がオリジナルの解像度になります。

接続先のiPadiPad Pro 10.5 inchですが、Disable/Enableにした場合の解像度は下記の通りです。 解像度が縦横半分になっていることがわかるかと思います。

Disableの場合 f:id:kimukats:20210612151755p:plain

Enableの場合 f:id:kimukats:20210612151946p:plain

iPad Proの画面をiPhone11ProMaxで撮影してみました。 照明の映り込みが入ってしまいましたが、イメージつきますでしょうか? 時計の文字もしっかりと認識できるレベルだと思います。

f:id:kimukats:20210612155619j:plain

またタッチも2点まで認識しており、一般用途としては十分だと思います。

最後に

現在、公式HPから、Pre-Orderという形で$109.99で販売されています。 20,000円もだせば、15inch FullHDのモバイルディスプレイが購入できる時代にこの値段はパフォーマンスが悪いと言わざるえないですが、iPadがバッテリー内蔵の完全ワイヤレスモバイルディスプレイとして使用できるというのは魅力的ではないでしょうか。

Microsoft.Unity.Analyzersを使ってみよう! Unity Editor編

はじめに

前回はVisual Stuio CodeでのMicrosoft.Unity.Analyzerの使い方を説明しましたが、Unity2020.2からUnity Editor上でRoslyn Analyzerが使用出来るようになりました。

docs.unity3d.com

これはIDEに依存せず、UnityEditor上でAnalayzerを利用出来るようなったことを意味します。 ※Unity2020.2以前のUnityをお使いの場合、この方法は使用できませんので、ご注意下さい。

セットアップ

基本的には前回と同じです。

Microsoft.Unity.Analyzers.dllを入手する。

  • GitHubリポジトリからダウンロードしてビルド
  • NuGetからパッケージを抜き出してdllを抜き出す

のいずれかでDLLを入手します。入手方法の詳細に関してはこちらに記載がありますのでそちらをご確認下さい。

DLLをプロジェクトへ配置する

Microsoft.Unity.Analyzers.dllをAseets/NuGetフォルダに配置します。 この時、大量のエラーが発生するのでInspectorからSelect platforms for pluginの設定をすべて解除して下さい。

f:id:kimukats:20210603133447p:plain

ここが前回になかった重要なポイントなのですが、 DLLのAssetLabelにRoslynAnalyzerを追加してください。 AssetLabelにRoslynAnalyzerが追加されたdllはcsprojでAnalyzerとしてマークされます。

f:id:kimukats:20210603172007g:plain

AssetLabelにRoslynAnalyzerを追加する前

... 省略 ...
  <ItemGroup>
    <None Include="Assets\NuGet\Microsoft.Unity.Analyzers.dll" />
  </ItemGroup>
... 省略 ...

AssetLabelにRoslynAnalyzerを追加した後

... 省略 ...
  <ItemGroup>
    <Analyzer Include="Assets\NuGet\Microsoft.Unity.Analyzers.dll" />
  </ItemGroup>
... 省略 ...

結果

consoleにMicrosoft.Unity.Analyzersによる警告が表示されていることが確認出来ます。

f:id:kimukats:20210603172810p:plain

設定自体もVisual Studio Codeを利用する場合と異なり、余計なファイルを作成する必要がない為、楽だと思います。 Unity2020.2以降であれば、Unity Editor上で、それ以前のUnityを使用している場合は、Visual Studio Code上でAnalyzerを使用するのが良いかと思います。 なお、前回のVisual Stuido Code編でdllをAssets/NuGetへ配置した理由はVisual Studio CodeとUnity Editor両方で使用出来るようにする為です。

以上です。

Microsoft.Unity.Analyzersを使ってみよう! Visual Studio Code編

Microsoft.Unity.Analyzersとは

Microsoft.Unity.AnalyzersはMicrosoft社が作成したUnity向けC#コードアナライザーです。 元々はVisual Studio 2019に「Visual Studio Tools for Unity」として組み込まれていましたが2020年2月にオープンソースコード化されました。 コード解析にはRoslynのCompiler APIを使用しており、チェック内容がUnity特有の内容にカスタマイズされている事が特徴です。 また、プロジェクトはGitHub上で公開されているのでだれでも内容を確認でき、自分達のプロジェクトに合わせて内容をカスタマイズすることが出来ます。

何が出来るのか

C#コードに対して静的解析を行い問題箇所を指摘してくれます。
例えば下記の様にGameObjectのtagを==で比較している箇所がある場合、

...省略...
void Update()
{
  if(gameObject.tag == "Enemy"){
      Debug.Log("Enemy");
  }
}
...省略...

「別に問題ないでしょ?」と思われる方も居るかと思いますが、tagへのアクセスは非常に重い処理となっています。 その為、比較を行う場合==ではなく、GameObject.CompareTag() APIを使用することでパフォーマンスの改善が見込めます。 そこでMicrosoft.Unity.Analyzersは次のような警告をしてくれます。

Comparing tags using == is inefficient. [Assembly-CSharp] csharp(UNT0002) ...

「tagの比較を‘==‘で行うと処理が遅いです」と警告してくれるので、ユーザーはそれを見て該当箇所を修正するというフローになる訳です。 これはとても良いのではないでしょうか。開発元がMicrosoftという所にとても安心感があります。

その他、どのような指摘をしてくれるかはこちらに一覧がありますのでご確認下さい。

設定編

それでは使う為の準備を進めて行きましょう。

インストール

UnityEditorとVisual Studio Codeは既にインストール済みの前提ですが、まだの人はインストールをお願いします。

.Net Core SDK.NET Framework 4.6 Targeting Packをインストールします。 インストールによって環境変数のPATHに項目が追加されますので、インストール終了後、再起動を行って下さい。

Visual Stdio Codeを起動し、拡張機能C# extension をインストールします。 同名の拡張機能が複数ありますので間違いないように注意して下さい。

このマークの拡張機能です。f:id:kimukats:20210603160941p:plain

Unity Editorが使用するExternal Script EditorをVisual Studio Codeへ変更する

Unity Editorが使用するExternal Script EditorをVisual Studio Codeへ変更します。 設定はEditor->Preferences->External Tools->External Script Editorから行います。

f:id:kimukats:20210603123208p:plain

Microsoft.Unity.Analyzers.dllを入手する

入手方法にはGitHubリポジトリから入手してビルドする方法とパッケージを入手その中に含まれるDLLを使用する方法の2種類があります。

GitHubから入手する場合

ビルドを行う為にはVisual Studio2019 16.4以降が必要で、個別機能から.NET Compiler Platform SDKをインストールする必要があります。

GitHubリポジトリからプロジェクトを取得します。 gitの使い方が良くわからない場合、Code->Download ZIPでプロジェクトを取得するのが良いでしょう。 f:id:kimukats:20210603130241g:plain

ZIPファイル展開後、コマンドラインを開いてプロジェクトのRootで下記のコマンドを実行します。

dotnet build .\src\Microsoft.Unity.Analyzers.sln

Microsoft.Unity.Analyzers.dllが下記のフォルダに生成されていれば成功です。 .\src\Microsoft.Unity.Analyzers\bin\Debug\netstandard2.0

パッケージから入手する場合

こちらからパッケージをインストールします。 PM経由でインストールするのが正しいのですが、Unityが.csprojを編集するのと相性が悪いようで手動でインストールした方が良さそうです。 画面右側にあるDownload packageからダウンロードを行い、dllファイルを抜き出します。

f:id:kimukats:20210603131109p:plain

ダウンロードしたパッケージはmicrosoft.unity.analyzers.X.YY.Z.nupkg (X.YY.Zはバージョン番号)のように拡張子がnupkgになっていますが、zipに変更して展開します。展開にはOS標準の展開ツールより7zip等を使用した方が良さそうです。

展開した.\analyzers\dotnet\cs以下のディレクトリにMicrosoft.Unity.Analyzers.dllが含まれていますのでこちらを使用します。

Microsoft.Unity.Analyzers.dllをプロジェクトへ配置する

解析を行う為にはMicrosoft.Unity.Analyzers.dllをUnity Projectへ配置します。 公式サイトではProjectのRootに適当なディレクトリ(NuGet)を作成してそこに配置するように記載されていますが、今回は.\Assets\NuGetMicrosoft.Unity.Analyzers.dllを配置します。 ※この理由は続編のMicrosoft.Unity.Analyzersを使ってみよう! UnityEditor編でお話しします。

するとUnity Editor側で大量のエラーが発生します。 Unity EditorのProject ViewからMicrosoft.Unity.Analyzers.dllを選択しInspectorからSelect platform for pluginでチェックされている項目をすべて外します。

f:id:kimukats:20210603133447p:plain

これで、すべてのエラーが消えた筈です。

omnisharp.json

ProjectのRoot(すなわちslnやcsprojが置かれている)ディレクトリにomnisharp.jsonという名前のファイルを作成し下記のように記載します。

{
  "RoslynExtensionsOptions": {
    "EnableAnalyzersSupport": true,
    "LocationPaths": [
      "./Assets/NuGet/Microsoft.Unity.Analyzers.1.10.2"
    ]
  }
}

LocationPathsにはMicrosoft.Unity.Analyzers.dllを配置したパス+パッケージバージョンとなります。 その為、DLLを配置した場所や、ダウンロードしたパッケージのバージョンによって内容が異なりますのでご注意下さい。 上記の例はパッケージバージョン1.10.2のMicrosoft.Unity.Analyzers.dll./Assets/NuGetに配置した場合の例となります。

.cspoj

.cspojファイルに下記の内容が含まれていることを確認してください。

  <ItemGroup>
    <Analyzer Include="Assets/NuGet/Microsoft.Unity.Analyzers.dll" />
  </ItemGroup>

これはUnityのパッケージであるVisual Studio Code Editorが自動的に設定してくれる筈なのですが、なければ手動で追加する必要があります。

必要な設定は以上です。

確認

試しに、次のようなスクリプトを作成してProjectへ配置してみましょう。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TEST : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if(gameObject.tag == "Enemy"){
            Debug.Log("Enemy");
        }
    }
}

C#コンパイル後、コンソールに下記のように表示されれば成功です。 表示されない場合は、設定を見直して見てください。

f:id:kimukats:20210603135650p:plain

表示された内容を確認するとIDE0051とUNT0001は同じ問題を指摘しています。 MicrosftUnity.Analyzersが警告しているメッセージはUNT0001ですので、別のAnalyzersが同じ内容の警告をIDE0051として重複して警告していることになります。

プライベート メンバー 'TEST.Start' は使用されていません [Assembly-CSharp] csharp(IDE0051)
The Unity message 'Start' is empty. [Assembly-CSharp] csharp(UNT0001)

このままでも問題ありませんが、重複の警告を非表示にする場合、Rootフォルダに .editorconfigという名前のファイルを次の内容で作成します。

root=true

[*.cs]
dotnet_diagnostic.IDE0051.severity = none

以上です。

【2021年度版】Android端末上で実行するアプリケーションをスクリプトデッバクする方法

概要

スクリプトデバックとはVisual Studion等のデバッカーを用いて、ユーザーが作成したC#のコードにbreakポイントを貼りステップ実行を行うデバック方法です。

Unity Editorで実行する場合、スクリプトデバックは比較的容易なのですが、Android端末でアプリケーションを実行する場合は、なぜか上手く行かないという話しを度々聞くのでここで可能な限り完結に説明します。

 

実行環境

- Windows10

- Unity2019.4.20f1

- Pixel4XL(Android12Preview)

 

ビルド時の設定

以下の機能をにチェックを入れてください。

  • Development Build
  • Script Debugging
  • Wait For Managed Debugger

 

Development BuildScript Debuggingは必須です。

Wait For Managed Debuggerを有効にすることで、アプリケーション起動時にAndroid端末とデバッカーの接続が行うタイミングを用意してくれます。

これによって、アプリケーション起動時からのデッバクが可能となります。

 

f:id:kimukats:20210531135937p:plain

 

 

また、Run Deviceのプルダウンリストの表記がDefault deviceとなっていますが、デバックを行いたい端末がリストの含まれていることを一度確認にして下さい。

表示されていない場合、Android端末側の設定に問題がある可能性があります。

設定->システム->開発者向けオプション->USBデバック が有効になっているか確認してください。

 

問題がなければ、Build And Runを押してアプリケーションをビルドしてAndroid端末へ転送します。

アプリケーションの起動

Android端末でアプリケーションが起動すると直ぐ(スプラッシュスクリーンが表示される前)に以下の画像のダイヤログが表示されます。

これが先程説明したAndroid端末とデバッカーを接続するタイミングです。

f:id:kimukats:20210531140446p:plain

 

Visual Studio(デバッカー)の設定

Unity EditorのProject Viewからデバックを行いたいC#のファイルをダブルクリックしてVisual Studioを起動します。

 

Visual Studio->デバック->Unity デバッガーのアタッチを選択します。

f:id:kimukats:20210531141522p:plain

 

 

Unity インスタンスの選択Windowが表示されるので、AndroidPlayerもしくはAndroid Player(USB)を選択してOKを押します。

f:id:kimukats:20210531141628p:plain

 
C#スクリプトの任意の行の左端をダブルクリックしてブレークポイントを設定します。
 
端末側に戻って、OKボタンを押します。
 
 
以上です。

LightSettings APIについて

f:id:kimukats:20210511122430p:plain

これまでLighting Windowの内容をスクリプトから参照するAPIが無い為、リフレクションとSerializeObjectを駆使して値を拾っていましたが、Unity2020.1でLightingSettingというクラスが追加されました。

こんな感じで現在のSceneのLighting設定の内容にアクセスすることが出来ます。

var lightingSettings =  Lightmapping.lightingSettings;

これまでは、LightmapEditorSettings内のinternalAPIから取得する必要があったのですが、Lightmappingクラスに追加された感じです。 もともとLightmappingの管理下にlightingDataAssetがあったので自然といえば自然ですが。

Unity2019.4.24f1リリースノート解説

日本語訳はUnity側で公開されるので、気になったポイントをピックアップして解説していきます。

既知の不具合

Windows: [Windows 7] "WindowsVideoMedia error 0xc00d36b4" error is thrown when loading a video with the VideoPlayer (1306350)

Windows7上でVideoPlayerで動画をロードすると"WindowsVideoMedia error 0xc00d36b4" が発生する。

Windows7って・・・。

WebGL: [iOS] video is not playing on iOS (1288692)

iOS上でビデオを再生出来ない。

初見でみた時、もの凄いクリティカルなのではと思いましたが、よく見るとプラットフォームがWebGL。 つまり、WebGL向けにビルドしたアプリケーションをiOSのブラウザ(Safari)で実行した場合、動画が再生出来ないということになります。

改善

Editor: Improved UTF documentation (DSTR-120).

DSTR-120とは?」と思いましたがこちらは新しい形式のIssue IDのようです。 DSTRから始まる場合、Unity Test FrameworkのIssueとなります。 UnityTestFrameWork側のリリースノートを確認するとDSTR-120の内容が確認できました。 DSTR-120にはいくつかのサブIssueが含まれています。

  • Improving UTF documentation(DSTR-120) Updated "Actions outside of tests" section of user manual. Added flow charts to clarify execution order for SetUp/TearDown,
    • TestActions, and complete flow (DSTR-121).
    • Fixed accepted values for scriptingBackend argument to be string literals instead of int values (DSTR-122).
    • Fixed possible values of ResultState to be Passed, Failed, Skipped, Inconclusive, plus labels instead of Success and Failure (DSTR-125).
    • Added NUNit version information (DSTR-130).
    • Added namespace information for LogAsset in user manual (DSTR-124).
    • Added instructions for creating additional sets of tests (DSTR-129).
    • Added information on testResults XML output format and exit codes (DSTR-131).
    • Updated description of testPlatform command line argument to clarify accepted values and their meaning (DSTR-123).

API Changes

iOS: Added: Added function PBXProject.GetEntitlementFilePathForTarget().

Unity as Libraryへの対応の為、PBXProjectAPIが色々削除され、Unity2018からの移行で色々ざわざわしていましたが、これで少しはましになるかと。

修正

Graphics: Fixed an editor crash by always allowing the use of Metal API on Apple M1 macs, even if Metal Editor Support is disabled in the Player Settings. (1298617)

Graphics: Fixed an editor crash by preventing the use of OpenGL API on Apple M1 macs, where it is not supported. (1306688)

M1 Mac周りでいくつかの修正が来てます。 「M1でUnity Editor動かん」という人はUnity2019.4.24以降にバージョンアップしてみてください。

Graphics: Fixed unintentional crossfades for LODs when the animated cross-fading flag is enabled. (1305495)

LOD GroupsのAnimated Cross-Fadingフラグがenableになっている時に、LODの意図しないCrossフェードが起こっていたと。

IL2CPP: Fixed an exception when converting a method with a parameter that is an in generic parameter with a default value. (1313460)

今回のリリースノートで一番難解な部分ですが、 こんな感じでinプロパティを持つジェネリックな引数がdefault値を持つ場合、IL2CPPが上手く変換出来ていなかったようです。

public static void Dummy<T>(in T value = default(T)) { }

iOS: Fixed a UnityWebRequest issue that caused freezing on background/resume when the device is offline. (1315244)

アプリケーションを実行中に、アプリケーションをバックグラウンドにして設定->機内モード->ONにしてからアプリケーションに戻ってくると、フリーズすることがあったということですね。

以上