[RELEASED] Binding System

Hello everyone,
I present you my first asset Binding System.
This plugin allows binding of almost any type directly in the Inspector. It uses a complex system underneath to make the binding as performant as possible (in some cases it is as fast as setting the value directly), and another drawing system to make the binding as easy as possible in the Inspector. The binding can be done in code as well, for those who prefer it.

Here is a quick animation which shows how it works in the Inspector.

To have a bindable field, it is enough to make it Bind<T> where T is the type of the field. Another system will pick the type change and will allow the user to transfer the serialized data to the bindable field.

Each bindable field can be altered through the use of converters and modifiers before returning the value to the user. This way, this system can be introduced for already developed components, without needing to reset the values from scratch.

The system is fully extensible and anyone can evolve it to their needs. There are multiple automatic processes in place to register new modifiers, new converters and new data providers (another more advanced concept) without requiring user intervention.

Here is a longer video showcasing the asset.

Documentation: Binding System - Documentation

Asset Store: https://assetstore.unity.com/packages/slug/261130

Roadmap: Binding System | Trello

Let me know what are your thoughts about this system…

9488026--1335175--BindingSystem01.gif

1 Like

Hey @Geeorge Thanks for Binding System. It was recommended on a @CodeMonkeyYT video - I’m sure you’re aware - so I bought it just now and it looks really useful.

One thing though, I’m getting constant errors now every time my code compiles:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ArgumentNullException: Value cannot be null.
Parameter name: obj
  at (wrapper managed-to-native) UnityEditor.PrefabUtility.GetCorrespondingObjectFromSource_internal(UnityEngine.Object)
  at UnityEditor.PrefabUtility.GetCorrespondingObjectFromSource[TObject] (TObject componentOrGameObject) [0x00001] in /Users/bokken/build/output/unity/unity/Editor/Mono/Prefabs/PrefabUtility.cs:2417
  at Postica.BindingSystem.Serialization.BindDatabase.TryCreatePrefabFile (System.String guid, Postica.BindingSystem.Serialization.BindDatabase+PrefabFile& prefabFile, System.Collections.Generic.HashSet`1[T] dependencies) [0x00049] in <3ce57564425c429abe18352a6410c920>:0
  at Postica.BindingSystem.Serialization.BindDatabase.BuildPrefabFile (System.String guid, System.Collections.Generic.HashSet`1[T] dependencies) [0x00000] in <3ce57564425c429abe18352a6410c920>:0
  at Postica.BindingSystem.Serialization.BindDatabase.RebuildPrefabs () [0x00065] in <3ce57564425c429abe18352a6410c920>:0
  at (wrapper managed-to-native) System.Reflection.RuntimeMethodInfo.InternalInvoke(System.Reflection.RuntimeMethodInfo,object,object[],System.Exception&)
  at System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x0006a] in <2ccb053bed3740ab940e67afec38ab31>:0
   --- End of inner exception stack trace ---
  at System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00083] in <2ccb053bed3740ab940e67afec38ab31>:0
  at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in <2ccb053bed3740ab940e67afec38ab31>:0
  at UnityEditor.EditorAssemblies.ProcessInitializeOnLoadMethodAttributes () [0x000a5] in /Users/bokken/build/output/unity/unity/Editor/Mono/EditorAssemblies.cs:145
UnityEditor.EditorAssemblies:ProcessInitializeOnLoadMethodAttributes () (at /Users/bokken/build/output/unity/unity/Editor/Mono/EditorAssemblies.cs:149)

Hi @Colin_MacLeod , thanks for letting me know about the recommendation and thank you for purchasing the tool and letting me know about this issue. Will try to investigate and provide a fix with the next update.
It would be really helpful if you could provide some additional context, like which version of Unity you’re using.

2022.3.15f1 with URP on macOS 14.0, Apple Silicon M2.

The error may be specific to my project. I’ve had to remove Binding System from my project until it is sorted, and I’d very much like to help you find a solution. Let me know if you can give me a version with added debugging.

I created a blank URP project and imported your asset. I didn’t see that error, but this one appears as soon as I import:

Unloading broken assembly Assets/BindingSystem/Editor/Burst/BindingSystem.Editor.dll, this assembly can cause crashes in the runtime

This is reproducible. It happens every time I delete and re-import the asset from the package manager.

Steps to reproduce on Unity 2022.3.16f1:

  1. Open Unity Hub
  2. Download the 3D URP template, if you don’t have it
  3. Create a new project using the 3D URP Template
  4. Import Binding System from the asset store

Here’s the Code Monkey link, in case you didn’t see it:
https://www.youtube.com/watch?v=Rcn-PUJlIuQ

Great, thank you for all this info, will upload a fix later this week.

On a side note, I am considering adding a logic to essentially allow having any field as bindable without touching a line of code (even for Unity built-in components). This will have some limitations, mostly the synchronization will happen at fixed points in player update loop, instead of being immediately propagated, but still, for most cases I think will be more than enough.

I would like to know your thoughts about this idea.

Great - were you able to reproduce the effect? What about my original issue? Can you please share a version with debugging so we can track it down? Right now, I can’t include the asset in my project because of all the noise it generates.

Sounds intriguing. Assuming minimal impact on performance, I’d certainly be interested.

My use case is scriptable objects to record shared information. I was hoping Binding System would let me arbitrarily bind various bools, ints, floats, and strings to these shared objects.

For example, I have a bool on almost all behaviors to enable/disable logging. It would be nice to be able to bind all of those bools to a single Debug value on a shared scriptable object in the project, so I can disable trace logging from one place. Or, maybe a group of similar objects could be tied to one bool to enable logging on just that one group.

I’d also love to be able to still use the inspector attributes such as Range - and even the Sirenix Odin Inspector attributes.

I was able to reproduce the dll issue, but it is not an issue. It shows the error because it requires an additional compilation to apply the correct define symbols. For your issue, I have added some additional safety checks which should help you out with your issue. The new version should be hopefully available till the end of this week.

This looks like a perfect fit for BInding System. Let me know if there are more specific things on your mind so I can adjust the system accordingly.

This is already possible with the version you’re having. Just add the [Bind] attribute over other attributes and it will push the inner value to other attributes.

[Bind]
[Range(0, 1)]
public Bind<float> myFloat;

Binding System already supports Sirenix Odin Inspector, although with some small limitations. There are some Sirenix attributes (such as AssetOnly) which are propagated to the bound value.

1 Like

That’s very clever. I’ve been using this scriptable object approach for some time, though with a more primitive reference class (e.g. IntReference) in place of the primitive, so it can be bound later. The disadvantage of that approach was always the loss of the Sirenix Odin inspector enhancements - particularly range sliders.

I’m looking forward to trying it again with the new version!

Hi @Geeorge , how’s it looking with the new release?

Hi @Colin_MacLeod , sorry for the delayed response. The new version has been submitted (1.0.2), it should be available in around 2-3 business days.

1 Like

The new version 1.0.2 is available on Asset Store. It fixes the install issues found in projects with Burst Compiler (hence the URP issue, thanks @Colin_MacLeod ) and occasional fail of AutoConversion logic.
For the Burst compiler issue, it is advisable to remove BindingSystem assemblies found in Library->Script Assemblies, otherwise Unity may continue showing the same error.

1 Like

@Geeorge I installed version 1.0.2, but for my game, it generates a lot of error messages in Unity Editor.
Shutting down Unity, deleting the Library folder, and restarting Unity does not resolve.

This was on Unity 2022.3.17f1 running on macOS 14.2.1 on Apple Silicon.

These are recurring errors:

Library/PackageCache/com.unity.collections@2.1.4/Unity.Collections.CodeGen/CecilExtensionMethods.cs(9,31): error CS0234: The type or namespace name 'Cil' does not exist in the namespace 'Mono.Cecil' (are you missing an assembly reference?)
Library/PackageCache/com.unity.collections@2.1.4/Unity.Collections.CodeGen/JobReflectionDataPostProcessor.cs(11,37): error CS0234: The type or namespace name 'MethodAttributes' does not exist in the namespace 'Mono.Cecil' (are you missing an assembly reference?)
Library/PackageCache/com.unity.collections@2.1.4/Unity.Collections.CodeGen/JobReflectionDataPostProcessor.cs(13,35): error CS0234: The type or namespace name 'TypeAttributes' does not exist in the namespace 'Mono.Cecil' (are you missing an assembly reference?)

Deleting the Assets/BindingSystem folder removes the errors.

Thank you @Colin_MacLeod for pointing to this issue. Apparently Collections and other Unity packages depend on the same library the Binding System is using (albeit with a different version).

I have just re-published a new version (1.0.3) which should be available early next week and should fix all assembly clashing issues.

1 Like

Thanks, @Geeorge . I’ll check it out.

Hi everyone, the version 1.0.3 is now live on Asset Store.

@Colin_MacLeod could you please let me know if the issues you’re facing have been addressed?

@Geeorge I installed it from the asset store just now, after which Unity crashed.
Started it up again → crash before the editor was shown. Nothing obvious in Editor.log. Here’s the tail:

- Loaded All Assemblies, in  0.761 seconds
Refreshing native plugins compatible for Editor in 3.86 ms, found 4 plugins.
Preloading 0 native plugins for Editor in 0.00 ms.
Refreshing native plugins compatible for Editor in 5.51 ms, found 4 plugins.
Native extension for WindowsStandalone target not found
Native extension for OSXStandalone target not found
Assembly reference Packages/com.unity.entities/Unity.Scenes.Editor/Internals/Properties/Unity.Properties.Internals.asmref has no target assembly definition
TypeManager.Initialize took: 538ms
Launching external process: /Applications/Unity/Hub/Editor/2022.3.17f1/Unity.app/Contents/Tools/UnityShaderCompiler
Launched and connected shader compiler UnityShaderCompiler after 0.04 seconds
Mono: successfully reloaded assembly
info: Microsoft.Hosting.Lifetime[0]
      Application is shutting down...
info: Unity.ILPP.Runner.PostProcessingAssemblyLoadContext[0]
      ALC ILPP context 1 is unloading

Deleted Library & started again → still crashing.
Deleted Assets/BindingSystem & started again → looks OK (currently still starting up)

Unity 2023.3.17f1 on macOS 14.2.1 (Apple Silicon/M2 Pro).

Would you like to access my git repo to try to see if you can reproduce?

1 Like

@Colin_MacLeod I tried with a similar setup, but no issues were detected.

That would be very helpful. My github account is GeeorgePostica.

I shared the details in a private forum conversation just now. Really hoping we can get to the bottom of it!

Hi everyone,
The version 1.0.4 is already available on Asset Store, it brings a couple of bug fixes (thanks @Colin_MacLeod ) and improves the splash screen experience.

@Geeorge , I’m still seeing anomalies. There were a number of errors when I imported BindingSystem into the project. I didn’t capture those.

Unity 2023.3.18f1 on macOS 14.2.1 (Apple Silicon/M2 Pro).

This error is re-appearing when the scripts recompile:

NullReferenceException: Object reference not set to an instance of an object
Postica.BindingSystem.Serialization.BindDatabase.IsValidScriptableObjectType (System.Type t) (at <e550877f6be34210ae5744868d0448d7>:0)
Postica.BindingSystem.Serialization.BindDatabase+<>c.<GetAllScriptedTypes>b__38_0 (System.Type t) (at <e550877f6be34210ae5744868d0448d7>:0)
System.Linq.Enumerable+WhereEnumerableIterator`1[TSource].MoveNext () (at <2bcf4fe59a1e4290a8c851a306d34b0f>:0)
System.Linq.Enumerable+ConcatIterator`1[TSource].MoveNext () (at <2bcf4fe59a1e4290a8c851a306d34b0f>:0)
System.Linq.Enumerable+SelectEnumerableIterator`2[TSource,TResult].MoveNext () (at <2bcf4fe59a1e4290a8c851a306d34b0f>:0)
System.Linq.Enumerable.Contains[TSource] (System.Collections.Generic.IEnumerable`1[T] source, TSource value, System.Collections.Generic.IEqualityComparer`1[T] comparer) (at <2bcf4fe59a1e4290a8c851a306d34b0f>:0)
System.Linq.Enumerable.Contains[TSource] (System.Collections.Generic.IEnumerable`1[T] source, TSource value) (at <2bcf4fe59a1e4290a8c851a306d34b0f>:0)
Postica.BindingSystem.Serialization.BindDatabase.GetAllScriptedTypes () (at <e550877f6be34210ae5744868d0448d7>:0)
Postica.BindingSystem.Serialization.BindDatabase.BuildDatabase () (at <e550877f6be34210ae5744868d0448d7>:0)
Postica.BindingSystem.Serialization.BindDatabase.RebuildTree () (at <e550877f6be34210ae5744868d0448d7>:0)
Postica.BindingSystem.Serialization.BindDatabase.get_Database () (at <e550877f6be34210ae5744868d0448d7>:0)
Postica.BindingSystem.Serialization.Reserializer.OnPostprocessAllAssets (System.String[] importedAssets, System.String[] deletedAssets, System.String[] movedAssets, System.String[] movedFromAssetPaths, System.Boolean didDomainReload) (at <e550877f6be34210ae5744868d0448d7>:0)
System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <fd2d3e9b010a4ba4b3fdc0456cd6b40b>:0)
Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <fd2d3e9b010a4ba4b3fdc0456cd6b40b>:0)
System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) (at <fd2d3e9b010a4ba4b3fdc0456cd6b40b>:0)
UnityEditor.AssetPostprocessingInternal.InvokeMethod (System.Reflection.MethodInfo method, System.Object[] args) (at /Users/bokken/build/output/unity/unity/Editor/Mono/AssetPostprocessor.cs:1168)
UnityEditor.AssetPostprocessingInternal.PostprocessAllAssets (System.String[] importedAssets, System.String[] addedAssets, System.String[] deletedAssets, System.String[] movedAssets, System.String[] movedFromPathAssets, System.Boolean didDomainReload) (at /Users/bokken/build/output/unity/unity/Editor/Mono/AssetPostprocessor.cs:395)
UnityEditor.AssetPostprocessingInternal:PostprocessAllAssets(String[], String[], String[], String[], String[], Boolean) (at /Users/bokken/build/output/unity/unity/Editor/Mono/AssetPostprocessor.cs:408)

Also:

Exception thrown while invoking [DidReloadScripts] method 'Postica.BindingSystem.Serialization.BindDatabase:RebuildTree ()' : NullReferenceException: Object reference not set to an instance of an object
Postica.BindingSystem.Serialization.BindDatabase.IsValidScriptableObjectType (System.Type t) (at <e550877f6be34210ae5744868d0448d7>:0)
Postica.BindingSystem.Serialization.BindDatabase+<>c.<GetAllScriptedTypes>b__38_0 (System.Type t) (at <e550877f6be34210ae5744868d0448d7>:0)
System.Linq.Enumerable+WhereEnumerableIterator`1[TSource].MoveNext () (at <2bcf4fe59a1e4290a8c851a306d34b0f>:0)
System.Linq.Enumerable+ConcatIterator`1[TSource].MoveNext () (at <2bcf4fe59a1e4290a8c851a306d34b0f>:0)
System.Linq.Enumerable+SelectEnumerableIterator`2[TSource,TResult].MoveNext () (at <2bcf4fe59a1e4290a8c851a306d34b0f>:0)
System.Linq.Enumerable.Contains[TSource] (System.Collections.Generic.IEnumerable`1[T] source, TSource value, System.Collections.Generic.IEqualityComparer`1[T] comparer) (at <2bcf4fe59a1e4290a8c851a306d34b0f>:0)
System.Linq.Enumerable.Contains[TSource] (System.Collections.Generic.IEnumerable`1[T] source, TSource value) (at <2bcf4fe59a1e4290a8c851a306d34b0f>:0)
Postica.BindingSystem.Serialization.BindDatabase.GetAllScriptedTypes () (at <e550877f6be34210ae5744868d0448d7>:0)
Postica.BindingSystem.Serialization.BindDatabase.BuildDatabase () (at <e550877f6be34210ae5744868d0448d7>:0)
Postica.BindingSystem.Serialization.BindDatabase.RebuildTree () (at <e550877f6be34210ae5744868d0448d7>:0)