Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9701

【Unity Editor拡張 with Odin】 Addressable AssetReferenceのプレビューを表示する

$
0
0

環境

Unity 2019.2.17f1
Addressable 1.5
Odin Inspector 2.1.8 (有料プラグイン)
odin.png

AssetReferenceって何を参照しているのか分かりにくい。。。

名前を設定している場合はまだ分かりやすいですが、フォルダを指定している場合フルパスが表示されるのでかなり分かり辛いです。それを有料プラグインのOdinを使って解決してみようと思います。

まずは Before / After

Before...
Addressable.gif
After !!!!
AddressableWithOdin.gif
だいぶ分かりやすくなりましたね。
Prefab名をクリックするとProject内のPrefabをハイライトしてくれます。

Code

OdinWithAddressableAssetReference.cs
usingSystem.Collections;usingSystem.Collections.Generic;usingSystem.Linq;usingUnityEngine;usingUnityEngine.AddressableAssets;usingSirenix.OdinInspector;#if UNITY_EDITOR
usingUnityEditor;usingUnityEditor.AddressableAssets;usingUnityEditor.AddressableAssets.Settings;#endif
[CreateAssetMenu(menuName="Sample/OdinWithAddressableAssetReference")]publicsealedclassOdinWithAddressableAssetReference:ScriptableObject{[SerializeField,HideInInspector]AssetReferenceGameObjectreferences;publicAssetReferenceGameObjectReferences=>references;#regionInspector#if UNITY_EDITOR
#pragma warning disable 0649
[SerializeField,ValueDropdown("ReferenceDropDownEditorOnly"),OnValueChanged("ReferenceValueChangedEditorOnly"),LabelText("References")]stringreferenceGuidEditorOnly;[ShowInInspector,ReadOnly,InlineEditor(InlineEditorModes.LargePreview),ShowIf("ReferencePreviewShowIfEditorOnly")]GameObjectPreviewOnEditor;[SerializeField,ValueDropdown("AssetGroupDropDownEditorOnly",IsUniqueList=true),LabelText("Addressable Group Filter")]string[]targetAssetGroupGuidsEditorOnly;#pragma warning restore 0649
IEnumerableReferenceDropDownEditorOnly(){returnGetAllAssetEntrys(targetAssetGroupGuidsEditorOnly).Select(x=>newValueDropdownItem(x.AssetPath,x.guid));}IEnumerableAssetGroupDropDownEditorOnly(){returnGetAllAssetGroups().Select(x=>newValueDropdownItem(x.Name,x.Guid));}voidReferenceValueChangedEditorOnly(stringguid){varentrys=GetAllAssetEntrys(targetAssetGroupGuidsEditorOnly);varitem=entrys.FirstOrDefault(x=>x.guid==guid);if(item!=default){references=newAssetReferenceGameObject(item.guid);UpdatePreviewAssetEditorOnly();}}boolReferencePreviewShowIfEditorOnly(){if(PreviewOnEditor==default){UpdatePreviewAssetEditorOnly();}returnPreviewOnEditor!=default;}voidUpdatePreviewAssetEditorOnly(){PreviewOnEditor=default;if(references.RuntimeKeyIsValid()){PreviewOnEditor=LoadAsset<GameObject>(references);}}/// <summary>/// アセットの取得/// </summary>/// <returns>The asset.</returns>/// <param name="reference">Reference.</param>/// <typeparam name="T">The 1st type parameter.</typeparam>publicstaticTLoadAsset<T>(AssetReferencereference)whereT:Object{returnreference.RuntimeKeyIsValid()?AssetDatabase.LoadAssetAtPath<T>(AssetDatabase.GUIDToAssetPath(reference.AssetGUID)):default;}/// <summary>/// グループ一覧を取得/// </summary>/// <returns>The asset groups.</returns>publicstaticList<AddressableAssetGroup>GetAllAssetGroups(){varsetting=AddressableAssetSettingsDefaultObject.GetSettings(false);vargropus=newList<AddressableAssetGroup>();if(setting!=default){gropus=setting.groups;}returngropus;}/// <summary>/// 全エントリーを取得/// </summary>/// <returns>The asset entrys editor only.</returns>/// <param name="groupFilterGuids">Group filter.</param>publicstaticList<AddressableAssetEntry>GetAllAssetEntrys(string[]groupFilterGuids=null){varsetting=AddressableAssetSettingsDefaultObject.GetSettings(false);varentrys=newList<AddressableAssetEntry>();if(setting!=default){foreach(vargroupinsetting.groups){if(groupFilterGuids!=null&&groupFilterGuids.Length>0&&!groupFilterGuids.Any(guid=>guid==group.Guid)){continue;}var_entrys=newList<AddressableAssetEntry>();group.GatherAllAssets(_entrys,false,true,false);entrys.AddRange(_entrys);}}returnentrys;}#endif
#endregion}

実装のポイント

AddressableAssetSettingsの取得方法が変わりました

OdinWithAddressableAssetReference.cs
varsetting=AddressableAssetSettingsDefaultObject.GetSettings(false);

プレビュー用GameObjectをシリアライズされないようにする

プレビューを表示するためのGameObjectがシリアライズされないようにprivateでShowInInspectorアトリビュートを使用しています。
publicにしたい場合は、[System.NonSerialized]を追加。

更に、プレビューは参照だけで使用されることが無いので#pragma warningでCS0649警告が表示されないようにしています。

OdinWithAddressableAssetReference.cs
[ShowInInspector,()]GameObjectPreviewOnEditor;

OdinでAddressableは非対応なのでGuidを保存する

Reference.png
ドロップダウンは実はテキストです(string referenceGuidEditorOnly)。
表示するリストを生成する際(ReferenceDropDownEditorOnly())、表示用のアセットパスと保存用のGuidをOdinのValueDropdownItemに代入しています。
そして、Guidに変更があった場合(ReferenceValueChangedEditorOnly(string guid))でプレビューを更新する仕様です。

OdinWithAddressableAssetReference.cs
[SerializeField,ValueDropdown("ReferenceDropDownEditorOnly"),OnValueChanged("ReferenceValueChangedEditorOnly"),LabelText("References")]stringreferenceGuidEditorOnly;IEnumerableReferenceDropDownEditorOnly(){returnGetAllAssetEntrys(targetAssetGroupGuidsEditorOnly).Select(x=>newValueDropdownItem(x.AssetPath,x.guid));}voidReferenceValueChangedEditorOnly(stringguid){varentrys=GetAllAssetEntrys(targetAssetGroupGuidsEditorOnly);varitem=entrys.FirstOrDefault(x=>x.guid==guid);if(item!=default){references=newAssetReferenceGameObject(item.guid);UpdatePreviewAssetEditorOnly();}}/// <summary>/// 全エントリーを取得/// </summary>/// <returns>The asset entrys editor only.</returns>/// <param name="groupFilterGuids">Group filter.</param>publicstaticList<AddressableAssetEntry>GetAllAssetEntrys(string[]groupFilterGuids=null){varsetting=AddressableAssetSettingsDefaultObject.GetSettings(false);varentrys=newList<AddressableAssetEntry>();if(setting!=default){foreach(vargroupinsetting.groups){if(groupFilterGuids!=null&&groupFilterGuids.Length>0&&!groupFilterGuids.Any(guid=>guid==group.Guid)){continue;}var_entrys=newList<AddressableAssetEntry>();group.GatherAllAssets(_entrys,false,true,false);entrys.AddRange(_entrys);}}returnentrys;}

グループフィルターに対応

Group.png
フィルタ機能もつけてみました。
ほんとはLabel用のフィルタ機能もつけたかったのですが、 LabelTableがprivateの為一覧取得ができず断念しました。


Viewing all articles
Browse latest Browse all 9701

Trending Articles