@@ -24,6 +24,7 @@ A package that brings data-binding to your Unity project.
2424- [ How To Use] ( #joystick-how-to-use )
2525 - [ Data-binding] ( #data-binding )
2626 - [ Create custom control] ( #create-custom-control )
27+ - [ Source code generator] ( #source-code-generator )
2728- [ External Assets] ( #link-external-assets )
2829 - [ UniTask] ( #unitask )
2930- [ Performance] ( #rocket-performance )
@@ -879,8 +880,6 @@ public class Image : VisualElement
879880 }
880881
881882 public new class UxmlFactory : UxmlFactory <Image , UxmlTraits > {}
882-
883- public new class UxmlTraits : VisualElement .UxmlTraits {}
884883}
885884```
886885
@@ -899,7 +898,7 @@ public class BindableImage : Image, IBindableElement
899898 _imagePathBindingData ??= BindingImagePath .ToPropertyBindingData ();
900899
901900 _imageProperty = objectProvider .RentReadOnlyProperty <Texture2D >(context , _imagePathBindingData );
902- _imageProperty .ValueChanged += OnImageValueChanged ;
901+ _imageProperty .ValueChanged += OnImagePropertyValueChanged ;
903902
904903 SetImage (_imageProperty .Value );
905904 }
@@ -911,7 +910,7 @@ public class BindableImage : Image, IBindableElement
911910 return ;
912911 }
913912
914- _imageProperty .ValueChanged -= OnImageValueChanged ;
913+ _imageProperty .ValueChanged -= OnImagePropertyValueChanged ;
915914
916915 objectProvider .ReturnReadOnlyProperty (_imageProperty );
917916
@@ -920,7 +919,7 @@ public class BindableImage : Image, IBindableElement
920919 SetImage (null );
921920 }
922921
923- private void OnImageValueChanged (object sender , Texture2D newImage )
922+ private void OnImagePropertyValueChanged (object sender , Texture2D newImage )
924923 {
925924 SetImage (newImage );
926925 }
@@ -961,6 +960,181 @@ public class ImageViewerViewModel : IBindingContext
961960</UXML >
962961```
963962
963+ ### Source code generator
964+
965+ The best way to speed up the creation of custom ` VisualElement ` is to use source code generators. With this powerful tool, you can achieve the same great results with minimal boilerplate code and focus on what really matters: programming!
966+
967+ Let's create the ` BindableImage ` control, but this time using source code generators.
968+
969+ For a visual element without bindings, we will use a [ UnityUxmlGenerator] ( https://github.com/LibraStack/UnityUxmlGenerator ) .
970+
971+ ``` csharp
972+ [UxmlElement ]
973+ public partial class Image : VisualElement
974+ {
975+ public void SetImage (Texture2D image )
976+ {
977+ style .backgroundImage = new StyleBackground (image );
978+ }
979+ }
980+ ```
981+
982+ <details ><summary ><b >Generated code</b ></summary >
983+ <br />
984+
985+ ` Image.UxmlFactory.g.cs `
986+
987+ ``` csharp
988+ partial class Image
989+ {
990+ [global ::System .CodeDom .Compiler .GeneratedCodeAttribute (" UnityUxmlGenerator" , " 1.0.0.0" )]
991+ public new class UxmlFactory : global ::UnityEngine .UIElements .UxmlFactory <Image , UxmlTraits >
992+ {
993+ }
994+ }
995+ ```
996+
997+ </details >
998+
999+ For a bindable visual element, we will use a [ UnityMvvmToolkit.Generator] ( https://github.com/LibraStack/UnityMvvmToolkit.Generator ) .
1000+
1001+ ``` csharp
1002+ [BindableElement ]
1003+ public partial class BindableImage : Image
1004+ {
1005+ [BindableProperty ]
1006+ private IReadOnlyProperty <Texture2D > _imageProperty ;
1007+
1008+ partial void AfterSetBindingContext (IBindingContext context , IObjectProvider objectProvider )
1009+ {
1010+ SetImage (_imageProperty ? .Value );
1011+ }
1012+
1013+ partial void AfterResetBindingContext (IObjectProvider objectProvider )
1014+ {
1015+ SetImage (null );
1016+ }
1017+
1018+ partial void OnImagePropertyValueChanged ([CanBeNull ] Texture2D value )
1019+ {
1020+ SetImage (value );
1021+ }
1022+ }
1023+ ```
1024+
1025+ <details ><summary ><b >Generated code</b ></summary >
1026+ <br />
1027+
1028+ ` BindableImage.Bindings.g.cs `
1029+
1030+ ``` csharp
1031+ partial class BindableImage : global ::UnityMvvmToolkit .Core .Interfaces .IBindableElement
1032+ {
1033+ [global ::System .CodeDom .Compiler .GeneratedCodeAttribute (" UnityMvvmToolkit.Generator" , " 1.0.0.0" )]
1034+ private global ::UnityMvvmToolkit .Core .PropertyBindingData ? _imageBindingData ;
1035+
1036+ [global ::System .CodeDom .Compiler .GeneratedCodeAttribute (" UnityMvvmToolkit.Generator" , " 1.0.0.0" )]
1037+ [global ::System .Diagnostics .CodeAnalysis .ExcludeFromCodeCoverage ]
1038+ public void SetBindingContext (global::UnityMvvmToolkit.Core.Interfaces.IBindingContext context ,
1039+ global::UnityMvvmToolkit.Core.Interfaces.IObjectProvider objectProvider )
1040+ {
1041+ BeforeSetBindingContext (context , objectProvider );
1042+
1043+ if (string .IsNullOrWhiteSpace (BindingImagePath ) == false )
1044+ {
1045+ _imageBindingData ??=
1046+ global :: UnityMvvmToolkit .Core .Extensions .StringExtensions .ToPropertyBindingData (BindingImagePath ! );
1047+ _imageProperty = objectProvider .RentReadOnlyProperty <global ::UnityEngine .Texture2D >(context , _imageBindingData ! );
1048+ _imageProperty ! .ValueChanged += OnImagePropertyValueChanged ;
1049+ }
1050+
1051+ AfterSetBindingContext (context , objectProvider );
1052+ }
1053+
1054+ [global ::System .CodeDom .Compiler .GeneratedCodeAttribute (" UnityMvvmToolkit.Generator" , " 1.0.0.0" )]
1055+ [global ::System .Diagnostics .CodeAnalysis .ExcludeFromCodeCoverage ]
1056+ public void ResetBindingContext (global::UnityMvvmToolkit.Core.Interfaces.IObjectProvider objectProvider )
1057+ {
1058+ BeforeResetBindingContext (objectProvider );
1059+
1060+ if (_imageProperty != null )
1061+ {
1062+ _imageProperty ! .ValueChanged -= OnImagePropertyValueChanged ;
1063+ objectProvider .ReturnReadOnlyProperty (_imageProperty );
1064+ _imageProperty = null ;
1065+ }
1066+
1067+ AfterResetBindingContext (objectProvider );
1068+ }
1069+
1070+ [global ::System .CodeDom .Compiler .GeneratedCodeAttribute (" UnityMvvmToolkit.Generator" , " 1.0.0.0" )]
1071+ [global ::System .Diagnostics .CodeAnalysis .ExcludeFromCodeCoverage ]
1072+ private void OnImagePropertyValueChanged (object sender , global::UnityEngine.Texture2D value )
1073+ {
1074+ OnImagePropertyValueChanged (value );
1075+ }
1076+
1077+ [global ::System .CodeDom .Compiler .GeneratedCodeAttribute (" UnityMvvmToolkit.Generator" , " 1.0.0.0" )]
1078+ partial void BeforeSetBindingContext (global::UnityMvvmToolkit.Core.Interfaces.IBindingContext context ,
1079+ global::UnityMvvmToolkit.Core.Interfaces.IObjectProvider objectProvider );
1080+
1081+ [global ::System .CodeDom .Compiler .GeneratedCodeAttribute (" UnityMvvmToolkit.Generator" , " 1.0.0.0" )]
1082+ partial void AfterSetBindingContext (global::UnityMvvmToolkit.Core.Interfaces.IBindingContext context ,
1083+ global::UnityMvvmToolkit.Core.Interfaces.IObjectProvider objectProvider );
1084+
1085+ [global ::System .CodeDom .Compiler .GeneratedCodeAttribute (" UnityMvvmToolkit.Generator" , " 1.0.0.0" )]
1086+ partial void BeforeResetBindingContext (global::UnityMvvmToolkit.Core.Interfaces.IObjectProvider objectProvider );
1087+
1088+ [global ::System .CodeDom .Compiler .GeneratedCodeAttribute (" UnityMvvmToolkit.Generator" , " 1.0.0.0" )]
1089+ partial void AfterResetBindingContext (global::UnityMvvmToolkit.Core.Interfaces.IObjectProvider objectProvider );
1090+
1091+ [global ::System .CodeDom .Compiler .GeneratedCodeAttribute (" UnityMvvmToolkit.Generator" , " 1.0.0.0" )]
1092+ partial void OnImagePropertyValueChanged (global::UnityEngine.Texture2D value );
1093+ }
1094+ ```
1095+
1096+ ` BindableImage.Uxml.g.cs `
1097+
1098+ ``` csharp
1099+ partial class BindableImage
1100+ {
1101+ [global ::System .CodeDom .Compiler .GeneratedCodeAttribute (" UnityMvvmToolkit.Generator" , " 1.0.0.0" )]
1102+ [global ::System .Diagnostics .CodeAnalysis .ExcludeFromCodeCoverage ]
1103+ private string BindingImagePath { get ; set ; }
1104+
1105+ [global ::System .CodeDom .Compiler .GeneratedCodeAttribute (" UnityMvvmToolkit.Generator" , " 1.0.0.0" )]
1106+ public new class UxmlFactory : global ::UnityEngine .UIElements .UxmlFactory <BindableImage , UxmlTraits >
1107+ {
1108+ }
1109+
1110+ [global ::System .CodeDom .Compiler .GeneratedCodeAttribute (" UnityMvvmToolkit.Generator" , " 1.0.0.0" )]
1111+ public new class UxmlTraits : global ::BindableUIElements .Image .UxmlTraits
1112+ {
1113+ [global ::System .CodeDom .Compiler .GeneratedCodeAttribute (" UnityMvvmToolkit.Generator" , " 1.0.0.0" )]
1114+ private readonly global::UnityEngine.UIElements.UxmlStringAttributeDescription _bindingImagePath = new ()
1115+ { name = " binding-image-path" , defaultValue = " " };
1116+
1117+ [global ::System .CodeDom .Compiler .GeneratedCodeAttribute (" UnityMvvmToolkit.Generator" , " 1.0.0.0" )]
1118+ [global ::System .Diagnostics .CodeAnalysis .ExcludeFromCodeCoverage ]
1119+ public override void Init (global::UnityEngine.UIElements.VisualElement visualElement ,
1120+ global::UnityEngine.UIElements.IUxmlAttributes bag ,
1121+ global::UnityEngine.UIElements.CreationContext context )
1122+ {
1123+ base .Init (visualElement , bag , context );
1124+
1125+ var control = (BindableImage ) visualElement ;
1126+ control .BindingImagePath = _bindingImagePath .GetValueFromBag (bag , context );
1127+ }
1128+ }
1129+ }
1130+ ```
1131+
1132+ </details >
1133+
1134+ As you can see, using [ UnityUxmlGenerator] ( https://github.com/LibraStack/UnityUxmlGenerator ) and [ UnityMvvmToolkit.Generator] ( https://github.com/LibraStack/UnityMvvmToolkit.Generator ) we can achieve the same results but with just a few lines of code.
1135+
1136+ > ** Note:** The [ UnityMvvmToolkit.Generator] ( https://github.com/LibraStack/UnityMvvmToolkit.Generator ) is available exclusively for my [ patrons] ( https://patreon.com/DimaChebanov ) .
1137+
9641138## :link : External Assets
9651139
9661140### UniTask
0 commit comments