Last active
March 16, 2025 08:06
-
-
Save karljj1/8d57394a18b67bac62e7f359ab554503 to your computer and use it in GitHub Desktop.
Example of a UI Toolkit custom binding for Addressables (2023.3)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using UnityEngine.AddressableAssets; | |
using UnityEngine.ResourceManagement.AsyncOperations; | |
using UnityEngine.UIElements; | |
#if UNITY_EDITOR | |
public class AssetReferenceConverter<T> : UnityEditor.UIElements.UxmlAttributeConverter<AssetReferenceT<T>> where T : Object | |
{ | |
public override AssetReferenceT<T> FromString(string value) | |
{ | |
var split = value.Split('#'); | |
return new AssetReferenceT<T>(split[0]){ SubObjectName = split[1] }; | |
} | |
public override string ToString(AssetReferenceT<T> value) | |
{ | |
return $"{value.AssetGUID}#{value.SubObjectName}"; | |
} | |
} | |
#endif | |
// Our concrete class for Texture2D | |
[UxmlObject] | |
public partial class Texure2DAddressablesBinding : AddressablesBinding<Texture2D> | |
{ } | |
[UxmlObject] | |
public partial class SpriteAddressablesBinding : AddressablesBinding<Sprite> | |
{ } | |
// Our generic class for any Object. A concrete class is needed for each to be used in UXML. | |
[UxmlObject] | |
public partial class AddressablesBinding<T> : CustomBinding where T: Object | |
{ | |
[UxmlAttribute] | |
public AssetReferenceT<T> AssetReference { get; set; } | |
[UxmlAttribute] | |
public bool Synchronous { get; set; } | |
public AddressablesBinding() | |
{ | |
updateTrigger = BindingUpdateTrigger.WhenDirty; | |
} | |
protected override void OnDeactivated(in BindingActivationContext context) | |
{ | |
if (AssetReference.OperationHandle.IsValid()) | |
AssetReference.ReleaseAsset(); | |
base.OnDeactivated(context); | |
} | |
protected override BindingResult Update(in BindingContext context) | |
{ | |
if (!AssetReference.OperationHandle.IsValid()) | |
{ | |
AssetReference.LoadAssetAsync<T>(); | |
if (!AssetReference.OperationHandle.IsDone && Synchronous) | |
AssetReference.OperationHandle.WaitForCompletion(); | |
} | |
if (!AssetReference.OperationHandle.IsDone) | |
return new BindingResult(BindingStatus.Pending); | |
if (AssetReference.OperationHandle.Status == AsyncOperationStatus.Failed) | |
return new BindingResult(BindingStatus.Failure, AssetReference.OperationHandle.OperationException?.ToString()); | |
var element = context.targetElement; | |
if (ConverterGroups.TrySetValueGlobal(ref element, context.bindingId, AssetReference.OperationHandle.Result as T, out var errorCode)) | |
return new BindingResult(BindingStatus.Success); | |
else | |
return new BindingResult(BindingStatus.Failure, errorCode.ToString()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment