- 2020/11/12 【Unity】Unity2019以降で新規作成したアセットは、Unity2018以前にインポートすると壊れる?
- 2020/09/08 【Unity】InputField のキャレット(点滅するカーソル) が見えないときは…
- 2019/11/29 【Unity】UI のフォーカスを外すコードと「Attempting to select while already selecting an object.」
- 2019/11/12 【Unity】タブ切り替えの UI をコードを書かないで作る
- 2019/09/07 【Unity】【C#】制限付きでテキストのサイズに合わせて他のオブジェクトのサイズも変化させる
« prev next »
【Unity】Unity2019以降で新規作成したアセットは、Unity2018以前にインポートすると壊れる? 
2020/11/12 Thu [edit]
以前、タブ切り替えUI(TabStrip, TabWidght)をパッケージ配布したが、タブのアセットは Unity2018.4 で作ってあり、特別なコンポーネントも使ってなかったので、Unity5.6, Unity2017, Unity2019 でも正常に利用できていた。
そして今回、Attached Image Finder のバージョン互換性を試していて気がついたのだが、どうやら Unity2019 上で新規に作ったアセットをエクスポートした場合、Unity2018 以前のバージョン(Unity2017, Unity5.6)でインポートすると、アセット(参照?)が壊れるようだ(ものにも依るかも知れないが)。
Unity2019.3 からはアセット管理の内部的な仕様がかなり変更されているからね。広くバージョン依存が少ないアセットを公開するには、注意が必要かも知れない。
・Unity 2019 LTS へのアップグレード
(※) Unity 2019.4.14f1 / Windows10(x64) で確認
具体的に説明すると、Unity2019.4 で UI-Image を3つ新規作成し、それぞれに適当な画像をアタッチしただけのものだ。それ以外は Canvas Scaler を設定しただけで、ほぼデフォルトのままである。そのサンプルシーンを Export Package する。
パッケージができたら、それを違う Unity のバージョンでインポートしてみる。今回試してみたのは Unity2018.4, Unity2017.4, Unity5.6.3 の3つだ。
簡単に言えば、Unity2019 で新規作成したアセットをエクスポート → Unity2018 以前(Unity2018. Unity5.6)へインポートすると壊れる。
また、Unity2019.2 でマイナーバージョンの違いも試してみたが、結果は同じようだ。
もう1つ違う実験をしてみたのだが、Unity2018 で同じように UI を配置したシーンを新規作成。それをエクスポートして、Unity2019 へインポート。そしてその後、Unity2019 からパッケージとしてエクスポートしてみた。そしたら、なぜがどのバージョンでも正常に表示された。Unity2017 でも試したが結果は同じだった。もしかして、Unity2019以降で新規にオブジェクトを作る(or 更新等)と、内部的なコンポーネントの ID(?)等が異なってしまう?
簡単に言えば、Unity2018以前(Unity2017, Unity5.6) で新規作成したアセットをエクスポート → Unity2019 に一旦インポートしてから、そのままエクスポート → Unity2018 以前にインポートしても正常に使える。
まぁ、Unity4 時代の .js で作ったアセットを読み込むと同じように壊れたりするが、シーンのメタデータも Unityのバージョンを上げると、シリアライズの番号が変わったり、GUIDみたいなものが変わったりとすることがあるので、何らかが影響してるのかもね。
とにかく、Unity2019 以降で新規にオブジェクトを作った場合、旧バージョンとの互換性は無い可能性が高いので(基本的にダウングレードは避けるべきだが)、一般配布するアセットでバージョン依存しないものにするには、Unity2018 以前でエクスポートした方が良いかもね。
(関連記事)
【Unity】【C#】ヒエラルキー(シーン)の Image, RawImage に使われている画像(Texture)を検出するエディタ拡張(ツール)
【Unity】タブ切り替えの UI をコードを書かないで作る
【Unity】InputSystem 対応 ピンチ操作ライブラリ (FantomPlugin 追加機能)
【Unity】Androidのトーストやダイアログ、通知、音声認識、ハード音量操作など基本的な機能を使えるプラグインを作ってみた
【Unity】InputField のキャレット(点滅するカーソル) が見えないときは… 
2020/09/08 Tue [edit]
エディタ画面ではちゃんと映っているのだが、なぜかランタイム(または Game ビュー)では InputField のキャレット(カーソル) が消えてしまい、少しつまづいたので、対処法を備忘録として残しておく。
(※) Unity 2019.2.21f1 / Windows10(x64) で確認
結論からと言うと、これは解像度による画像やフォントなどの自動伸縮によるもので、私が使っていた Canvas Scaler や Game ビューの解像度で 1px が伸縮され、見えなくなっていただけだった。

※クリックで画像拡大
はじめは原因がわからなかったのだが、エディタ上では見えているので、インスペクタで色々いじってみたら、InputField コンポーネントの設定で「Caret Width」をデフォルトの 1 → 2 へ変更したら見えるようになった。


※クリックで画像拡大
まぁ、もちろんキャレット(カーソル)の幅が大きくなってしまうのだが、解像度が十分に高い環境なら、ほとんど違いは気にならないだろう。
このとき使っていた設定は Canvas Scaler は 1920x1080 (Height: 1), Gameビューとランタイム時の解像度は 1280x720 にしていたが、この組み合わせだと(または UI の配置など)、たまたまキャレットが消えてしまったらしい(Gameビューの解像度を変えると見える)。
元々 Canvas 自体もスケールなどによって伸縮されたりするが、キャレットなど 1px の画像なども伸縮されたとき、計算上見えなくなってしまうことがある。これは画像の伸縮アルゴリズムによるものだと思うが(例えば、バイリニア法だとピクセルにスムージングがかかったりするが、ニアストレイバー法だと荒くなるみたいな。フォトショなどで 1px 画像を作って試すとわかる)、配置する座標などによっても見え方が変わることもある(浮動小数点型だと、整数位置以外にも置けるが、物理的なディスプレイはドットなので、当然半端な位置ほど、画像がぶれやすくなる → なので、Pixel Perfect みたいなオプションがある)。
まぁ、ただの仕様みたいなものなので、対処法は今回みたいに「Caret Width」を変えるとか、または解像度を固定するとか、場合によっては Text Mesh Pro (TMP) の UI 使うとか(小さい UI でもくっきり見やすい)、状況によって色々あると思うけど、見た目おかしくならなければ何でも良いと思う。少しでもヒントになれば嬉しい。
(関連記事)
【Unity】タブ切り替えの UI をコードを書かないで作る
【Unity】【C#】制限付きでテキストのサイズに合わせて他のオブジェクトのサイズも変化させる
【Unity】UI のフォーカスを外すコードと「Attempting to select while already selecting an object.」
【Unity】【C#】uGUI ドロップダウンの要素をコードで設定と取得、外観のカスタマイズなど
【Unity】5.6 の Canvas の警告:Shader channels Normal and Tangent are most often used with lighting~ を消す
【Unity】UI のフォーカスを外すコードと「Attempting to select while already selecting an object.」 
2019/11/29 Fri [edit]
最近まで気が付かなかったのだが、Unity の UI を使っていると、例えばマウスでボタンをクリックした後に、キーボードの [Enter] キーを押すとそのままフォーカスが残っていて、無駄に連打されてしまうことがある。
そこでフォーカスを外す方法を調べたら「EventSystem.current.SetSelectedGameObject(null) を使うと良い」とあったので使ってみたのだが(※interactable を一旦 false にする手もあるが、元に戻す必要がある)、ごく稀にタイミングによっては以下のエラーが出ることがある。
UnityEngine.EventSystems.EventSystem:SetSelectedGameObject(GameObject)
・・・(中略)・・・
UnityEngine.EventSystems.EventSystem:Update()
(※) Unity 2018.4.13f1 / Windows10(x64) で確認
最初の1行(Attempting to select while already selecting an object.)を google翻訳にかけると…
いまいち意味がわからなかったので「Attempting to select while already selecting an object.」でググってみると、以下の記事が出てきた。
・選択中扱いとするゲームオブジェクトの管理
・Event System SetSelectedGameObject Error, but code still runs fine.
・Unity UI 4.6 inputfield bug or behavoir?
ああ、なるほど「現在選択中のオブジェクトと EventSystem.SetSelectedGameObject」 の引数のオブジェクトと比較して、同じだったらエラー出してる」んだね、と理解できた。
また、フォーラムでは「EventSystem.alreadySelecting」(EventSystem が SetSelectedGameObject に存在する場合は true を返す)を使うと良い、みたいなことが書かれてあったので、試してみたのだが、「フォーカスを外す」ときの引数に null を渡す場合、やはりたまにエラーが出ることがある。まぁ、Debug.LogError なら実害は無いのだが、なんとなく気持ち悪いので、他の方法がないかと試してみたら、以下のコードで上手くいった。
//現在アクティブとみなされる GameObject が null でないとき
if (EventSystem.current.currentSelectedGameObject != null)
{
EventSystem.current.SetSelectedGameObject(null); //フォーカスを外す
}
・EventSystem.currentSelectedGameObject
まぁ、使っているコードが EventSystem の static なメソッドのみなので、static なクラスに関数を作っても良いと思う。地味な挙動だが、かえってサンプルコードみたいのが出て来なかったので、備忘録として残しておく。
(関連記事)
【Unity】Unity2018 でビルドエラー「CommandInvokationFailure: Gradle build failed.」が出る
【Unity】IncrementalCompiler でのエラー:Unloading broken assembly Packages/com.unity.incrementalcompiler/Editor/Plugins/Unity.PureCSharpTests.dll, this assembly can cause crashes in the runtime
【Unity】【Android】2019.2.0 でパッケージ名(Bundle Identifer)でアンダーバーが使えない
【Unity】EventTrigger のコールバック引数変わった?
【Unity】タブ切り替えの UI をコードを書かないで作る 
2019/11/12 Tue [edit]
今回はスクリプト無しでタブ切り替え(TabStrip, Tabs Widget)を作る方法を紹介しよう。と言っても私が考えたわけではなく、内容的には海外記事の翻訳したものを、自分なりにアレンジしたものだったりする(笑)。
・Unity UI: Easy Tabs (no scripting)

タブの UI の実装に関しては、大抵スクリプトで画像を切替える方法がオーソドックスな気がするが、今回のように Toggle を上手く利用する方法もなるほどと感じたので、日本語記事にしておくと初心者にも役に立つんじゃないかと考えた(ググってもなぜかタブ実装の詳しい日本語記事が見つからなかったので)。それに何にしてもコードを書かずに済ませられるなら、それだけ労力を減らせるので、そういった方法は積極的に導入していくと良いと思う(アプリが大きくなるにつれ、大量のコードの管理・デバッグに時間を取られてしまうため)。
(※) Unity 2018.4.12f1 / Windows10(x64) で確認
■タブの backgroud 画像を用意する
とりあえず、参考記事を真似して、もっと簡単な画像を用意したので、必要ならダウンロードして使って欲しい。もちろんダウンロードした素材は自由に加工して使って貰っても構わない(zip には psd と完成例の unitypackage も付けておく)。
プロジェクトビューで適当なフォルダを作ったら、zip に入っている「Tab_altas.png」をドラッグドロップなどして、インポートして欲しい(.unitypackage はこの記事の完成例となっている。プレファブ化して利用するのも良いだろう)。
「Tab_altas.png」をインポートしたら、まずはインスペクタで「Texture Type」を「Sprite (2D and UI)」に、「Sprite Mode」を「Multiple」にしよう。これは1つの画像を複数のスプライトとして利用する設定だ。
次にそのままインスペクタから「Sprite Editor」を開いて、上部の [Slice]を押して、「Type」で「Grid By Cell Size」で「Pixel Size」を 64x64 にして、[Slice] して欲しい。これでグリッド状に 64x64 でスプライトが等分割される。
分割したら、各スプライトをクリックすると、右下に「Sprite」の設定が出るので、Name(名前)や Border(引き伸ばしの領域)を設定しておこう。名前は左から「Tab_panel」「Tab_item」(わかり易い名前なら何でも良い)と付けておき、Border は各スプライトの LRTB を全て 18 にしておいて欲しい。完了したら、右上の [Apply] を押しておく。画像の引き伸ばし領域の設定に関しては以下の記事がわかり易いだろう。
・UnityのSpriteを引き伸ばす際に綺麗に引き伸ばす方法 SpriteEditor
■タブの UI を作る
スプライトの設定ができたら、本題のタブの UI を作っていこう。まずは背景のベースとなる画像(Image)を1つ置く。場所はどこでも良いが、とりあえず中央に置いておきたいので RectTransform の Pos を全て (0, 0, 0) にしておく。
また、ついでに Image を置いたときに自動で追加された Canvas の「Canvas Scaler」を適当に設定しておく。ここでは「UI Scale Mode」を「Scale With Screen Size」に、「Reference Resolution」を「1920 x 1080」にしておいた。この辺りは自分の環境によって変えて欲しい。
先ほど置いた Image も「TabPanel」と名前を変えておき、サイズも適当に決めておこう。ここでは 600 x 500 にしておいた。そして Image に「Tab_altas」の分割スプライトの「Tab_panel」を設定しておく
次にタブの画像を並べるレイアウト用の空オブジェクトを作ろう。「TabPanel」をヒエラルキーで選択して、右クリックで「Create Empty」して、名前を「TabContainer」としておく。そして、[Add Component] から「Toggle Group」と「Horizontal Layout Group」を追加しておく。設定は自分の環境に合わせればよいが、「Child Control Size」と「Child Force Expand」をオンにしておけば、自動でレイアウトしてくれる。
また「TabContainer」の RectTransform は Pivot や引き伸ばしなどの設定をしておこう。これも画像などのサイズによるので、自由に設定しても構わない。設定例はキャプチャを参考にして欲しい。
TabContainer を適当に設定したら、次に各タブを作っていこう。TabContainer を右クリックして、Toggle を置く。初期位置がおかしくなってたりしたら、一旦 Toggle をオフ→オンにすると自動レイアウトになっている場合、再配置される(セーブなど何らかの操作をすると再計算される)。
置いた Toggle はわかり易いように「Tab 1」とでも名前を変えておき、「Toggle」コンポーネントの「Group」に、先ほど「TabContainer」にアタッチした「Toggle Group」を登録しておく。
そして「Tab 1」を展開し、「Bacground」の Image にスプライト「Tab_atlas」の「Tab_item」を設定する。Color も A(アルファ)を下げておく。RectTransform は適当で良いが、上下ストレッチを設定しておこう。
また、更に下の階層の「Checkmark」にも「Tab_item」を設定し、同じように RectTransform をストレッチ設定にしておく。あとはテキストとなる「Label」も適当に設定しておくと良いだろう。
タブが1つできたら、「Tab 1」を [Ctrl + D] で適当に複製しよう。名前は適当に付けて欲しい。また複製したタブの「Toggle」コンポーネントの「IsOn」は全てオフにしておく(これも設定したら、一旦オブジェクトをオフ→オンすると再描画できる)。
タブを並べたら、次に切り替える内容を作ろう。これも自分の環境によって何でも構わないが、「TabPanel」以下に適当に同じサイズの空オブジェクトをタブと同じ数だけ作り、内容を各オブジェクトに入れておく、ここでは「PageContainer」を作って「Page 1~3」を作ってテキストを入れておいただけだ。好きにやって貰って構わない。これらも「Page 1」以外は非表示にしておく(タブのオン/オフの初期状態に合わせておく)。
Page 1~3 を作ったら、各対応タブに戻り、「Toggle」コンポーネントの「On Value Changed (Boolean)」にコールバックを設定しよう。これは Toggle.IsOn のオン/オフ状態が変化したときに、実行されるメソッドなどを登録するものだ。ここに各対応する「Page」の表示/非表示を設定する。具体的には「Tab 1」には「Page 1」の「GameObject.SetActive (Dynamic)」をセットし、同様に「Tab 2」には「Page 2」を、「Tab 3」には「Page 3」をセットする。ここでは表示の切り替えだけなのでコードを書く必要はないが、色々コールバックに仕込みたいなら以下の記事を参考にして欲しい。
・【Unity】【C#】UnityEvent, Action, delegate, interface でのコールバック実装方法とインスペクタでの登録
もし、クリックしたときのトランジション(色の変化)がいらないなら、各 Toggle の Transition の Target Graphic を None(元の画像を外す)にしておけば良い。
これで完成だ。シーンを保存して動作を確かめてみよう。

(関連記事)
【Unity】【C#】UnityEvent, Action, delegate, interface でのコールバック実装方法とインスペクタでの登録
【Unity】【C#】制限付きでテキストのサイズに合わせて他のオブジェクトのサイズも変化させる
【Unity】【C#】RectTransform の矩形の実座標を取得する
【Unity】【C#】uGUI ドロップダウンの要素をコードで設定と取得、外観のカスタマイズなど
【Unity】【C#】インスペクタの表示項目を動的に変更する
【Unity】【C#】独自のギズモ(Gizmo)を表示する
【Unity】【C#】制限付きでテキストのサイズに合わせて他のオブジェクトのサイズも変化させる 
2019/09/07 Sat [edit]
ContentSizeFitter を使えば近い感じにもなるが、最小~最大みたいになると、レイアウトの入れ子になったり、オブジェクトを階層化しなくてはならなかったりと複雑になる気がするので、もっと簡単にできるものないかとググってみたら、やはり同じ様なものがあった。
・TextSizeAdjuster

ただ試してみたら、ちょっと私が欲しい挙動と違ったので、元のスクリプトを参考に改造してみた。簡単に言えば「テキストの幅が最小~最大サイズまでは伸縮し、最大を超えたら折り返す」みたいにできるようにスクリプトに書き換えた。
まぁ、自動レイアウトを駆使すれば同じことはできるかもしれないが、実は私も自動レイアウトは苦手なので、今回のスクリプト1つで簡単に実現できるのなら、それもアリかと(笑)。
・【Unity】uGUIの自動レイアウトが分かりにくいと評判なので解説してみる
(※) Unity 2018.4.8f1 / Windows10(x64) で確認
■テキストのサイズに合わせて他のオブジェクトのサイズも変化させる(サイズ制限付き)
●TextSizeSync.cs
using UnityEngine;
using UnityEngine.UI;
#if UNITY_EDITOR
using UnityEditor;
#endif
/// <summary>
/// https://gist.github.com/iwashihead/db6e88e7de74f43c43fb9ebbd6769516
/// を改造
/// Text の preferredWidth / preferredHeight に合わせて
/// 他の RectTransform のサイズも変更する.
/// </summary>
[ExecuteInEditMode]
//[ExecuteAlways]
public class TextSizeSync : MonoBehaviour
{
//サイズを調整する方向
public enum AdjustMode
{
Width, Height, Both,
}
public AdjustMode adjustMode = AdjustMode.Width;
public bool alwaysAdjust = false; //Update でテキスト変化を検出
public Text referenceText; //サイズを参照するテキスト
public float minWidth = -1; //調整する最小幅 (※負で無視)
public float maxWidth = -1; //調整する最大幅 (※負で無視)
public float minHeight = -1; //調整する最小高 (※負で無視)
public float maxHeight = -1; //調整する最大高 (※負で無視)
//同期させるオブジェクトの余白(テキストサイズ+余白になる)
public RectOffset padding = new RectOffset();
//サイズを同期させるオブジェクト
public RectTransform[] syncRectTransforms = new RectTransform[0];
//Editor only
private void Reset()
{
if (referenceText == null)
referenceText = GetComponent<Text>();
}
//Editor only
private void OnValidate()
{
Adjust();
}
private void OnEnable()
{
Adjust();
}
// Use this for initialization
private void Start()
{
Adjust();
}
// Update is called once per frame
private void LateUpdate()
{
if (alwaysAdjust && IsTextChanged)
Adjust();
}
string _oldText;
//テキストの内容が変化したか?
public bool IsTextChanged {
get {
if (referenceText == null)
return false;
if (_oldText == null || _oldText != referenceText.text)
{
_oldText = referenceText.text;
return true;
}
return false;
}
}
//サイズの調整
public void Adjust()
{
if (referenceText == null)
return;
switch (adjustMode)
{
case AdjustMode.Width:
AdjustWidth();
break;
case AdjustMode.Height:
AdjustHeight();
break;
case AdjustMode.Both:
AdjustBoth();
break;
}
AdjustSyncRectTransforms();
}
Vector2 _size = Vector2.zero;
//幅を調整
void AdjustWidth()
{
var w = ClampWidth(referenceText.preferredWidth);
var h = referenceText.rectTransform.sizeDelta.y;
_size.Set(w, h);
referenceText.rectTransform.sizeDelta = _size;
}
//高さを調整
void AdjustHeight()
{
var w = referenceText.rectTransform.sizeDelta.x;
var h = ClampHeight(referenceText.preferredHeight);
_size.Set(w, h);
referenceText.rectTransform.sizeDelta = _size;
}
//幅・高さの両方を調整
void AdjustBoth()
{
var w = ClampWidth(referenceText.preferredWidth);
var h = ClampHeight(referenceText.preferredHeight);
_size.Set(w, h);
referenceText.rectTransform.sizeDelta = _size;
}
//幅の制限
float ClampWidth(float w)
{
if (minWidth >= 0) w = Mathf.Max(minWidth, w);
if (maxWidth >= 0) w = Mathf.Min(maxWidth, w);
return w;
}
//高さの制限
float ClampHeight(float h)
{
if (minHeight >= 0) h = Mathf.Max(minHeight, h);
if (maxHeight >= 0) h = Mathf.Min(maxHeight, h);
return h;
}
//他の RectTransform のサイズ同期(余白付き)
void AdjustSyncRectTransforms()
{
var w = ClampWidth(referenceText.preferredWidth);
var h = ClampHeight(referenceText.preferredHeight);
foreach (var rt in syncRectTransforms)
{
var x = rt.sizeDelta.x;
var y = rt.sizeDelta.y;
switch (adjustMode)
{
case AdjustMode.Width:
x = padding.left + w + padding.right;
break;
case AdjustMode.Height:
y = padding.top + h + padding.bottom;
break;
case AdjustMode.Both:
x = padding.left + w + padding.right;
y = padding.top + h + padding.bottom;
break;
}
_size.Set(x, y);
rt.sizeDelta = _size;
}
}
}
#if UNITY_EDITOR
//※エディタ用
//OnValidate() では他のコンポーネント変化が検知できないので、
//インスペクタの更新で変化をチェックする
[CustomEditor(typeof(TextSizeSync))]
public class TextSizeSyncEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
var obj = target as TextSizeSync;
if (obj.IsTextChanged)
{
obj.Adjust();
}
}
}
#endif
色々付け加えたので長くなった(笑)。まぁ、少し古いバージョン(.NET3.5)でも対応できるようにしてるせいもあるけどね。
"[ExecuteInEditMode]" なんかもいつの間にか "[ExecuteAlways]" になったらしいしね。
使い方は、参照する Text と同じ GameObject にアタッチし、変化させたいオブジェクトを syncRectTransforms に登録するだけだ。あとは最小~最大サイズや余白を設定しておく。


ちなみに、gif アニメの ContetnSizeFitter と TextSizeAdjuster の設定は以下のようになる。

●ContentSizeFitter ① を使い、LayoutElement で MinWidth を設定


●ContentSizeFitter ② を使い、LayoutElement で MinWidth, PereferedWidth を設定


●TextSizeAdjuster と ContentSizeFitter を使う
・TextSizeAdjuster


まぁ、自動レイアウトを極めれば色々できるかも知れないが、とにかく組み合わせを考えるのが大変なので、何重にもレイアウトの入れ子になるくらいなら、簡単なスクリプトを作るのも1つの手かも知れない(笑)。
・【Unity】uGUIの自動レイアウトが分かりにくいと評判なので解説してみる
・【Unity】逆引き自動レイアウトのトレーニング。UIをLayoutGroupで並べる
・逆引き、UnityのuGUIのレイアウトトレーニング(uGUI RectTransform入門その2)
(関連記事)
【Unity】タブ切り替えの UI をコードを書かないで作る
【Unity】【C#】RectTransform の矩形の実座標を取得する
【Unity】【C#】uGUI ドロップダウンの要素をコードで設定と取得、外観のカスタマイズなど
【Unity】【C#】インスペクタの表示項目を動的に変更する
【Unity】【C#】独自のギズモ(Gizmo)を表示する
- 関連記事
-
-
【Unity】【C#】AssetBundleManager を WebGL で使う・エラー対処法
-
【Unity】【C#】Light の Halo はランタイム操作できない?
-
【Unity】【C#】Addressable Assets でキー(アドレス)の存在(登録)を調べる
-
【Unity】【C#】制限付きでテキストのサイズに合わせて他のオブジェクトのサイズも変化させる
-
【Unity】【C#】LINQとfor, ListとArray(配列)での実行速度を比較してみる
-
category: Unity
thread: ゲーム開発
janre: コンピュータ
tag: Unityライブラリ Unityリファレンス uGUI