fc2ブログ
ヽ|∵|ゝ(Fantom) の 開発blog? ホーム »Unity
カテゴリー「Unity」の記事一覧

【Unity】【C#】3DText(TextMesh) を半透明より手前に表示する  


 VRM Live Viewer には 3D空間上に名前を表示する機能があるんだけど、それを実装したときの Tips の1つ。

 Unity では 3D空間にテキストを表示する方法として 3DText (Text Mesh) というものがあり、常に最前面に表示されるので便利…と思ったら、半透明なものには後ろになってしまうんだよね。

 VRM Live Viewer では自由にオブジェクトを配置できるので、最前面に出てくれないと、背景オブジェクトによっては後ろに回ってテキスト(名前)が見えなくなってしまう。

 なので、ググってたら描画順を変更するために、シェーダを作ってる例があった。と言っても、これらは逆に後ろに回すためのものだけどね。

(3DText を後ろに周りこませる)
3D Textの前後関係を正しく表示する
3DTextの主張を止めたい

 しかし、このためだけにシェーダ作るのも何だな~、と思ったので(シェーダはシステム依存が強いので、後々面倒になることが多い)、スクリプトで RenderQueue を変更してみたら、上手くいったので、その時のメモ。

●デフォルトでは 3DText は半透明より後ろに描画されるが、スクリプトで最前面に表示させた例


(※) Unity 2020.3.34f1 / Windows11(x64) で確認


●3DText (Text Mesh) のRenderQueue を変更して、透明より手前に表示させる
using UnityEngine;
using UnityEngine.Rendering;

namespace Example
{
public class TextMeshRenderQueue : MonoBehaviour
{
public TextMesh textMesh; //描画順を変更する 3DText をアタッチ
public int renderQueue = (int)RenderQueue.Transparent + 1; //3001 (とりあえず、透過より大きくしておく)

private void Reset()
{
if (textMesh == null)
textMesh = GetComponent<TextMesh>();
}

// Use this for initialization
private void Start()
{
textMesh.font.material.renderQueue = renderQueue;
}
}
}

 何らかの 3DText (Text Mesh) の1つにアタッチして、プレイするだけで、描画順が透明の RenderQueue + 1(Transparent+1 [=3000+1]) に変更されるので、常に最前面に表示されるようになる。3001 以上の描画順が他にあるなら、それより大きい値にすれば良い。

 ただ欠点としては、TextMesh.font.material が sharedMaterial みたいなもの(?)だったので、3DText ごとに描画順を設定できないことかな。なので、全体で1つの描画順となる。試しに Material を複製して再設定してみたが、なぜか上手く行かなかった。まぁ、使い勝手は悪いが「全てにおいて最前面に表示」みたいな使い方なら、問題無く使える。







(関連記事)
【Unity】【C#】制限付きでテキストのサイズに合わせて他のオブジェクトのサイズも変化させる
【Unity】【C#】RectTransform の矩形の実座標を取得する(GetWorldCorners)
【Unity】【C#】uGUI ドロップダウンの要素をコードで設定と取得、外観のカスタマイズなど
【Unity】【C#】固定背景画像(2D)を表示する
【Unity】【C#】HDR Color を計算(変換)する
【Unity】【C#】ガンマ(Gamma, sRGB) - リニア(Linear) 値の相互変換


スポンサーサイト



category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: Unityリファレンス 
tb: 0   cm: --

【Unity】【C#】固定背景画像(2D)を表示する  


 VRM Live Viewer には固定で2D画像を表示できる機能があるが、これの実装を簡単に書いておこう。

 といっても、私もこちらの記事を参考にさせて貰って作ったものだったりする(とりま何でもググる(笑))。

(参考) 背景・前景を固定する

 ただ今の Unity のバージョンだともう少し簡単にできる方法があるので、あくまでも考え方だけ応用した感じ。大まかに説明すると、Quad の代わりに Canvas と RawImage で同じことをすれば、調整などもいらないのでかなり楽にできる。それではやってみよう。


(※) Unity 2020.3.34f1 / Windows11(x64) で確認



■ヒエラルキー上に固定背景専用のカメラと Canvas(RawImage) を用意する

1. まずはスクショのように、空オブジェクト(FixedImage)[※名前等は任意]を作り、その中に Canvas と Camera を新規に追加しよう。Canvas には1つ RawImage を置いておく。



2. 固定背景には余計なものを映したくないので、専用の Layer (2DImage)[※名前は任意] を作って、全て Layer を設定しておく(一番上の FixedImage の Layer を変更すれば「子オブジェクトも変更するか?」のメッセージが出るので適用するのが簡単)。




3. Canvas の Render Mode を「Screen Space - Camera」にし、Render Camera に先程新規追加した Camera をセットしておく。Order in Layer は -1000 など、なるべく一番背後になるような値にしておくと良いだろう。



4. Camera の Clear Flags は Solid Color にし、黒にしておく。Culling Mask に先程作った専用 Layer (2DImage) を指定し、他の Layer が映らないようにしておく。2D 画像専用なら、Projection を Orthographic にしておくと良いだろう。Depth は Main Camera より低い値にしておく。



5. RawImage はストレッチを最大にして、Aspect Ratio Fitter をアタッチしておくと良いだろう。アス比(Aspect Ratio) は 1.77778 (= 16/9 [16:9]) にしておけば良い(もちろん、4:3 の画像なら 1.33333 とかにする)。



6. 最後に元からある Main Camera の Clear Flags を「Depth only」にし、Culling Mask からは「2DImage」の Layer は外しておく(2DImage は映さない=専用カメラで映すため)。



 これで準備は完了だ。固定背景とそれ以外をわかりやすくするために、ヒエラルキーに Capsule など 3Dオブジェクトを置いておくのも良い。次にスクリプトで画像をロードしてみよう。



■スクリプトで画像をロードして、固定背景として映す

 ヒエラルキーの RawImage をスクリプトにアタッチしたら、適当な画像を path に入れて欲しい。フォーマットは .jpg か .png が良いだろう。あとはエディタ上でプレイ(開始)すれば、読み込めるだろう。

●画像を読み込んで、固定背景にするテストスクリプト
using System.IO;
using UnityEngine;
using UnityEngine.UI;

namespace Example
{
public class FixedImageTest : MonoBehaviour
{
public RawImage rawImage;
public string path; //背景にしたい画像のフルパスをインスペクタで入れる

private void Start()
{
if (File.Exists(path))
{
rawImage.texture = LoadTexture2D(path);
}
}

//2D画像をロード
Texture2D LoadTexture2D(string path)
{
var bytes = File.ReadAllBytes(path);
var texture = new Texture2D(2, 2, TextureFormat.ARGB32, mipChain: false);
texture.filterMode = FilterMode.Bilinear;
texture.Compress(false);
texture.LoadImage(bytes);
return texture;
}
}
}


 2D画像のロードは定型処理なので、static にしてライブラリとして使い回せば良いと思う(ここでは簡単にするため、エラーキャッチ等してないので注意)。動画にしたいときは VideoPlayer に動画を読み込んで、RenderTexture に映して表示すれば良い。

 注意点としては Main Camera の Clear Flag を Depth only にしなければならないので、その辺りの切り替えが必要ということかな。アプリでは 2D画像/動画モードに切り替えたときにそうしてる(空[Skybox]が使えなくなるので注意)。画面に貼り付いた感じになるので、距離感や方向感も無くなるね。ADVゲームの固定背景みたいな使い方になるだろう。







(関連記事)
【Unity】【C#】BMP をランタイムで読み込む
【Unity】【C#】画面解像度とアクペクト比(整数)を求める
【Unity】ヒエラルキー(シーン)の Image, RawImage に使われている画像(Texture)を検出するエディタ拡張(ツール)
【Unity】【C#】HDR Color を計算(変換)する
【Unity】【C#】ガンマ(Gamma, sRGB) - リニア(Linear) 値の相互変換
【Unity】【C#】3DText(TextMesh) を半透明より手前に表示する


category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: Unityリファレンス  画像ファイル読み込み 
tb: 0   cm: --

【Unity】【C#】音量設定用にデシベル(dB)変換をする  


 これも VRM Live Viewer の音量設定を作ったときのメモ。

 Unity には AudioMixer という複数の音量(Master, Music, SE, ...等)をミキシングして出力できる便利な機能があるのだけれど、設定する値は 0~1f ではなく、デシベル[dB](-80dB~0dB) なんだよね。

 デシベル変換はググればいくらでも出てくるけど、定型処理なら拡張メソッドにしておくと楽なので、いつものように簡単に定義しておいたもの。
あと AudioMixer 使う際に気になる事があったので、少しばかり工夫してる。

(参考)デシベルのすすめ (KAYAC engineers' blog)


(※) Unity 2020.3.34f1 / Windows11(x64) で確認



■音量(0~1f) → デシベル(-80~0dB) に変換する

●音量(0~1f) → デシベル(-80~0dB) に変換する
using UnityEngine;

namespace Exsample
{
public static partial class Extensions //※クラス名は任意
{
//無音とみなすデジベル(dB) や音量
const float DECIBEL_MIN = -80f; //この dB 以下をミュート(音無し)とする
const float DECIBEL_MUTE = DECIBEL_MIN * 10; //単位: dB (-80dB だと僅かに聞こえる気がするので、とりあえず10倍してる)
const float VOLUME_MIN = 0.0001f; //この volume 以下をミュート(音無し)とする

/// <summary>
/// 音量(0~1f) → デシベル(-80(-800)~0dB) に変換
/// ※ただし、volume ≤ 0.0001f のとき -800 [db] を返す
/// (参考) https://techblog.kayac.com/linear-vs-decibel
/// </summary>
/// <param name="volume">0~1f</param>
/// <returns>-80(-800)~0 [dB]</returns>
public static float ToDecibel(this float volume)
{
if (volume <= VOLUME_MIN) //0.0001f を最小値とする
return DECIBEL_MUTE; //-800dB (-80dB だと僅かに聞こえる気がするので、とりあえず10倍してる)

var db = 20 * Mathf.Log10(volume);
return Mathf.Clamp(db, DECIBEL_MUTE, 0f);
}
}
}

 参考資料そのままだが、冒頭に書いた「少しばかり工夫してる」とは、最小値 (0.0001) 以下では DECIBEL_MUTE (-800dB) を返すところで、AudioMixer の Threshold のデフォ値(-80dB) 付近だと、わずかに音が聞こえる気がするからだ。もちろん Threshold の値を上げても良いが、毎回調整するのは面倒なので(笑)、とりま 10倍した値(-800dB)を返すようにしてる。これをそのまま AudioMixer.SetFloat に当ててやれば、確実に無音(ミュート)できる。

(参考)デシベルのすすめ (KAYAC engineers' blog)

 アプリではわかりやすいように音量を 0~100(%) 表記してるが、やはり定型処理となるので、以下のような簡単な拡張メソッド(.NET 4.x)を作るのも良いだろう。

//音量(0~100%) → デシベル(-80(-800)~0dB) に変換
public static float PercentToDecibel(this float per) => ToDecibel(per * 0.01f);




■デシベル(-80~0dB) → 音量(0~1f) に変換する

●デシベル(-80~0dB) → 音量(0~1f) に変換する
using UnityEngine;

namespace Exsample
{
public static partial class Extensions //※クラス名は任意
{
/// <summary>
/// デシベル(-80~0dB) → 音量(0~1f) に変換
/// (参考) https://techblog.kayac.com/linear-vs-decibel
/// </summary>
/// <param name="decibel">-80~0dB</param>
/// <returns>0~1f</returns>
public static float FromDecibel(this float decibel)
{
if (decibel <= DECIBEL_MIN) //-80dB を最小値とする
return 0f;

return Mathf.Pow(10f, decibel / 20f);
}
}
}

 これも参考資料そのままなので、詳細はそちらを参考にして欲しい。

(参考)デシベルのすすめ (KAYAC engineers' blog)

 これも少し手を加えたのは、-80dB を引数に与えると 0.0001 の計算値になるので、強制的に 0 (無音) にしている所。この方が実用的で使いやすかっただけのこと。

 例えば簡単にテストすると、以下のような結果になる。

var volMin = 0f;
var volMax = 1f;
var volOverMin = -1f;
var volOverMax = 2f;

//volume (0~1f) → dB (-80(-800)~0dB) 変換
var dBMin = volMin.ToDecibel();
var dBMax = volMax.ToDecibel();
var dBOverMin = volOverMin.ToDecibel();
var dBOverMax = volOverMax.ToDecibel();

Debug.Log($"volMin = {volMin}, ToDecibel = {dBMin}");
Debug.Log($"volMax = {volMax}, ToDecibel = {dBMax}");
Debug.Log($"volOverMin = {volOverMin}, ToDecibel = {dBOverMin}");
Debug.Log($"volOverMax = {volOverMax}, ToDecibel = {dBOverMax}");

//dB (-80(-800)~0dB) → volume (0~1f) 変換
var dBMinToVol = dBMin.FromDecibel();
var dBMaxToVol = dBMax.FromDecibel();
var dBOverMinToVol = dBOverMin.FromDecibel();
var dBOverMaxToVol = dBOverMax.FromDecibel();

Debug.Log($"dBMin FromDecibel = {dBMinToVol}");
Debug.Log($"dBMax FromDecibel = {dBMaxToVol}");
Debug.Log($"dBOverMin FromDecibel = {dBOverMinToVol}");
Debug.Log($"dBOverMax FromDecibel = {dBOverMaxToVol}");

volMin = 0, ToDecibel = -800
volMax = 1, ToDecibel = 0
volOverMin = -1, ToDecibel = -800
volOverMax = 2, ToDecibel = 0
dBMin FromDecibel = 0
dBMax FromDecibel = 1
dBOverMin FromDecibel = 0
dBOverMax FromDecibel = 1








(関連記事)
【Unity】【C#】HDR Color を計算(変換)する
【Unity】【C#】ガンマ(Gamma, sRGB) - リニア(Linear) 値の相互変換
【C#】文字列 → float (浮動小数点) 変換でエラーが出るときは…


category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: Unityライブラリ  Unityリファレンス  算術関数  サウンド 
tb: 0   cm: --

【Unity】【C#】HDR Color を計算(変換)する  


 現在の VRM Live Viewer にはパーティクルの発光色を設定できる機能があり、HDRカラーピッカーが実装されているのだけど、これを作ったときのメモ。

 そもそも Unity にはエディタ上で普通に HDRカラーピッカーが入ってるのだけど、なぜか API にはそういった Utility クラスが無いんだよね。なので、ググってたら、いくつか見つけたので、それを少しばかり使いやすくした例。

(参考) How to Get / Set HDR Color intensity


(※) Unity 2020.3.26f1 / Windows11(x64) で確認



■LDR Color と intensity → HDR Color に変換する

 参考資料を見てみると、どうやら HDR Color の計算は LDR Color の アルファを除いた RGB の各要素に 2 の intensity 乗(= 2intensity) を掛ければ良いようだ。実際にやってみたら、Unity エディタ上のカラーピッカーの色とも合致する。なので、変換する拡張関数を定義すると以下のようになる。

(参考) How to Get / Set HDR Color intensity

●LDR Color と intensity → HDR Color に変換する
using UnityEngine;

namespace Exsample
{
public static partial class Extensions //※クラス名は任意
{
/// <summary>
/// LDR Color と intensity → HDR Color に変換する
/// https://answers.unity.com/questions/1652854/how-to-get-set-hdr-color-intensity.html
/// </summary>
/// <param name="ldrColor">LDR Color</param>
/// <param name="intensity">輝度(intensity)</param>
/// <returns>HDR Color</returns>
public static Color ToHDRColor(this Color ldrColor, float intensity)
{
var factor = Mathf.Pow(2, intensity);
return new Color(
ldrColor.r * factor,
ldrColor.g * factor,
ldrColor.b * factor,
ldrColor.a
);
}
}
}

 これは参考資料をそのまま拡張メソッドにしただけである。intensity = 0 のときは 20 = 1 なので、元のままとなるね。2 の intensity 乗(= 2intensity) というのは、そういうものと覚えておけば良いだろう。

(参考) How to Get / Set HDR Color intensity



■HDR Color → LDR Color と intensity に分離する

 次は前述の HDR Color 変換とは逆で、HDR Color を LDR Color と intensity に分離する計算だ。といっても参考資料そのままでも良いので、ここでは少しだけ使いやすく、戻り値を Tuple 型(.NET 4.x)にして、表現の値を255値にした例を書いておこう。

●HDR Color → LDR Color と intensity に分離する
using UnityEngine;

namespace Exsample
{
public static partial class Extensions //※クラス名は任意
{
private const byte k_MaxByteForOverexposedColor = 191; //internal Unity const

/// <summary>
/// HDR Color を baseColor, intensity(exposure) に分離する (Tuple)
/// https://answers.unity.com/questions/1652854/how-to-get-set-hdr-color-intensity.html
/// ※overExposed = 255 を与えると直感的になる : (白) baseColor = RGBA(1.000, 1.000, 1.000, 1.000), intensity = 1
/// Unity デフォ = 191 で HDR Color ピッカーと同等 : (白) baseColor = RGBA(0.749, 0.749, 0.749, 1.000), intensity = 1.416925
/// </summary>
/// <param name="linearColorHdr">HDR Color</param>
/// <param name="overExposed">internal Unity const = 191 (デフォルト: 255)</param>
/// <returns>(LDR Color, intensity)</returns>
public static (Color32, float) DecomposeHdrColor2(this Color linearColorHdr, byte overExposed = 255)
{
Color32 baseLinearColor32 = linearColorHdr; //※暗黙変換には型が必要
var exposure = 0f;

var maxColorComponent = linearColorHdr.maxColorComponent; //※たぶん (r,g,b) 内で一番高い値 → 1f を超えてたら HDR となる

// replicate Photoshops's decomposition behaviour : Photoshopの分解動作を複製する
if (maxColorComponent == 0f || maxColorComponent <= 1f && maxColorComponent >= 1 / 255f) //1/255 = 0.003921568627451
{
exposure = 0f;
baseLinearColor32.r = (byte)Mathf.RoundToInt(linearColorHdr.r * 255f);
baseLinearColor32.g = (byte)Mathf.RoundToInt(linearColorHdr.g * 255f);
baseLinearColor32.b = (byte)Mathf.RoundToInt(linearColorHdr.b * 255f);
}
else
{
// calibrate exposure to the max float color component : 最大フロートカラーコンポーネントへの露出を調整します
var scaleFactor = overExposed / maxColorComponent;
exposure = Mathf.Log(255f / scaleFactor) / Mathf.Log(2f);

// maintain maximal integrity of byte values to prevent off-by-one errors when scaling up a color one component at a time
baseLinearColor32.r = Math.Min(overExposed, (byte)Mathf.CeilToInt(scaleFactor * linearColorHdr.r));
baseLinearColor32.g = Math.Min(overExposed, (byte)Mathf.CeilToInt(scaleFactor * linearColorHdr.g));
baseLinearColor32.b = Math.Min(overExposed, (byte)Mathf.CeilToInt(scaleFactor * linearColorHdr.b));
}

return (baseLinearColor32, exposure);
}
}
}

//メインでは…
//var (baseColor32, intensity) = emissionColor.DecomposeHdrColor2(); //overExposed = 255

 コードも参考資料とほとんど変わらない。ただ、Unity エディタで HDRカラーピッカーを使っている時、Intensity の値を上げると、再び開き直した時、なぜか 191 になってるのが不思議だったが、どうやら内部の定数値「k_MaxByteForOverexposedColor = 191」が効いていたようだ。なので overExposed で 255 をデフォルトで与えることによって(RGB 要素で 255 を超えた場合の表現方法らしい)、より LDR Color が直感的になったので変更している。Unity エディタと同じにしたければ、overExposed = k_MaxByteForOverexposedColor (191) を引数に与えれば良い。元コードのコメントを読むと、191 は PhotoShop に合わせた値らしいが、色コード("#FFFFFF" のような形式)として扱う場合には、ちょっと使いづらいんだよね…。

(参考) How to Get / Set HDR Color intensity



■HDR Color から intensity のみを取り出す

 これは前述の HDR Color → LDR Color と intensity に分離する の縮小版みたいなものだ。実際に DecomposeHdrColor2() のコードの一部のみを抜き出した感じとなる。輝度(Intensity)だけ欲しいときなど、短く書けるので一応載せておこう(もちろん、DecomposeHdrColor2() を使って intensity だけを得ても同じ)。

●HDR Color → LDR Color と intensity に分離する
using UnityEngine;

namespace Exsample
{
public static partial class Extensions //※クラス名は任意
{
private const byte k_MaxByteForOverexposedColor = 191; //internal Unity const

/// <summary>
/// HDR Color から Intensity のみを取得する
/// https://answers.unity.com/questions/1652854/how-to-get-set-hdr-color-intensity.html
/// ※overExposed = 255 を与えると直感的になる : (白) baseColor = RGBA(1.000, 1.000, 1.000, 1.000), intensity = 1
/// Unity デフォ = 191 で HDR Color ピッカーと同等 : (白) baseColor = RGBA(0.749, 0.749, 0.749, 1.000), intensity = 1.416925
/// </summary>
/// <param name="hdrColor">HDR Color</param>
/// <param name="overExposed">internal Unity const = 191</param>
/// <returns>輝度(intensity)</returns>
public static float ExtractIntensity(this Color hdrColor, byte overExposed = 255)
{
var maxColorComponent = hdrColor.maxColorComponent;
var scaleFactor = overExposed / maxColorComponent;
return Mathf.Log(255f / scaleFactor) / Mathf.Log(2f);
}
}
}

 これは参考資料の最後にあるコードと同じ。これも DecomposeHdrColor2() と同じように、overExposed の引数を k_MaxByteForOverexposedColor (191) にすれば、Unity エディタ上の HDRカラーピッカーと同じ値になる。

(参考)
How to Get / Set HDR Color intensity







(関連記事)
【Unity】【C#】ガンマ(Gamma, sRGB) - リニア(Linear) 値の相互変換
【Unity】色形式:Unity の Color と Android の ARGB(int32) の相互変換をする


category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: Unityライブラリ  C#  グラフィックス 
tb: 0   cm: --

【Unity】【C#】Project Settings (Graphics Settings) をスクリプトで変更する  


 う~む、Unity 標準の Fog (Light Settings にあるやつ) を実験してたんだけど、どうやら Android でビルドすると、アプリサイズが肥大化するみたいだな。3種類(Linear, Exponential, ExponentialSquared) 入れてみたら、200MB も増えた…。そしてスマホだとメモリー不足で落ちる…。|||orz

 しかし、PC 版には入れたい(PC 版ではあまりサイズは増えない)。だけど Graphics Settings って、Shader stripping 以下の項目ってプラットフォームごとに設定できないんだよね。PC 版では Custom で 3種類(Linear, Exponential, ExponentialSquared) 入れて、Android 版では入れないようにしたい。でも毎回手動で設定するのは面倒くさい…。

 Editor~系のクラスでできるのかな?と思ったけど、どうもできそうなのが見つからないので、ググってみたら、似たようなことをやってるのを見つけた。これを改造したら、どうやら上手く行くようだ。そのメモ。

(参考)
Project Settings の「Disable Unity Audio」をスクリプトから操作する方法

(※) Unity 2020.3.26f1 / Windows11(x64) で確認

●Graphics Settings の Fog 設定をスクリプトで変更する (メニュー)
using System.Linq;
using UnityEngine;
using UnityEditor;

namespace Exsample
{
//※Editor フォルダに配置
public static partial class GraphicsSettingsEdit //※クラス名は任意
{
//フォグ設定をビルドに含める
[MenuItem("Tools/Include Fog in Build")]
private static void IncludeFogInBuild()
{
var path = "ProjectSettings/GraphicsSettings.asset";
var manager = AssetDatabase.LoadAllAssetsAtPath(path).FirstOrDefault();
var obj = new SerializedObject(manager);
var prop = obj.FindProperty("m_FogStripping");
prop.intValue = 1; //0: Automatic, 1: Custom
prop = obj.FindProperty("m_FogKeepLinear");
prop.boolValue = true;
prop = obj.FindProperty("m_FogKeepExp");
prop.boolValue = true;
prop = obj.FindProperty("m_FogKeepExp2");
prop.boolValue = true;
obj.ApplyModifiedProperties();
}

//フォグ設定をビルドから除外
[MenuItem("Tools/Exclude Fog in Build")]
private static void ExcludeFogInBuild()
{
var path = "ProjectSettings/GraphicsSettings.asset";
var manager = AssetDatabase.LoadAllAssetsAtPath(path).FirstOrDefault();
var obj = new SerializedObject(manager);
var prop = obj.FindProperty("m_FogStripping");
prop.intValue = 1; //0: Automatic, 1: Custom
prop = obj.FindProperty("m_FogKeepLinear");
prop.boolValue = false;
prop = obj.FindProperty("m_FogKeepExp");
prop.boolValue = false;
prop = obj.FindProperty("m_FogKeepExp2");
prop.boolValue = false;
obj.ApplyModifiedProperties();
}
}
}

 これは Unity プロジェクトのルートにある ProjectSettings フォルダ内の GraphicsSettings.asset の内容を書き換えるものだ。各 ~.asset ファイルは YAML(?)なので、テキストエディタで開ける。"m_~" でプロパティ名で保存されているので、何でもできそうだ(名前がわからないのなら、一度エディタで変更して、差分を見ればわかる)。

 ここでは余談だが、Automatic だと、エディタではオフで、ランタイムでオンに切り替えたりする使い方の場合、stripping されるのでビルドに含まれなくなってしまう。必ず Custom にして、使いたい FogMode をオンにしておく必要がある。



 上記のスクリプトはメニューから変更するものだけど、これと以前作ったプラットフォーム切り替えのコールバックを合わせれば、自動で設定変更もできる

Unity2020 でプラットフォーム切り替えをすると、Run In Background が勝手にオフになってしまう

●プラットフォーム切り替え・ビルド開始時にフォグ設定を強制的に更新するスクリプト
using UnityEngine;
using UnityEditor;
using UnityEditor.Build;

//※Editor フォルダに配置
public class EditorPlatformSetting : IActiveBuildTargetChanged, IPreprocessBuild //※クラス名は任意
{
public int callbackOrder => 0;

//ビルドターゲットを変更したときのコールバックハンドラ
public void OnActiveBuildTargetChanged(BuildTarget previousTarget, BuildTarget newTarget)
{
Debug.Log("BuildTarget is " + newTarget);
UpdateFogSettingsByPlatform(newTarget);
}

//ビルド開始するときのコールバックハンドラ
public void OnPreprocessBuild(BuildTarget target, string path)
{
UpdateFogSettingsByPlatform(target);
}

//プラットフォームにより、強制的にフォグ設定を更新する
void UpdateFogSettingsByPlatform(BuildTarget target)
{
switch (target)
{
//※必要なら、プラットフォームを追加する
case BuildTarget.StandaloneWindows:
case BuildTarget.StandaloneWindows64:
IncludeFogInBuild(); //フォグをビルドに含める
break;

case BuildTarget.Android:
ExcludeFogInBuild(); //フォグをビルドから除外
break;
}
}
}

 OnActiveBuildTargetChanged(BuildTarget previousTarget, BuildTarget newTarget) でプラットフォーム判別できるので、ここで IncludeFogInBuild() または ExcludeFogInBuild() を呼べば良いね。path と FindProperty() のプロパティ名を変えれば、色々自動化できそうだ。ただし、Unity はバージョンによって、たまにプロパティ名が変わるので、そこだけは注意だけどね。







(関連記事)
Unity】Unity2020 でプラットフォーム切り替えをすると、Run In Background が勝手にオフになってしまう


category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: Unityリファレンス  エディタ拡張 
tb: 0   cm: --


プロフィール

Social

検索フォーム

全記事一覧

カテゴリ

ユーザータグ

最新記事

リンク

PR

▲ Pagetop