Instancing Unity prefab with Houdini ?

   7989   12   1
User Avatar
Member
2 posts
Joined: Sept. 2019
Offline
Hello, I'm an Unity developer but I'm new to Houdini.

My question is, as our old workflow, I have prefabs in Unity which have some scripts/lods/colliders configured on them. I want to input them to a .hda and populate them along a curve with Houdini, preserving those scripts/lods/colliders.

I checked the docs and tried for a while, but I find that the prefabs are inputted in Houdini as meshes and the scripts/lods/colliders are lost in the generated asset.

So how can I preserve the components attached on the prefabs in the generated assets, thanks?
User Avatar
Member
571 posts
Joined: May 2017
Offline
If you are simply instancing the source prefab, and not changing the mesh geometry in Houdini, then you don't need to use them as input meshes. Rather, in your HDA, add a string or path parm to just take the Unity asset path to the prefab, then on the curve points, add a unity_instance string attribute. Their value should be the asset path you provided in your parm. This simply instances the prefabs on export, and keeps everything intact. Note that in order to use unity_instance attribute to create instances, the output geo must only have points (no primitives).
https://www.sidefx.com/docs/unity/_instancing.html#ObjectInstancers_Attribute [www.sidefx.com]

If you need to bring in the mesh into Houdini for modification, you should split up your HDA to generate two objects:
1. Generates new mesh based on your source input mesh.
2. Generates instances using the prefab path like I described above.
3. In a post cook event, replace the prefab instance mesh with your new mesh from 1. https://www.sidefx.com/docs/unity/_assets.html#Assets_AssetInspectorUI_Events [www.sidefx.com]
Edited by seelan - Sept. 23, 2019 08:51:10
User Avatar
Member
2 posts
Joined: Sept. 2019
Offline
Saved the day! Thank you so much
User Avatar
Member
12 posts
Joined: May 2017
Offline
Piggy backing on the main question.
I hava a HDA that does exactly that: it takes path to Unity prefab stored in unity_instance attribute and among other things places this prefab along curve path.

Our workflow is that at the end all content created with the HDA is baked into objects (not prefabs). These objects are grouped together under parent Unity Game Object and all this is saved as a major prefab.
We do this to allow multiple team members to work on the same Unity scene at the same time.

I noticed some strange behavior:
Every time I recook or rebake HDA that uses some Unity prefab (let's call it prefab A) - it will cause Unity to update every major prefab where said prefab A is also used. The more scenes in the project the longer it takes to go through all the major prefabs. I am writing this post while waiting for Unity to finish recooking 20 HDAs due to some changes in the HDA definition. Every HDA causes series of “Hold on…” pop ups:


I'd appreciate some information on why it might be happening and how to get rid of it.
Cheers,
STC
Edited by staszek-c - Oct. 10, 2019 08:17:07

Attachments:
UpdateIssue.jpg (13.8 KB)

User Avatar
Member
571 posts
Joined: May 2017
Offline
Does the long prefab update also happen if you make a change directly to the prefab and apply it (i.e. not going through Houdini Engine)?
User Avatar
Member
12 posts
Joined: May 2017
Offline
Hi, thanks for quick response.

If I make a direct change to “small” prefab that is embedded inside another major prefabs they will also update once I apply the changes - this is standard behavior.
To clarify my HDAs are not making any changes to the small prefab. They just place it in locations of the points generated by the Houdini Engine.

STC
Edited by staszek-c - Oct. 10, 2019 10:27:19
User Avatar
Member
12 posts
Joined: May 2017
Offline
seelan
Does the long prefab update also happen if you make a change directly to the prefab and apply it (i.e. not going through Houdini Engine)?
@seelan Did you tried / manage to recreate the issue?

So far I hacked a walkaround by replacing the prefab placing nodes in HDA definition with simple dummy mesh that's packed and copied to points. After baking the HDA in Unity I run custom script that replaces each dummy with chosen prefab. Although I'd still appreciate some update on this.

STC
Edited by staszek-c - Oct. 16, 2019 10:20:38
User Avatar
Member
571 posts
Joined: May 2017
Offline
No I haven't reproduced it. Which version of Unity are you using, as well as Houdini version?
Please provide an HDA to test with.
User Avatar
Member
12 posts
Joined: Jan. 2020
Offline
Hello! Did you ever get to the bottom of this?

I'm having a similar problem where the project has a single .hda which has multiple instances across several scenes. Each instance is baked to a prefab (via the Bake Prefab button in the inspector for the instance). Every time a new instance is created or modified, *every* baked prefab is re-imported, with associated ‘hold on…’ progress bars. Obviously as we add prefabs to the project it's just getting slower and slower to actually do anything, which sucks.

Unity version 2018.4.12f1
Houdini version 18.0.348
Houdini engine version 3.3.2

What's weird is that the prefab doesn't have any Houdini components or references inside it, so I have no idea what's causing the reimport. And it happens with an otherwise empty scene so it's not just triggering the prefabs that exist in the scene, but all prefabs that have been baked by Houdini.
User Avatar
Member
12 posts
Joined: Jan. 2020
Offline
So since this was really dragging our productivity down, I went and did the legwork to track this down further. My (simplified) setup is a RoomTemplate.hda, which references Probe_proxy.prefab (via an Attribute Create op as above). This is cooked and then baked as separate prefabs (RoomA.prefab / RoomB.prefab / etc.). Certain modifications seem to trigger several full re-import of all baked prefabs (in my case, each one re-imported three times).

I've tracked it down to HEU_PartData.cs / GenerateInstancesFromUnityAssetPathAttribute @ line 880:
HEU_AssetDatabase.ImportAsset(instancePathAttrValues[i], HEU_AssetDatabase.HEU_ImportAssetOptions.Default);

Which is a wrapper around AssetDatabase.ImportAsset [docs.unity3d.com]. This triggers a reimport of the Probe_proxy.prefab (which is just a single GameObject with a marker component) *but* then because that's included in the existing baked prefabs (RoomA.prefab etc.) it triggers a reimport of *all* of those. This will happen for each time that the .hda references a unity prefab (which is why I see everything reimported three times in total).

Thoughts:
  1. Unity could be smarter here. Probe_proxy.prefab is unchanged, yet it ripples through and reimports the room prefabs unnecessarily.
  2. Houdini could be smarter here and use the batching API [docs.unity3d.com] for asset database changes since we’ll be doing lots in a single operation and that would be much faster.
  3. But… do we even need the ImportAsset call in the first place? Houdini isn’t modifying it, it just wants it loaded, which it does on the line after with LoadAssetAtPath. Removing the ImportAsset line and things seem to work (and avoids all the unnecessary imports).
  4. Alternatively, a post-cook script could unpack any created prefabs so they no longer contain nested prefabs. Less than idea since prefab changes won’t propagate, but the least risky and doesn’t involve changing the Houdini plugin. I’ve tested this by manually unpacking and this also works.

Right now I'm going with option 3, because as far as I can see that's safe. Unity will just cache the asset itself like normal and we never need to force a reimport. But it'd be good to get some more eyes on it that are more familiar with the plugin code.

(Aside: thanks for including the source to the Unity plugin, otherwise tracking this down would have been impossible. )
User Avatar
Member
571 posts
Joined: May 2017
Offline
Yes, AssetDatabase.ImportAsset is needed for loading assets since that is Unity's catch all API for it.

I did make a change to make this faster though. In tomorrow's daily build (Houdini 18.0.531), it will now support instances with assets from the Resources directory, which makes for a faster loading time, and eliminate the need for updating the AssetDatabase.

To use this new feature, move your assets into the Resources directory, and specify the path as you would normally to them.
User Avatar
Member
12 posts
Joined: Jan. 2020
Offline
seelan
Yes, AssetDatabase.ImportAsset is needed for loading assets since that is Unity's catch all API for it.
Hello! Thanks for the response.

In this case, I really don't think this is the correct usage of the API. ImportAsset signals that the asset has changed on disk, which isn't what's happening here. If the plugin needs it loaded then LoadAssetAtPath (which it does on the next line) will trigger that (potentially using an already cached and loaded version). But a hda just referencing an existing prefab doesn't need to import it, just load it. I've been working with unity a very long time and written lots of code using the asset database, and this part of the Unity API is just poorly named and documented imho.
Edited by OrangyTang - July 21, 2020 19:42:38
User Avatar
Member
571 posts
Joined: May 2017
Offline
Interesting. I remember that just using LoadAssetAtPath was not working in certain cases, hence the ImportAsset call before it. This was from my testing a couple of years ago, so perhaps they have improved it.

I suppose I can do a LoadAssetAtPath first, then fallback to ImportAsset then LoadAssetAtPath if it fails as well.
  • Quick Links