-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
- Loading branch information
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using UnityEditor; | ||
using UnityEngine; | ||
using UnityEngine.AddressableAssets; | ||
using UnityEngine.ResourceManagement.AsyncOperations; | ||
using Object = UnityEngine.Object; | ||
|
||
namespace PiRhoSoft.Utilities.Editor | ||
{ | ||
public class AssetPickerControl : BasePickerControl<AssetReference>, IDragReceiver | ||
{ | ||
private class AssetProvider : PickerProvider<AssetReference> { } | ||
|
||
private const string _invalidTypeWarning = "(PUAPCIT) Invalid type for AssetPickerControl: the type '{0}' must be derived from UnityEngine.Object"; | ||
|
||
public new const string Stylesheet = "Picker/AssetPicker/AssetPickerStyle.uss"; | ||
public new const string UssClassName = "pirho-asset-picker"; | ||
|
||
public Type Type { get; private set; } | ||
|
||
public AssetPickerControl(AssetReference value, Type type, string tag) : this(value, type, tag, null, Addressables.MergeMode.None) | ||
{ | ||
} | ||
|
||
public AssetPickerControl(AssetReference value, Type type, string[] tags, Addressables.MergeMode mode) : this(value, type, null, tags, mode) | ||
{ | ||
} | ||
|
||
private AssetPickerControl(AssetReference value, Type type, string tag, string[] tags, Addressables.MergeMode mode) | ||
{ | ||
if (type != null && !(typeof(Object).IsAssignableFrom(type))) | ||
{ | ||
Debug.LogWarningFormat(_invalidTypeWarning, type); | ||
return; | ||
} | ||
|
||
Type = type; | ||
|
||
var provider = ScriptableObject.CreateInstance<AssetProvider>(); | ||
var paths = new List<string> { "None" }; | ||
var assets = new List<AssetReference> { null }; | ||
|
||
var loader = tags == null ? Addressables.LoadResourceLocationsAsync(tag, type) : Addressables.LoadResourceLocationsAsync(tags, mode, type); | ||
loader.Completed += handle => | ||
{ | ||
if (handle.Status == AsyncOperationStatus.Succeeded) | ||
{ | ||
foreach (var result in handle.Result) | ||
{ | ||
paths.Add(result.PrimaryKey); | ||
assets.Add(new AssetReference(result.ProviderId)); | ||
} | ||
|
||
provider.Setup(type?.Name ?? "Addressable Asset", paths, assets, GetIcon, OnSelected); | ||
} | ||
}; | ||
|
||
Setup(provider, value); | ||
|
||
this.MakeDragReceiver(); | ||
this.AddStyleSheet(Configuration.ElementsPath, Stylesheet); | ||
AddToClassList(UssClassName); | ||
} | ||
|
||
private Texture GetIcon(AssetReference asset) | ||
{ | ||
return asset != null && asset.editorAsset ? AssetPreview.GetMiniTypeThumbnail(asset.editorAsset.GetType()) : null; | ||
} | ||
|
||
private void OnSelected(AssetReference selected) | ||
{ | ||
var previous = Value; | ||
|
||
SetValueWithoutNotify(selected); | ||
this.SendChangeEvent(previous, Value); | ||
} | ||
|
||
protected override void Refresh() | ||
{ | ||
var text = Value == null ? Value.editorAsset.name : $"None ({Type?.Name ?? "Asset"})"; | ||
var icon = GetIcon(Value); | ||
|
||
SetLabel(icon, text); | ||
} | ||
|
||
#region IDragReceiver Implementation | ||
|
||
public bool IsDragValid(Object[] objects, object data) | ||
{ | ||
//if (objects.Length > 0) | ||
//{ | ||
// var obj = objects[0]; | ||
// if (obj != null) | ||
// { | ||
// var drag = obj.GetType(); | ||
// return Type.IsAssignableFrom(drag); | ||
// } | ||
//} | ||
|
||
return false; | ||
} | ||
|
||
public void AcceptDrag(Object[] objects, object data) | ||
{ | ||
//OnSelected(new AssetReference(AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(objects[0])))); | ||
} | ||
|
||
#endregion | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
using UnityEditor; | ||
using UnityEngine; | ||
using UnityEngine.AddressableAssets; | ||
using UnityEngine.UIElements; | ||
|
||
namespace PiRhoSoft.Utilities.Editor | ||
{ | ||
[CustomPropertyDrawer(typeof(AssetPickerAttribute))] | ||
public class AssetPickerDrawer : PropertyDrawer | ||
{ | ||
private const string _invalidTypeWarning = "(PUAPDIT) invalid type for AssetPickerAttribute on field {0}: AssetPicker can only be applied to an AssetReference"; | ||
|
||
public override VisualElement CreatePropertyGUI(SerializedProperty property) | ||
{ | ||
var assetAttribute = attribute as AssetPickerAttribute; | ||
|
||
if (this.GetFieldType() == typeof(AssetReference)) | ||
return assetAttribute.Tags == null ? new AssetPickerField(property, assetAttribute.Type, assetAttribute.Tag) : new AssetPickerField(property, assetAttribute.Type, assetAttribute.Tags, assetAttribute.Mode); | ||
else | ||
Debug.LogWarningFormat(_invalidTypeWarning, property.propertyPath); | ||
|
||
return new FieldContainer(property.displayName); | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
using System; | ||
using UnityEditor; | ||
using UnityEngine.AddressableAssets; | ||
using UnityEngine.UIElements; | ||
|
||
namespace PiRhoSoft.Utilities.Editor | ||
{ | ||
public class AssetPickerField : BaseField<AssetReference> | ||
{ | ||
public const string UssClassName = "pirho-scene-picker-field"; | ||
public const string LabelUssClassName = UssClassName + "__label"; | ||
public const string InputUssClassName = UssClassName + "__input"; | ||
|
||
public AssetPickerControl Control { get; private set; } | ||
|
||
public AssetPickerField(SerializedProperty property, Type type, string tag = null) : this(property.displayName, property.GetObject<AssetReference>(), type, tag) | ||
{ | ||
this.ConfigureProperty(property); | ||
} | ||
|
||
public AssetPickerField(SerializedProperty property, Type type, string[] tags, Addressables.MergeMode mode) : this(property.displayName, property.GetObject<AssetReference>(), type, tags, mode) | ||
{ | ||
this.ConfigureProperty(property); | ||
} | ||
|
||
public AssetPickerField(string label, AssetReference value, Type type, string tag = null) : base(label, null) | ||
{ | ||
Setup(value, type, tag, null, Addressables.MergeMode.None); | ||
} | ||
|
||
public AssetPickerField(string label, AssetReference value, Type type, string[] tags, Addressables.MergeMode mode) : base(label, null) | ||
{ | ||
Setup(value, type, null, tags, mode); | ||
} | ||
|
||
private void Setup(AssetReference value, Type type, string tag, string[] tags, Addressables.MergeMode mode) | ||
{ | ||
Control = tags == null ? new AssetPickerControl(value, type, tag) : new AssetPickerControl(value, type, tags, mode); | ||
Control.AddToClassList(InputUssClassName); | ||
Control.RegisterCallback<ChangeEvent<AssetReference>>(evt => base.value = evt.newValue); | ||
|
||
labelElement.AddToClassList(LabelUssClassName); | ||
|
||
this.SetVisualInput(Control); | ||
AddToClassList(UssClassName); | ||
SetValueWithoutNotify(value); | ||
} | ||
|
||
public override void SetValueWithoutNotify(AssetReference newValue) | ||
{ | ||
base.SetValueWithoutNotify(newValue); | ||
Control.SetValueWithoutNotify(newValue); | ||
} | ||
|
||
#region UXML Support | ||
|
||
public AssetPickerField() : base(null, null) { } | ||
|
||
public new class UxmlFactory : UxmlFactory<ScenePickerField, UxmlTraits> { } | ||
|
||
public new class UxmlTraits : BaseField<string>.UxmlTraits | ||
{ | ||
private UxmlStringAttributeDescription _path = new UxmlStringAttributeDescription { name = "path" }; | ||
|
||
public override void Init(VisualElement element, IUxmlAttributes bag, CreationContext cc) | ||
{ | ||
base.Init(element, bag, cc); | ||
|
||
var field = element as AssetPickerField; | ||
var path = _path.GetValueFromBag(bag, cc); | ||
var guid = AssetDatabase.AssetPathToGUID(path); | ||
|
||
field.Setup(new AssetReference(guid), null, null, null, Addressables.MergeMode.None); | ||
} | ||
} | ||
|
||
#endregion | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
.pirho-asset-picker | ||
{ | ||
} | ||
|
||
.pirho-asset-picker__load | ||
{ | ||
min-width: 17px; | ||
max-width: 17px; | ||
min-height: 15px; | ||
max-height: 15px; | ||
margin-left: 2px; | ||
} | ||
|
||
.pirho-asset-picker__create | ||
{ | ||
margin-left: 2px; | ||
margin-bottom: 2px; | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
using System; | ||
using UnityEngine.AddressableAssets; | ||
|
||
namespace PiRhoSoft.Utilities | ||
{ | ||
public class AssetPickerAttribute : PropertyTraitAttribute | ||
{ | ||
public Type Type { get; private set; } | ||
public string Tag { get; private set; } | ||
public string[] Tags { get; private set; } | ||
public Addressables.MergeMode Mode { get; private set; } | ||
|
||
public AssetPickerAttribute() : base(FieldPhase, 0) | ||
{ | ||
} | ||
|
||
public AssetPickerAttribute(Type type) : this() | ||
{ | ||
Type = type; | ||
} | ||
|
||
public AssetPickerAttribute(string tag, Type type = null) : this(type) | ||
{ | ||
Tag = tag; | ||
} | ||
|
||
public AssetPickerAttribute(string[] tags, Type type = null, Addressables.MergeMode mode = Addressables.MergeMode.Intersection) : this(type) | ||
{ | ||
Tags = tags; | ||
Mode = mode; | ||
} | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.