I have a child object that gets instantiated in the editor as a child of a prefab, but need to exclude the object from the prefab itself. This child will only ever exist within the editor, not at runtime. It is essentially part of a design-time preview feature.
I had assumed from the (very vague) documentation that this could be achieved by setting the hideFlags of the child, but this does not seem to have any effect on prefabs. This is an issue that others clearly care about as evidenced by this unanswered Unity Answers question that has had significant activity over time.
Other options I have tried:
Implementing ISerializationCallbackReceiver and briefly un-parenting the child in OnBeforeSerialize(). This does not seem to work however as in the editor OnBeforeSerialize() is called very frequently and OnAfterDeserialize() is not called each time to clean up the parenting. I fear there may also be threading issues here, the documentation is unclear on this.
In some way (PrefabUtility?) hooking into the saving process itself and removing the child. There does not however seem to be any provided way of doing that. The best I can think of is that maybe I could detect every prefab save that occurs, immediately instantiate that prefab again, modify it from script to remove the child and then re-save it. This may work but is a hacky-workaround at best and seems fairly dangerous.
Not actually have the child object be a child but emulate all of the effects that parenting an object has. This would not be a great solution from a usability perspective but may be better than nothing. I would however need to exactly emulate all of the effects of parenting as much as possible, and it’s not immediately clear exactly what those are.
Are there any other ways to do this? Is this behaviour of hideFlags intended? It sure would be nice if the documentation were clearer on these more advanced behaviours…
There’s absolutely no way to do what you want that I know of, however in your case this might be helpful to attach to the child objects that are being generated:
public class SelfDestructOnExit: MonoBehaviour
{
void OnApplicationQuit()
{
Destroy(gameObject);
}
}
EDIT: Upon re-reading, I think I may have misunderstood your specific needs here. I got you and the author of that question you posted mixed up there.
It might be possible to achieve this in some other way. What is the child object doing? If you’re just using the child object for handles or something, there’s ways to do that without having an object in the scene, which is why I’m asking.
A possible solution would be to fake-child the prefab; have whatever editor script you have on it make it move like a child transform would, but not actually having it as a child
You could attach the child object at runtime when the object gets instantiated in code, with the directive #if UNITY_EDITOR wrapped around it. In that case you will only ever have it attached in the editor.
Presumably you mean gizmos? No, that is not applicable here - I actually need to have arbitrary other GameObjects as the children. It’s one of those things that would be easy if we had actual working nested prefabs (no, buying an asset for this is not an option) but I’m trying to hack my way around at the moment. Thanks for the reply though, I’m sure that method will work for some people who may find this thread in the future.
I actually already have a system that’s doing something like this, instantiating the child from script in the editor. The problem is that I need the parent to be able to be a prefab and for that prefab to be applied without the instantiated child being included in that prefab.
If I only needed the child to be present at runtime this would be a solution as the parent prefab is never saved at runtime. However in this case it is important to be able to have the instantiated child visible for level design purposes.
I initially figured this would be simple, as the documentation seems to indicate hideFlags could achieve this but it appears not, and I have not been able to find any callback methods which I can use to modify the parent right-before the prefab is saved.
Oops, I forgot to respond to this bit in my previous reply. Yeah, this is something I have considered, it’s basically my third bullet point in the original post, but it’s not quite ideal. It would be significantly nicer to have the child actually show as a child in the hierarchy. This may, however, be what I end up going with if nothing better is possible. I could hide it from the hierarchy all-together and it wouldn’t be too bad a user-experience I guess.
Such an old question and no one mentioned the most obvious solution? The same way Unity handles all their internal objects like the sceneview camera and the sceneview lights: hideflags. With the hideflags of a UnityEngine.Object you can specify if an object should be saved at all and you can also control if it would be visible / editable in the inspector / hierarchy.
Though be careful. Things marked as DontSave are not saved into the scene or prefabs, however they also are not subject to the normal object management. As you can read in the example:
So you have to take care of the lifetime of those objects yourself. As an example, here in my UVViewer I create a MeshCollider on the viewed object if it does not have one already. That temp collider is marked with HideAndDontSave as well as HideInInspector. This is only used to get raycast results from the collider that includes mesh details (triangle index and uv coords). Note that this is actually quite old. I think that HandleUtility.RaySnap may actually work in this case. Though I’ve never tried it.
Note when creating temporariy gameobjects in the scene, you should use EditorUtility.CreateGameObjectWithHideFlags as it does not cause the scene to get dirty when you set hideflags that tell Unity to not save the object. Otherwise just creating a new gameobject and then setting the hideflags would already cause the scene to be marked as dirty before you can set the hideflags.
@Bunny83 . Looks like a good solution for this case.
I can only imagine that at the time the posting was written hideFlags didn’t apply to prefabs as @UnitedWeFall mentions them as not working for him. But they do.
Personally I came here when looking for a solution where…
the component would stay on a prefab instance in the scene after the scene is saved
but is never added to the prefab when applying instance changes to the prefab.
I fear in that case hideflags won’t help.
Though the upper solution isn’t great either as I found out by now.
If you click on a prefab in the project view and change anything on it (like ticking a checkbox) the inspector would vanish.
Because: Prefab changes → Instance changes → Callback fires → Prefab replaced → Inspector gone
It’s also quite dangerous as all existing changes on the first instance the callback fires for will be applied to the prefab… and is so even propagated to all other instances.
Meh.
edit:
Tried to make prefab modification work… but it always came with some nasty quirks in my case.
I think I found a simple, robust solution for my case now, based on hideFlags as @Bunny83 pointed out: