Hdg Remote Debug works using .NET’s reflection features; it doesn’t use any sort of built-in Unity serialisation. Every second it gathers all
GameObjects that are currently active, finds all
Components on them, and for each component, uses reflection to find all serialised and public fields. This data is sent back to the client running in the editor over a network connection, where the data is displayed in custom hierarchy and inspector windows.
This means it doesn’t use the built-in Unity inspectors or any custom inspectors you may have created, so when you click on, say, a
Camera object you see the public and serialised fields of the
Camera type rather than what Unity’s built-in
CameraEditor inspector would have shown.
I would like to fix this and use the built-in inspectors and I have actually prototyped it extensively but it turns out there are several problems. To use the built-in inspectors we require a proxy
GameObject that represents the selected object on the server. The idea is that whenever we receive a message from the server, we create a new proxy
GameObject, dynamically add all components to it, and for each component, create an
Editor instance with
Editor.CreateEditor(component). When drawing the UI for the components, we just call
Editor.OnInspectorGUI for each one and use
BeginChangeCheck/EndChangeCheck to determine if anything changed. If fields have changed we send a message to the server to update it.
There are a couple of problems with this approach. The built-in inspectors cause undo events to be added to the system, but those undo events are undesirable; the
GameObject is a temporary proxy object for which we don’t want to track undo events. In fact the object is not visible in the scene, so the undo events seem spurious to the user. It’s not a good user experience to generate all these undo events that go nowhere.
Another problem is that
EndChangeCheck doesn’t detect that changes have happened when certain fields are changed. One such field that I found was the camera mask property. It seems to be something to do with the
EditorGUI.PropertyField, which doesn’t seem to set
GUI.changed to true.
The last major problem is with the proxy
GameObject. We create a new proxy every time we receive a message from the server, but destroying the previous one seems to cause the
Editor objects that we created to throw
NullReferenceExceptions when you hit play or when Unity reloads assemblies, when it tries to reinitialise its
serializedObject field. I think I need to find a way to clear the reference on the
Editor when destroying the
GameObject, but it wasn’t possible when I last investigated. I can’t just leave the proxy object; that’s a memory leak!
I have a Trello roadmap board with some features I’d like to add. Some are wishlist features which may not really be possible without digging into the Unity source (e.g. hotswapping prefabs, or the aforementioned built-in inspectors). One feature I would like to add is an extensible console system, where you can hook in your own commands to control the game remotely. That way you can add debug features to the game that you can then control from Unity.
Get in touch if you have any questions or feature requests for Hdg Remote Debug!