How to assign unity prefabs to scattered objects? (17.5.308)

   4031   7   1
User Avatar
Member
29 posts
Joined: Sept. 2017
Offline
Hi,

i'm fairly new to Houdini and try to create a terrain with biomes and objects. I managed to create a terrain with textures in unity by using “unity_hf_texture_diffuse”. Now i want to spawn some objects, but “unity_instance” has no effect. The node i export to a digital asset has all the textures and instances correctly set in geometry tab. I even get no gameobject assign field in unity to manually assign the prefabs. Oh, and i also don't get a texture input field anymore (worked in 17.5.293).

Using:

  • Houdini 17.5.308
  • Unity 2019.1.8

Some shots:





Thanks,
daschatten
Edited by daschatten - July 6, 2019 09:00:58

Attachments:
Houdini_Terrain_01.jpg (265.7 KB)
Houdini_Terrain_02.jpg (196.1 KB)
Houdini_Terrain_03.jpg (202.5 KB)

User Avatar
Member
571 posts
Joined: May 2017
Offline
If you set things up, it should work. What are you using for your scatter points (a heightfield scatter node)?

I've attached a simple scattering HDA for you to test. It requires that you place a prefab at Assets/Prefabs/Sphere.prefab. You can simply create a prefab out of a Unity sphere mesh and place it at that path. This is a simple test case, and if it works, then you should compare with your HDA setup.

I even get no gameobject assign field in unity to manually assign the prefabs.

Hmm are you using an object path parm to expose the input field?

Oh, and i also don't get a texture input field anymore (worked in 17.5.293).

So this was changed in the recent Houdini versions in relation to how terrains are generated from HDAs. It's now simpler and more flexible. Instead of specifying TerrainLayer properties individually, you can now just specify the path to existing TerrainLayers. This means less attribute setup, can share or reuse TerrainLayers, and better future proofing (in case Unity changes TerrainLayer properties). See https://www.sidefx.com/forum/topic/67618/ [www.sidefx.com]

Attachments:
hf_scatter_instance.hda (39.4 KB)

User Avatar
Member
29 posts
Joined: Sept. 2017
Offline
Found the issue! I have a primitive connected to each scatter field for better visualization. This overrides the unity_instance setting. It would be helpful if this could be changed to not override the unity_instance setting. Especially if there are a lot of different objects scattered around. Or maybe i can modify this via attribute or vex script?
User Avatar
Member
571 posts
Joined: May 2017
Offline
Looks like the underlying system is converting the instancing into a different type of instancing when you specify the object in the Heightfield scatter node. It might not be easy to remove it via a change in your network afterwards.

I'll add an RFE to investigate whether we can do something on the plugin side to have the override happen the other way around.
User Avatar
Member
29 posts
Joined: Sept. 2017
Offline
seelan
Looks like the underlying system is converting the instancing into a different type of instancing when you specify the object in the Heightfield scatter node. It might not be easy to remove it via a change in your network afterwards.

I'll add an RFE to investigate whether we can do something on the plugin side to have the override happen the other way around.

Any news on that @seelan?

I have one more feature request regarding a hf scatter node. Today i learned about weighted and hierarchical scattering. It would be great to use such a graph:

Cube -> Create Attribute (weight, unity_instance, instance_prefix) -> Scatter

Right now this isn't possible because the scatter node doesn't copy the attributes. Or did i miss something?
User Avatar
Member
28 posts
Joined: March 2015
Offline
Yes, this is annoying, you actually have to “re-implement” the weighting after the scatter node.
I basically copied the 4 nodes highlighted in red from inside the HF Scatter node to assign the right point attributes.

And at the beginning of graph, I create as many points as I have prefabs that I want to scatter, add the proper attributes in the for-each loop.
Then I modified slightly the vex code in the “generate_rand_id” node with the following:
From:
for (int i = 0; i < nprimitives(1); ++i)
{
    if (generated_rand < primattrib(1, "_normalized_weight", i, 0))
    {
        i@variant = i;
        break;
    }
}
To:
for (int i = 0; i < npoints(1); ++i)
{
    if (s@tag == "rocks")
    {
        if (generated_rand < pointattrib(1, "_normalized_weight", i, 0))
        {
            s@unity_instance = pointattrib(1, "path", i, 0);
            break;
        }
    }
}
Since tags are preserved, I was able to use them to differentiate trees and rocks for example.
I hope it makes sense!

Thanks,
Alex

Attachments:
Scattering.png (61.4 KB)

User Avatar
Member
29 posts
Joined: Sept. 2017
Offline
@chekboom It seems i'm using a different approach:



The problem here is that the scatter node ignores “unity_instance” and “instance_prefix”. To fix this i use a attribute wrangle node later. The VEX reads tag (from which scatter node the point is) and variant (which object variant belongs to this point) and sets “unity_instance” and “instance_prefix” accordingly. But now we come to another issue: the unity importer places the primitive mesh rather than the unity prefab given in “unity_instance”. Therefore i slightly changed the “instance_prefix” and added the variant number to it. In unity i have a script which finds all gameobjects, splits the prefix into tag and variant and spawns the right prefab there.

int hasTag;
string area = getattrib(@geoself, "point", "tag", @ptnum, hasTag);
int hasVariant;
int variant = getattrib(@geoself, "point", "variant", @ptnum, hasVariant);

string treesPath = "Assets/NatureManufacture Assets/Meadow Environment Dynamic Nature/Trees/High Quality Poplar Prefabs/";
string rocksPath = "Assets/NatureManufacture Assets/Meadow Environment Dynamic Nature/Rocks/Rocks/Prefabs/";

function string GetPrefix(string area; int variant) {
    if(area == "forrest_scatter_trees") return "Tree_" + itoa(variant);
    if(area == "forrest_scatter_bushes") return "Bush_" + itoa(variant);
    if(area == "forrest_scatter_rocks") return "Rock_" + itoa(variant);
    return "Unknown Prefix";
}

function string GetPrefab(string area, treesPath, rocksPath; int variant) {
    if(area == "forrest_scatter_trees") {
        if(variant == 0) return treesPath + "prefab_00_Poplar_plant_A.prefab";
        if(variant == 0) return treesPath + "prefab_03_Poplar_skan.prefab";
        if(variant == 0) return treesPath + "prefab_04_Poplar_skan.prefab";
    }
    
    if(area == "forrest_scatter_rocks") {
        if(variant == 0) return rocksPath + "prefab_m_rock_01.prefab";
        if(variant == 0) return rocksPath + "prefab_m_rock_02.prefab";
        if(variant == 0) return rocksPath + "prefab_m_rock_03.prefabb";
    }
    
    return "Unknown Prefab";
}

if(variant == -1) return;

setattrib(geoself(), "point", "unity_instance", @ptnum, 0, GetPrefab(area, treesPath, rocksPath, variant));
setattrib(geoself(), "point", "instance_prefix", @ptnum, 0, GetPrefix(area, variant));

Some workarounds, but finally works :-)
Edited by daschatten - July 16, 2019 05:20:18

Attachments:
Houdini_Scatter_03.png (50.6 KB)

User Avatar
Member
2 posts
Joined: July 2019
Offline
seelan
If you set things up, it should work. What are you using for your scatter points (a heightfield scatter node)?

I've attached a simple scattering HDA for you to test. It requires that you place a prefab at Assets/Prefabs/Sphere.prefab. You can simply create a prefab out of a Unity sphere mesh and place it at that path. This is a simple test case, and if it works, then you should compare with your HDA setup.

I even get no gameobject assign field in unity to manually assign the prefabs.

Hmm are you using an object path parm to expose the input field?

Oh, and i also don't get a texture input field anymore (worked in 17.5.293).

So this was changed in the recent Houdini versions in relation to how terrains are generated from HDAs. It's now simpler and more flexible. Instead of specifying TerrainLayer properties individually, you can now just specify the path to existing TerrainLayers. This means less attribute setup, can share or reuse TerrainLayers, and better future proofing (in case Unity changes TerrainLayer properties). See https://www.sidefx.com/forum/topic/67618/ [www.sidefx.com]

hi
i'm fairly new to Houdini too.I can't use the HDA file you provided.Can you help me?

Attachments:
_CN3GXSR%KA10[7%GVBF)W4.png (417.0 KB)
`$87467V22~{IL(7PJ)XZ[5.png (110.8 KB)
CR59B[$T%@2CGU2]K[$3E_5.png (14.0 KB)

  • Quick Links