In Houdini 18.0.311 and newer, a new feature was added to store any attributes of a SOP in the output gameobject as a script component (HEU_OutputAttributesStore). More info provided in the online documentation:
https://www.sidefx.com/docs/unity/_attributes.html#AttributesStore [www.sidefx.com]
This is a useful feature, especially when combined with a script callback to apply those attributes right after a cook. See the included example HDA (Assets/Plugins/HoudiniEngineUnity/HDAs/HEUInstanceAttributesStore.hda) which triggers a callback to query the health values on instances and set them as y-scale. You'll need to create a Cube prefab in Assets/Prefabs/Cube.prefab before instancing the example HDA in Unity.
New Houdini Engine for Unity feature: Attributes Store
4786 7 1- seelan
- Member
- 571 posts
- Joined: May 2017
- Offline
- sascha
- Member
- 158 posts
- Joined: July 2005
- Offline
Is the attribute store only accessible from the attached detail unity_script? I'm trying to access the HDA's OutputAttributesStore in a script on another game object (just an empty) but I guess I'm missing something:
So far I only got:
How do I get access to the OutputAttributesStore?
PS: The script above should work in any vanilla Unity project with HEU installed, just attach it to an empty and hit play. I used Unity 2019.3.13f and Houdini 18.0.463.
using System.Collections; using System.Collections.Generic; using UnityEngine; using HoudiniEngineUnity; public class HEU_AttributesStore : MonoBehaviour { void Start() { string attributesStoreAssetPath = "Assets/Plugins/HoudiniEngineUnity/HDAs/HEUInstanceAttributesStore.hda"; string attributesStoreFullPath = HEU_AssetDatabase.GetAssetFullPath(attributesStoreAssetPath); if (string.IsNullOrEmpty(attributesStoreFullPath)) { Debug.LogErrorFormat("Unable to load asset at path: {0}", attributesStoreAssetPath); return; } HEU_SessionBase session = HEU_SessionManager.GetOrCreateDefaultSession(); GameObject rootGO = HEU_HAPIUtility.InstantiateHDA(attributesStoreFullPath, Vector3.zero, session, true); if (rootGO != null) { HEU_EditorUtility.SelectObject(rootGO); } HEU_HoudiniAsset houdiniAsset = QueryHoudiniAsset(rootGO); if (houdiniAsset == null) { return; } CookAsset(houdiniAsset); HEU_OutputAttributesStore attrStore = houdiniAsset.GetComponent<HEU_OutputAttributesStore>(); if (attrStore == null) { Debug.LogWarning("No HEU_OutputAttributesStore component found!"); return; } } // Update is called once per frame void Update() { } public static HEU_HoudiniAsset QueryHoudiniAsset(GameObject rootGO) { HEU_HoudiniAssetRoot heuRoot = rootGO.GetComponent<HEU_HoudiniAssetRoot>(); if (heuRoot == null) { Debug.LogWarningFormat("Unable to get the HEU_HoudiniAssetRoot from gameobject: {0}. Not a valid HDA.", rootGO.name); return null; } if (heuRoot._houdiniAsset == null) { Debug.LogWarningFormat("Unable to get the HEU_HoudiniAsset in root gameobject: {0}. Not a valid HDA.", rootGO.name); return null; } return heuRoot._houdiniAsset; } public static void CookAsset(HEU_HoudiniAsset houdiniAsset) { houdiniAsset.RequestCook(bCheckParametersChanged: true, bAsync: false, bSkipCookCheck: true, bUploadParameters: true); } }
So far I only got:
No HEU_OutputAttributesStore component found!
How do I get access to the OutputAttributesStore?
PS: The script above should work in any vanilla Unity project with HEU installed, just attach it to an empty and hit play. I used Unity 2019.3.13f and Houdini 18.0.463.
Edited by sascha - May 15, 2020 13:21:33
- seelan
- Member
- 571 posts
- Joined: May 2017
- Offline
You should be able to access it from any script, as long as you have access to the HEU_HoudiniAsset component.
Note that your HDA has to output a valid geometry, I believe. If you HDA does output that, and has attribute with name hengine_attr_store of class Detail and type String, then it should work.
Attach your HDA if you are still having a problem.
Note that your HDA has to output a valid geometry, I believe. If you HDA does output that, and has attribute with name hengine_attr_store of class Detail and type String, then it should work.
Attach your HDA if you are still having a problem.
- seelan
- Member
- 571 posts
- Joined: May 2017
- Offline
Apologies, I should have check out your sample code. I see what you're trying to do now. Unfortunately, there are 2 problems with it.
First, I believe when transitioning to play mode, the internal attribute data is stored as a Dictionary which is likely being cleared during the code domain reload. So don't use play mode for getting the attributes.
Second, the HEU_HoudiniAsset.GetAttributesStores() function returns the attribute store on the HDA. This is different from the output attribute store (HEU_OutputAttributesStore) which is for each output geometry. To get those, you need to get the output GameObjects, and get the HEU_OutputAttributesStore component on them. See below code. The rootGO is your HDA root gameobject.
Check HEU_ExampleInstanceCustomAttribute.cs which has more example code.
First, I believe when transitioning to play mode, the internal attribute data is stored as a Dictionary which is likely being cleared during the code domain reload. So don't use play mode for getting the attributes.
Second, the HEU_HoudiniAsset.GetAttributesStores() function returns the attribute store on the HDA. This is different from the output attribute store (HEU_OutputAttributesStore) which is for each output geometry. To get those, you need to get the output GameObjects, and get the HEU_OutputAttributesStore component on them. See below code. The rootGO is your HDA root gameobject.
HEU_HoudiniAsset houdiniAsset = QueryHoudiniAsset(rootGO); List<GameObject> outputGOs = new List<GameObject>(); houdiniAsset.GetOutputGameObjects(outputGOs); HEU_OutputAttributesStore attrStore = outputGOs[0].GetComponent<HEU_OutputAttributesStore>(); if (attrStore == null) { Debug.LogWarning("No HEU_OutputAttributesStore component found!"); return; }
Check HEU_ExampleInstanceCustomAttribute.cs which has more example code.
- sascha
- Member
- 158 posts
- Joined: July 2005
- Offline
- sascha
- Member
- 158 posts
- Joined: July 2005
- Offline
seelan
Apologies, I should have check out your sample code. I see what you're trying to do now. Unfortunately, there are 2 problems with it.
First, I believe when transitioning to play mode, the internal attribute data is stored as a Dictionary which is likely being cleared during the code domain reload. So don't use play mode for getting the attributes.
Second, the HEU_HoudiniAsset.GetAttributesStores() function returns the attribute store on the HDA. This is different from the output attribute store (HEU_OutputAttributesStore) which is for each output geometry. To get those, you need to get the output GameObjects, and get the HEU_OutputAttributesStore component on them. See below code. The rootGO is your HDA root gameobject.HEU_HoudiniAsset houdiniAsset = QueryHoudiniAsset(rootGO); List<GameObject> outputGOs = new List<GameObject>(); houdiniAsset.GetOutputGameObjects(outputGOs); HEU_OutputAttributesStore attrStore = outputGOs[0].GetComponent<HEU_OutputAttributesStore>(); if (attrStore == null) { Debug.LogWarning("No HEU_OutputAttributesStore component found!"); return; }
Check HEU_ExampleInstanceCustomAttribute.cs which has more example code.
Thanks for the detailed reply!
Actually the dictionary doesn't seem to get cleared in play mode, at least not my my project right now. Though I'm not pursuing that route.
By the way, does the HEU_OutputAttribute support vector values? I guess not but floats work just fine…
Edited by sascha - May 19, 2020 00:16:51
- seelan
- Member
- 571 posts
- Joined: May 2017
- Offline
- seelan
- Member
- 571 posts
- Joined: May 2017
- Offline
-
- Quick Links