LogicalError / realtime-CSG-for-unity

Realtime-CSG, CSG level editor for Unity
https://realtimecsg.com
MIT License
732 stars 76 forks source link

Redundant [default-CSGModel] is created on domain reload in wrong scene when using additive scene loading #386

Open Appleguysnake opened 10 months ago

Appleguysnake commented 10 months ago

On a domain reload, RCSG reinitializes and creates an extra hidden [default-CSGModel] gameobject even when one is in the scene. It creates the object in the active scene rather than the scene with the model.

The immediate cause is in InternalCSGModelManager.DefaultModel.cs at line 111 where sceneState.DefaultModelObject is set to a new gameobject. There appears to be no way in Unity to instantiate a gameobject in a particular scene unless creating a prefab for some reason. Adding SceneManager.MoveGameObjectToScene(sceneState.DefaultModelObject, currentScene); to the following line appears to move the gameobject successfully, but at the end of the domain reload it shows up in the hierarchy in the wrong place. I can't tell if it's being moved by some RCSG methods later in initialization, or some arcane Unity nonsense. On the next domain reload / initialization, the default model is searched for with SceneQueryUtility.GetUniqueHiddenGameObjectInSceneWithName, but that correctly searches the added scene and therefore doesn't find it, so it creates another one. If the scene is opened alone, or is set active during a reload, the hidden models are removed by that method.

It appears that objects marked DontSave hang around through scene changes (additive or not) in the editor hierarchy if something has a reference to them. That may be part of the issue, but I have not 100% confirmed this. From the docs: "The object will not be saved to the Scene. It will not be destroyed when a new Scene is loaded. You must manually clear the object from memory using DestroyImmediate to avoid memory leaks."

A constant issue with rcsg in my experience is giant git diffs or git diffs for scenes with no changes, even when not saving meshes in scene files. Often the problem appears to be objects just shuffling their order in the hierarchy. Since Unity instantiates things in weird places in the hierarchy sometimes, this may be (one of) the causes of that issue as well.

Appleguysnake commented 10 months ago

On a more speculative note, line 145 of the same file says

// force the users to use a CSG-model, but gracefully let it still be 
//  visible for objects outside of it.

Arguably, this feature can be counter-productive since it allows for brushes outside of a model to show in the editor which will then be stripped from a build, which seems likely to hide errors from users in a way that's difficult to identify.

Appleguysnake commented 10 months ago

I just noticed that some default models were saved in my scene again, which may be a separate issue of its own. Not sure where to start searching for the cause of that one.

Appleguysnake commented 9 months ago

Okay I think I've gotten closer to figuring this one out but I don't have time to thoroughly confirm right now.

InternalCSGModelManager.DefaultModel.cs only marks the default model as DontSave if it's in prefab mode. I'm not sure why. The default model is marked DontSaveInBuild. There are notes about weird behavior relating to hideflags in MeshInstanceManager.cs but no indication about not saving in editor.

According to the docs, objects marked DontSave aren't destroyed when a new scene is loaded. So it seems like RCSG should be holding onto that reference and destroying it on scene unload. The current find solution seems like it might be fine when not using additive scene loading, but that would be the more diligent solution I guess? Alternately, just make sure to search all open scenes. Whatever is easier (since Unity is making it hard to want to write code with a long term future in mind right now 😢 )

There's also this post about some Unity hideflags weirdness but I have not explored that angle. https://forum.unity.com/threads/hideflags-hideflags-dontsave-being-saved-to-prefab.675523/

Going to just set everything to dontsave and hope nothing breaks for now.