20210115のUnityに関する記事は5件です。

Unityプロジェクトをアップグレードした時に起きた問題

はじめに

今回はUnity2017のプロジェクトをUnity2020にアップグレードした時に起きたトラブルを
シンプルなプロジェクトを作り検証した結果をまとめてみました。
ただ、結局のところ何が起こっているのかまでは調べてはいないのであしからず…

試した環境

Windows10
Unity2017.4.10f1(元のプロジェクト)
PlatformはiOS
※ 新規プロジェクト作って、Assets直下に以下のスクリプトを仕込んでいます。

Test.cs
public class Test
{
    public System.Reflection.Emit.ILGenerator test;
}

Unity2019.2.21f1(段階的にアップグレードするのに使用)
Unity2020.2.1f1(アップグレードしたいバージョン)
※ Unity2020を起動する時、エラーがあるとEnter Safe Mode?と出るので Ignoreで対処。

アップグレードした流れ

パターン1(成功例)

① Unity2017.4.10f1のプロジェクトをUnity2019.2.21f1で起動。
② 起動すると以下のようなエラーが出る。

Assets\Test.cs(3,32): error CS0234: The type or namespace name 'ILGenerator' does not exist in the namespace 'System.Reflection.Emit' (are you missing an assembly reference?)

③ Api Compatibility Level* を .NET 4.x に変更することでエラーは解消。Unityを終了する。
④ Unity2019.2.21f1になったプロジェクトをUnity2020.2.1f1で起動。
⑤ 起動すると以下のようなエラーが出る。
※ この時、Api Compatibility Level* は .NET Standard2.0 に戻っている。

Deterministic compilation failed. You can disable Deterministic builds in Player Settings
Library\PackageCache\com.unity.multiplayer-hlapi@1.0.2\Editor\Tools\Weaver\AssemblyInfo.cs(22,28): error CS8357: The specified version string contains wildcards, which are not compatible with determinism. Either remove wildcards from the version string, or disable determinism for this compilation

⑥ これを修正するためにPackageManagerのIn ProjectでMultiplayerHLAPI 1.0.2 を 1.0.8に更新。
 あるいはMultiplayerHLAPIがいらなければ削除する。エラー解消。
※ MultiplayerHLAPIが存在する場合、1.0.8に更新する前に Api Compatibility Level* を
  .NET 4.xに変更すると以下のエラーが出るが、プロジェクトを起動し直すと消える。

Microsoft (R) Visual C# Compiler version 3.5.0-dev-20359-01 (8da8ba0c)
Copyright (C) Microsoft Corporation. All rights reserved.

パターン2(失敗例)

※ パターン1の流れでUnity2019.2.21f1でエラーを無視した時の流れです。
① Unity2017.4.10f1のプロジェクトをUnity2019.2.21f1で起動。
② 起動すると以下のようなエラーが出る。

Assets\Test.cs(3,32): error CS0234: The type or namespace name 'ILGenerator' does not exist in the namespace 'System.Reflection.Emit' (are you missing an assembly reference?)

③ エラーはひとまず無視してプロジェクトを終了。
④ Unity2019.2.21f1になったプロジェクトをUnity2020.2.1f1で起動。
⑤ 起動すると以下のようなエラーが出る。

Deterministic compilation failed. You can disable Deterministic builds in Player Settings
Library\PackageCache\com.unity.multiplayer-hlapi@1.0.2\Editor\Tools\Weaver\AssemblyInfo.cs(22,28): error CS8357: The specified version string contains wildcards, which are not compatible with determinism. Either remove wildcards from the version string, or disable determinism for this compilation

⑥ これを修正するためにPackageManagerのIn ProjectでMultiplayerHLAPI 1.0.2 を 1.0.8に更新。
 あるいはMultiplayerHLAPIがいらなければ削除する。
⑦ 以下のエラーが出る。

Assets\Test.cs(3,32): error CS0234: The type or namespace name 'ILGenerator' does not exist in the namespace 'System.Reflection.Emit' (are you missing an assembly reference?)

⑧ Api Compatibility Level* を .NET 4.x に変更しても解決しない。
⑨ 解決方法不明。

パターン3(失敗例)

① Unity2017.4.10f1のプロジェクトをUnity2020.2.1f1で起動。
② 起動すると以下のようなエラーが出る。

Assets\Test.cs(3,32): error CS0234: The type or namespace name 'ILGenerator' does not exist in the namespace 'System.Reflection.Emit' (are you missing an assembly reference?)

③ Api Compatibility Level* を .NET 4.x に変更しても解決しない。
④ 解決方法不明。

パターン1とパターン2の比較

プロジェクトで最終的に何が違っているのかを調べ、Libraryフォルダ等を削除し、全てのファイルを比較。
するとProjectSettingsフォルダのProjectSettings.assetに以下の違いがありました。
2021-01-15_19h04_08.png
左がエラーが出ないプロジェクトで、右がエラーの出るプロジェクトです。
Unityエディター内ではこの項目がどこで変更出来るかは分からなかったのですが、直接書き換えてから
エラーが出ていたプロジェクトを開くとエラーが出なくなりました。
※ パターン2の検証直後だと、apiCompatibilityLevelPerPlatform: {} になってたので何かを触ると iOS: 6
  は付いたみたいです。.NET 4.x 辺りを触って戻してとかした時かな…?

結論

とりあえず、Unity2017.4.10f1でSystem.Reflection.Emitを使用しているプロジェクトをUnity2020.2.1f1に
アップグレードする場合、Unity2019.2.21f1で起動して .NET 4.xに変更、Unity2020.1.1f1で起動すれば解決する。
※ 細かいバージョン誤差での挙動は不明、Unity2019で自動的に入るパッケージは使ってなければ削除でもOK。

まあ、Unityバージョンの開きが大きいので何かしらのトラブルは起こるとは思いますが
同様の現象が起きた人の参考になればと思います。

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

XcodeでのIL2CPPインクリメンタルコンパイル

今回の主な話題:XcodeでのIL2CPPインクリメンタルコンパイル、OnPopulateMeshでUIの頂点データを変更します、AnimationにTextMesh.color変数を追加できません。


コンパイル

Q1: 最近、加速パッケージングの問題を勉強しています。毎回IL2CPPがコードを生成した後、Xcodeが完全コンパイル(Clean + Archiveではなく直接Build)であります。「こちら」を参照して比較しました。C#コードが変更されない場合、生成されたCPP コードの内容は確かに変更されません。ただし、再生成するとファイルの変更時間や他の属性が変更されるようです。Xcodeは依然をして全てをコンパイルします。この分野での経験はありますか?

「出力されたXcodeがsvnを使用してXcodeパッケージプロジェクトに同期されます」—Freshair。
dnspyで調べました、il2cpp.exeで直接に変更するのは費用がかかり、維持しにくいです。BeyondCompareで比較しました、Preprocessor.hとNative二つのフォルダだけの変更時間が変更されていることがわかりました。


UI

Q2: OnPopulateMeshでUIの頂点データを変更し、Tangentを介してUGUIのShaderにデータを渡します。
C#コードは次とおります。

C#
public class MyRawImage : RawImage 
{
    protected override void OnPopulateMesh(VertexHelper vh)
    {
        base.OnPopulateMesh(vh);

        UIVertex vert = new UIVertex();
        int vertCount = vh.currentVertCount;
        for(int i = 0; i <vertCount; ++i)
        {
            vh.PopulateUIVertex(ref vert, i);
            vert.tangent = new Vector4(1,0,0,1); // tangentを介してデータを渡す -----------------
            vert.color = new Color(1,0,0,1); // colorを介してデータを渡す -----------------
            vh.SetUIVertex(vert, i);
        }
    }
}

Shaderコード:

Shader
struct appdata_t
{
    float4 vertex   : POSITION;
    float4 color    : COLOR; // color データ -----------------
    float2 texcoord : TEXCOORD0;
    float4 tangent : TANGENT; // tangent データ -----------------
    UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f
{
    float4 vertex   : SV_POSITION;
    fixed4 color    : COLOR; // color データ -----------------
    float2 texcoord  : TEXCOORD0;
    float4 worldPosition : TEXCOORD1;
    float4 tangent : TEXCOORD2; // tangent データ -----------------
    UNITY_VERTEX_OUTPUT_STEREO
};

v2f vert(appdata_t v)
{
    v2f OUT;
    UNITY_SETUP_INSTANCE_ID(v);
    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
    OUT.worldPosition = v.vertex;
    OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);

    OUT.texcoord = v.texcoord;
    OUT.tangent = v.tangent; // tangent データ -----------------

    OUT.color = v.color; // color データ -----------------
    return OUT;
}

fixed4 frag(v2f IN) : SV_Target
{
    return IN.color; // color データ -----------------
    return IN.tangent; // tangent データ -----------------
}

Colorデータは正しく取得できますが、Tangentは常に0です。UGUIがTangentデータをShaderに渡さなかったようです。 原因は何ですか、またはコードに何か問題ありませんか?

下図をみろう。
1.png


クラッシュ

Q3: VideoPlayerを使用すると、Android端末でStopをコールするとアプリがクラッシュします。Unityバージョンは5.6.1です。みなさんはこのような状態に遭いましたか?どうすればいいでしょうか?
2.png

下位バージョンのUnityのVideoPlayerは不安定で、クラッシュしやすいです。この点について、Unity公式テクニカルサポートチームに確認済みです。Unityバージョンを、できればUnity 2017にアップグレードすることをお勧めします。都合が悪い場合は、Unity5.6シリーズの上位バージョンにアップグレードできます。


アニメーション

Q4: AnimationにTextMesh.color変数を追加できないようにしたいですが、どうすれば実現できますか?アニメーションにTextMashのaの値を変更する必要がありますが、matでの変更はバッチ処理できません。
3.png

確かにTextMeshのcolorは、Animationで直接変更できませんが、colorはスクリプトで変更できる。ですから、Textコンポーネントを追加する必要はありません。スクリプトで一つのColor変数をpublicし、AnimationでこのColor変数を変更させ、スクリプトでTextMeshに割り当てます。但し、実にはAnimationを使わず、スクリプトを直接使用してTextMesh.colorを制御することもできます。

こちらを参照できます:https://stackoverflow.com/questions/37426522/unity-how-to-animate-a-flashing-textmesh-so-varying-the-alpha-when-the-player


スクリプト

Q5: Get CompaonentのAPIでGameObjectのコンポーネントを取得する時に、時々に取得する手順は違う場合があります。この順序は何によって決まりますか?

前にこの問題に気づいていませんでしたが、面白いと感じで、GetComponentsとorderの二つのキーワードを使用して検索を行いました。
https://answers.unity.com/questions/1293957/reliable-order-of-components-using-getcomponents.html
https://answers.unity.com/questions/556932/does-getcomponents-return-the-components-in-the-or.html
https://stackoverflow.com/questions/42375242/unity-getcomponentsinchildrent-return-order
大意は、順序はInspectorに見た順序と同じですが、この順序はundocでありため、Unityがいつ実現を変更して順序を変更させても私たちはわかりません。

問題主はどのような状況で取得した順序が違うのが知りません、この不一致は、全く同じ状況で複数回取得した結果ですか?とりあえず、順序がゲームのロジックに影響できないようにする方がいいと思います。何となく、現在のテストが安定していても、将来のバージョンにはわかりません。

GetComponentsによって取得される順序は、Inspector内のComponentの順序です。Editorこの順序を変更すると、それに応じてこの関数APIで得られるものも変わります。


UWA Technologyは、モバイル/VRなど様々なゲーム開発者向け、パフォーマンス分析最適化ソリューション及びコンサルティングサービスを提供している会社でございます。

UWA公式サイト:https://jp.uwa4d.com
UWA公式ブログ:https://blog.jp.uwa4d.com

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

フレーム同期フレームワークでの浮動小数点精度の計算

今回の主な話題:フレーム同期フレームワークでのゲームロジックの浮動小数点精度問題、同じマテリアルを引用しますが、DrawCallバッチの結果は一貫ではありません、Pragma Target 3.0、GC標準。


フレーム同期

Q1: 私たちのゲームはフレーム同期フレームワークを使用しており、ロジックを計算するときに、移動やジャンプなどの浮動小数点計算が必然的に発生します。異なるプラットフォームおよび異なるマシンで一貫した結果を保証するために、浮動小数点数の結果が一貫性のない問題を解決または回避するための良い解決策はありますか?

一般的に、浮動小数点計算に関する位置同期は、高精度を保持する必要はなく、小数点以下2〜4桁を保持するだけで十分です。ですから、計算前に浮動小数点数に1000を掛けて、整数を取得して計算を実行することで、マルチエンド精度の非同期問題を効果的に解決できます。

私たちが研究しているフレーム同期の経験によると、「伝説対決」のようなレベルのゲームではない場合、フレーム同期の浮動小数点精度の影響はシステムのボトルネックではありません。戦闘時間が長くない場合、バレする可能性は非常に低く、全体を整数に変更する作業量は非常に大きくなります。会社は大きくない場合、生き残ることができるかどうかを評価する必要があります。ロジックと表現の分離が最大の問題です、つまり、多数のUnityコンポーネントを使用できません。再実現されたものの多くは最初から作成する必要があり、もちろんすべて整数を使用したいなら最初から作成する必要もあります。小さなゲーム会社に対して、生存と完璧の間に慎重に判断する必要があります。

フレーム同期には固定小数点数の方が信頼でき、浮動小数点数によって引き起こされるエラーは許容できないレベルまで蓄積される可能性があります。他の質問にも答えします。
1)ネットワーク送信に、信頼性の高いUDP(TCP)送信を使用します。
2)さらに、他の人がロジックと表現の分離を言及しましたが、これはフレーム同期に対して必要なものです。Unityの多数のコンポーネントを使用できないということの主な原因は、フレーム同期ロジックをローカル時計の時間に従って処理するのではなく、サーバー時計の時間に従って厳密に処理する必要があるためです。使用できないと言っても、実際には主にロジックレイヤーに対することです。プレゼンテーションレイヤーは、Unityコンポーネントが絶対に利用できないことを意味するわけではありません。プレゼンテーションレイヤーのUnityコンポーネントは実際には不可欠です。


レンダリング

Q2: ShaderのPassに”LightMode” = “ShadowCaster”を追加すると、このオブジェクトに投影と深度レンダリング機能を追加することを意味しますが、”LightMode” = “ShadowCaster”を削除し、Fallbackもoff状態に置いた場合、このオブジェクトをベイクすると(ライトはMixedではなくBakeであり)、シャドウが生成できます。これはなぜですか?

ShadowCasterは動的シャドウ(Cascaded ShadowMap)のみに使用されますが、ベイクはこのLightModeを使用しません。

ベイクはMetaというLightModeを使用します、こちらを参照できます。

ベイクシャドウは完全にEnlightenによって計算されるため、一般的なレイトレースベイクの実現から見ると、投影するかどうかはオブジェクトのmeshと透明度に決定します。意外がなければ、metaによって生成された透明度情報がEnlightenで使用され、ShadowCasterを使用してEnlightenに追加情報を生成して渡す必要はありません。

シャドウをシールドするだけの場合は、スクリプトを使用してオブジェクトにハングアップし、スクリプトを使用してベイクすることを考慮できます。このスクリプトを使用しているオブジェクトがシャドウをオフにすることがわかった場合は、ベイク後に復元すればいいです。


レンダリング

Q3:あるShaderに以下のコマンドを追加しました。

#pragma target 3.0

では、このShaderがこの特性をサポートしていない場合、自動的にPragma Target 2.0にFallbackしますか?

https://docs.unity3d.com/Manual/SL-ShaderCompileTargets.html

When writing either Surface Shaders or regular Shader Programs, the HLSL source can be compiled into different “shader models”. To allow the use of more modern GPI functionality, you must use higher shader compilation targets.

Note: Using higher shader compilation targets may prevent the shader from working on older GPUs or platforms.

問題主が自分で理解してください。私の理解と経験では、コマンドまたは特性がサポートされていない場合、FallBackせず、直接ピンク色になります。

これはプログラムの「Graphics APIの選択問題」(中国語注意)であります。

実際に、Shader Target自体はUnityによって抽象化された概念(またはDXのShader Modelを参照して抽象化された概念)であり、実に対応しているものはGraphics APIです。同じに、これもAPIの変更だけでなく、ハードウェア機能の向上も表しています。

Shader Target3.0のVertexTexture Samplingを使用したい場合は、UnityがShader Target 2.0マシンで自動的にPixelTextureSamplingに変換することは思わないでください。

もちろん、FallBackを自分で指定するのが最善の方法です。


GC

Q4: 現在、私たちが書いたプログラムはどのバージョンのGCを実行していますか?私はいつもC#のGC原理を、現在作成しているプログラムのGC標準と認識していましたが、今日、Unityには独自のGCがあるという公式ドキュメントを突然見たので、迷惑しました。下記の質問を教えてください。

1)UnityのGCはMonoのGCですか?
2)Monoは.NET標準を実現していませんか?
3)では、MonoのGCもC#のGCの原理であるべきではありませんか?

CLR GCには3つの世代があり、MonoまたはIL2CPPGCは世代を分けません。

Monoソースコード:https://github.com/mono/mono
現在、Monoが使用しているGCはBenchmark Suite:https://github.com/xamarin/benchmarker

もちろん、独自のMonoライブラリをコンパイルして、マルチジェネレーションマルチスレッドGC、SGenを使用することもできます。

1)Monoは、初期にはBoehm-Demers-Wiser GCライブラリを使用していましたが、後で世代分け機能とマルチスレッド機能を備えたSGenライブラリに更新しました。
2)強調すべきのは、歴史的な理由から、Unityはバージョンの古いMonoを使用しています。そして、それに基づいて多くの変更を加え、いくつかの新しい周辺機能を統合しているため、最新バージョンのMonoをフォローアップできなくなりました。そのため、GCは依然として最古のBoehm-Demers-Wiserライブラリです。 したがって、最新のMonoを自分で統合しようとする場合、その結果は理想的ではない可能性があります。
3)次に、IL2CPPを忘れないでください。これは完全に独立したRuntimeです。IL2CPPにコンパイルすると、Monoとは関係ありません。この度、独自のGC実現がありましたが、残念ながら、依然として古いBoehm-Demers-Wiser GCを使用しています。
4)Monoは、文法、コンパイル、Runtime、ライブラリなどの方で.NET標準を実行していますが、GCの最下層実現では、少なくとも初期に最下層をどのように実現するのは確定していませんでした。たとえあったとしても、MonoはMicrosoftがコードを開示していないため、当時に、自分で一セットのソリューションを探さなければならなかったので、.NETとは関係のない今のGCの実現があります。


レンダリング

Q5: 教えてください。ゲームシーンのコンポーネントが全部ロードされた後、静的バッチ処理が必要なコンポーネントに対して、統一にStaticBatchingUtility.Combineを一回実行します。ゲーム内のバッチ処理効果と直接にシーン内のバッチ処理DrawCallとは大きく異なることがわかりました。
1.png
これらのModelはすべて成功にバッチ処理されており、結果は全部以下の図の示し通りです。
2.png
同じマテリアルを引用し、マテリアル変数も同じでおり、インスタンス化されたマテリアルIDも同じです。2つのDrawCallモデルのMeshもバッチ処理されていますが、提出を二回行い、DrawCallは一つではなく二つあります。
問題はどこにあるのかよくわかりません。シーンで静的バッチ処理を実行した後、シーンDrawCallは約40になり、ゲーム内にシーンをロードした後に静的バッチ処理を一回実行すると、DrawCallは約110になります。

調査の結果、この問題は静的バッチ処理できないことで引き起こされます。「Objects are affected by different forward lights」と表示されます。さらにテストしたところ、ゲーム内のシーンパーツがポイント光源で照らされ、ForwardAddがバッチ処理を中断することは異なる点であります。ポイント光源がシールドされている場合、バッチ処理は正常です。


UWA Technologyは、モバイル/VRなど様々なゲーム開発者向け、パフォーマンス分析最適化ソリューション及びコンサルティングサービスを提供している会社でございます。

UWA公式サイト:https://jp.uwa4d.com
UWA公式ブログ:https://blog.jp.uwa4d.com

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

悩みがちなベクトルの回転での向きの調整、local/worldの位置の変更

モバイルアプリを開発していると、画面前方にある何かに向きを合わせて表示したくなることがあると思います。
例えば地図を表示したときは、自分の向きがわかるように表示したいですよね。
ただ携帯(Unity上のカメラ)、表示するもの、向きを合わせたいものなど複数出てきますし、
位置とか向きとか、local、world、ベクトル、内積、クォータニオンとかを考え出すと頭が混乱してきませんか?

Unity には三次元空間上でベクトルや角度を計算するためのメソッドが用意されています。
数学的には難しいと感じるものでも、用意されているメソッドを利用することで数行で実装することができます。
そのサンプルです。

TL;DR

以下二つのメソッドを利用しています。

  • 三次元ベクトルをある平面上(二次元)に投影するメソッド、ProjectOnPlane
  • 2つのベクトルから角度を求めるメソッド、SignedAngle

サンプル

想定

矢印が常に携帯の前に表示されていて、かつ北向きを表示してくれるようにします。

  • あるタイミング(今回はRキーを押したとき)に
  • 携帯の画面前方(今回は3m前方)に
  • 進行方向(今回は仮想の北向き)を教えてくれる

結果

いきなり出てきて終わりという感じです。

output.gif

全コード

using UnityEngine;
using Random = UnityEngine.Random;

public class Sample : MonoBehaviour
{
    [SerializeField] private Transform north;
    [SerializeField] private Transform came;
    [SerializeField] private GameObject arrowPrefab;

    void Start()
    {
        north.position = new Vector3(RandPos(), 1, RandPos());
        north.rotation = Quaternion.Euler(0, RandAngle(), 0);
        came.position = new Vector3(RandPos(), 1, RandPos());
        came.rotation = Quaternion.Euler(RandAngle(), RandAngle(), RandAngle());
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.R))
        {
            // カメラから見て 5m 先にポジションする
            var pos = came.position + came.forward * 5;
            // インスタンス生成、角度はなし
            var arrow = Instantiate(arrowPrefab, pos, Quaternion.identity);

            // xz平面上における camera の local の前向き
            var came2d = Vector3.ProjectOnPlane(came.forward, Vector3.up).normalized;
            // コンパス分を戻す
            var direction = Quaternion.Euler(new Vector3(0, -InputCompassTrueHeading(), 0)) * came2d;
            // 向き先を local から world にするために自身の position を追加する
            arrow.transform.LookAt(arrow.transform.position + direction);
        }
    }

    /// <summary>
    /// Input.compass.trueHeading の代わり
    /// </summary>
    private float InputCompassTrueHeading()
    {
        var north2d = Vector3.ProjectOnPlane(north.forward, Vector3.up);
        var came2d = Vector3.ProjectOnPlane(came.forward, Vector3.up);
        return Vector3.SignedAngle(north2d, came2d, Vector3.up);
    }

    private int RandAngle()
    {
        return Random.Range(0, 360);
    }

    private int RandPos()
    {
        return Random.Range(-3, 3);
    }
}

コード紹介

登場人物

  • north : 仮想北を向く青矢印。携帯では簡単に取得できるがサンプルなのでオレオレ実装。(以下仮想略)
  • came : 仮想カメラで撮影用みたいなカメラを使用。見えないとわかりにくいので仮想。(以下仮想略)
  • arrowPrefab : 今回の主人公。came の前に north に合わせて表示される。
    [SerializeField] private Transform north;
    [SerializeField] private Transform came;
    [SerializeField] private GameObject arrowPrefab;

方位磁石に合わせて came を xz 平面の角度で考えたい

三次元ベクトルをある平面上に投影する ProjectOnPlane を使用します。
これだけでカメラの前方の向きを、xz平面上に投影することができます。
こうすることで方位磁石の北向きと比較できるようにします。

            // xz平面上における camera の local の前向き
            var came2d = Vector3.ProjectOnPlane(came.forward, Vector3.up).normalized;

北向きとカメラの向きの角度を知りたい

平面上のベクトル間の角度を求める SingledAngle を使用します。
先ほどの ProjectOnPlane で二つのオブジェクト(north2d = 仮想の北向き、came2D = カメラの前向き)の、
ベクトルに対する角度を取得することができます。
up と down の設定を逆にすると、角度の正負が逆になるので注意が必要です。

    private float InputCompassTrueHeading()
    {
        // ここの up は down でもどちらでも大丈夫、面を指定するので同じ意味合いになります。
        var north2d = Vector3.ProjectOnPlane(north.forward, Vector3.up);
        var came2d = Vector3.ProjectOnPlane(came.forward, Vector3.up);
        // ここの down を up にしてしまうと、角度が正負逆になってしまうので注意です。
        return Vector3.SignedAngle(north2d, came2d, Vector3.up);
    }

カメラの 5m 手前に矢印を表示する

forward に 5 をかけて、カメラの位置から和算してあげればいいだけですね。

            // カメラから見て 5m 先にポジションする
            var pos = came.position + came.forward * 5;
            // インスタンス生成、角度はなし
            var arrow = Instantiate(arrowPrefab, pos, Quaternion.identity);

矢印を常に北向きに表示する

arrow を direction に LookAt するときに、came2d をコンパス分回転させたものが local なので、
arrow の位置が原点にない場合はおかしくなってしまいます。
わかっていればすぐですが、わからないと何がなんだかのところなので注意が必要です。

            // xz平面上における camera の local の前向き
            var came2d = Vector3.ProjectOnPlane(came.forward, Vector3.up).normalized;
            // コンパス分を戻す
            var direction = Quaternion.Euler(new Vector3(0, -InputCompassTrueHeading(), 0)) * came2d;
            // 向き先を local から world にするために自身の position を追加する
            arrow.transform.LookAt(arrow.transform.position + direction);

参考

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

【Unity】URP環境でポストエフェクトを追加する方法

UnityでURPを導入したときにPostProcessingを適用する手順についてのメモになります。

1.CameraのPost Processingにチェックを入れる。

01.png

2.Hierarchyを右クリックしVolume > Global Volumeを選択しGlobal Volumeを追加する。

02.png

3.追加したGlobal VolumeのProfileを追加しAdd Overrideボタンから追加したいエフェクトを選択する。

03.png

以上です。

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