Skip to content

FAQs and Known Issues

Dr Luke Thompson edited this page Oct 20, 2018 · 8 revisions

This list will grow and evolve, and hopefully then shrink as tutorials are added which should explain many of the FAQs as you go.

How do I bind and unbind listeners in code?

SmartData uses our custom events implementation Relay (github). This is a replacement for using C#'s event keyword.

As with any events system, it's critical to clear listeners at end-of-life to not "leak" memory (Wikipedia).

SmartRefs (e.g. FloatWriter, StringReader) allow adding listeners in code using the method BindListener. This adds a listener and returns a Sigtrap.Relay.IRelayBinding object. Store this in a member field, then at end-of-life call its Enable(false) method to remove the listener.

This is the main recommended way to handle events in code, for a few reasons. Firstly, since you have the binding object you'll hopefully be more likely to remember to disable it at end-of-life. Secondly, it allows easy use of lambdas/anonymous methods - rather than having to find a way to manually remove the lamdba by rewriting it or storing it as a delegate, you just need to disabled the IRelayBinding.

However, you can also get the underlying Relay object from the SmartRef (e.g. FloatReader.relay) and use the methods AddListener and RemoveListener, amongst other advanced features, if you prefer.

Do changes to a SmartObjects value persist between sessions?

Simple answer - no.

Longer answer:
First let's define "sessions". This means one of three things.

  1. Hitting Play in-editor
  2. Exiting playmode in-editor
  3. Running a built standalone app/game

In case 3, changes never persist. I.e. if you close the app and launch again, all values will be at their defaults. ScriptableObjects do not get modified on disk in builds.
Note that changes will persist across level loads unless you tick Reset On Scene Load in the SmartObject's inspector.

In cases 1 and 2, usually changes will not persist. When Play mode starts, SmartObjects make a runtime copy of the data, and this is what's being changed. Out of Play mode, by changing the value in the inspector you do change the on-disk value.

There are cases in 1 and 2 where changes will persist however. If the SmartType has an underlying reference type (e.g. SmartMaterial) and the referenced object is an asset (i.e. not instantiated at runtime) then changes to that object will persist. This is true of any manipulation of assets, for example using MeshFilter.sharedMesh rather than MeshFilter.mesh. It's important to be aware that SmartData shares the same limitations as any other Unity code.

When your underlying type is a reference type, the SmartObject inspector will warn you that reset behaviour may not do exactly what you think. In these cases, you can implement custom behaviour. Each generated SmartObject class uses the partial keyword so you can add code without having it overwritten by the code generator.

To do this, write a new partial class with the same name (and namespace) and override the OnRestore() method.

What if I want it to?

For now, tough. For case 3, it'll always be "tough". To get around that, you could for instance write a Decorator which serialised the value to a save file and loads from that save file at runtime.

In cases 1 and 2, for now you just have to remember the setting you changed to, exit play mode and alter it - just like scene objects. But I plan to add a button to the SmartObject inspector to "save" the value at runtime.

Does changing the runtime value hit the disk?

Nope! Unity doesn't automatically serialize changes to disk - this only happens when you click File > Save Project, or Unity closes. In other words, it's the same as changing a value on any MonoBehaviour.

Known Issues

Scene objects cannot be dragged into SmartObjects

Since ScriptableObjects are "global" and scene objects only exist in that scene, Unity disallows serialization of scene objects within ScriptableObjects. So if you're using a SmartGameObject, SmartRigidbody or similar you cannot drag-and-drop a scene object into your SmartObject.

The most important thing to note is that it still works in code! There is no issue with using SmartData to pass Unity objects around. It's just that Unity won't let you drag-and-drop.

At edit-time this is absolutely correct. However at runtime it makes sense to be able to do this for testing and debugging. Hopefully a workaround can be found in the future, although this is a relatively low priority.

I use Odin Inspector and SmartData looks all janky

Yeah, it'll do that. Odin conflicts with some of SmartData's custom inspectors. It's easily solved - just go to Odin's settings and disable it for the SmartData namespace.

I'm having trouble compiling SmartData on [insert platform here]

Please let us know if you can't compile SmartData on a particular platform! Be sure to include Unity version number and any compilation errors. There may be issues with IL2CPP compilation in beta versions of Unity 2018.3; however to our knowledge, IL2CPP should be fine in general.