Respecting hideFlags on build/export

Hey there, when traversing the exported object could you consider adding a check like hideFlags.HasFlag(HideFlags.DontSaveInBuild) to exclude the object?

And/or is there a callback like Unity’s own IPreprocessBuildWithReport or something similar to have a chance to modify the scene/project on the fly before exporting?

Hi krizzl0r, thanks for the feedback! In Needle Engine, we use a HideFlags enum that already contains a flag—HideFlags.DontExport—that serves a similar purpose during export. When this flag is set, the glTF exporter omits the object (and its children) from being exported (at engine_types.d.ts.md). This means that, rather than checking for a DontSaveInBuild flag, you should mark unneeded objects with DontExport.

Regarding a callback similar to Unity’s IPreprocessBuildWithReport, currently there isn’t a built‐in pre-export hook in Needle Engine that lets you modify the scene or project on the fly during export. At the moment, the recommended approach is to handle any preprocessing via Unity’s editor scripts before starting the export—for example, by leveraging IPreprocessBuildWithReport on your Unity side to remove or adjust objects as needed.

Hope this helps clarify things! If you have more questions or need further integration tips, feel free to ask.

1 replies left - Become PRO for more replies.
thread_mfyMhMYN3wO91s9zfZ6vfaOM
Reply to this post directly if you need further help (bottom right button)

Hi - you can tag objects with EditorOnly to exclude them from export.
The reason we’re not using HideFlags for that is that tools with procedural mesh generation usually mark objects (correctly) as DontSave, but that doesn’t mean you actually want them ignored. DontSave is a shorthand for DontSaveInEditor | DontSaveInBuild.

Usually I tag objects as EditorOnly and disable them; we even have a little hierarchy icon showing that they won’t be exported.

Regarding callbacks, yes – you can leverage the UnityGltf plugin system and do pretty much everything.

That’s what I’ve been doing. But I have a use case now where I have a prefab instance in my scene which I do not want exported as it’s just a preview.
If I modify the tag it get registered as a prefab override. Now if someone is editing the prefab “preview” instance in a meaningful way and wants to apply the overrides the prefab itself, it’s easy to overlook the changed tag override and voila, no more export for this prefab from here on.

I can see though that procedural tools would be on the other end of the of hideFlags-edge-case-spectrum :slight_smile: My stance is if it’s not committed to the scene, it should not be part of the export as well.

Thanks for the pointer to the plugin system of UnityGltf though. This works great:

using GLTF.Schema;
using UnityEngine;
using UnityGLTF;
using UnityGLTF.Plugins;

public class DontSaveInBuildExportPlugin: GLTFExportPlugin
{
    public override GLTFExportPluginContext CreateInstance(ExportContext context)
    {
        return new DontSaveInBuildExportPluginContext();
    }

    public override string DisplayName => "Strip HideFlags.DontSaveInBuild";
    public override string Description => "Strips GameObjects with hideFlags containing HideFlags.DontSaveInBuild";
}

public class DontSaveInBuildExportPluginContext : GLTFExportPluginContext
{
    public override bool ShouldNodeExport(GLTFSceneExporter exporter, GLTFRoot gltfRoot, Transform transform)
    {
        return transform.gameObject.hideFlags.HasFlag(HideFlags.DontSaveInBuild) == false;
    }
}

Awesome!

What I usually do, when I have prefabs in the scene in that way, is nest them under a parent that is EditorOnly – this way the prefab overrides are not affected.

Ha, this messes with your exporters as they set HideFlags too in some scenarios. E.g. here: SceneExportUtils.cs:238

// If a component in a prefab asset was referenced we get a prefab instance of the whole thing in our scene
// so we want to destroy the whole instance again
var objectToDestroy = PrefabUtility.GetOutermostPrefabInstanceRoot(instance);
if (!objectToDestroy && instance is Component comp) objectToDestroy = comp.gameObject;
objectToDestroy.hideFlags = HideFlags.HideAndDontSave;
dispose = () => { Object.DestroyImmediate(objectToDestroy); };

Now this flags my prefab (which is only referenced as an AssetReference) as HideAndDontSave which my plugin (see above) then rejects through ShouldNodeExport() which then creates a null node in the GLTFScene which results in a null ref exception during serialization:

NullReferenceException: Object reference not set to an instance of an object
GLTF.Schema.GLTFScene.Serialize (Newtonsoft.Json.JsonWriter writer) (at ./Library/PackageCache/org.khronos.unitygltf@2.16.1/Runtime/Plugins/GLTFSerialization/Schema/GLTFScene.cs:67)

:cry:

I see! Well, hide flags / DontSave should not really be used for determining export I think :sweat_smile: