public void Start()
    {
        // Grab the HEU_HoduiniAsset
        _evergreenAsset = _evergreenGameObject.GetComponent <HEU_HoudiniAssetRoot>() != null?_evergreenGameObject.GetComponent <HEU_HoudiniAssetRoot>().HoudiniAsset : null;

        // Always get the latest parms after each cook
        List <HEU_ParameterData> parms = _evergreenAsset.Parameters.GetParameters();

        foreach (HEU_ParameterData parmData in parms)
        {
            HEU_Logger.Log(parmData._labelName);

            if (parmData._parmInfo.type == HAPI_ParmType.HAPI_PARMTYPE_BUTTON)
            {
                // Display a button: parmData._intValues[0];
            }
            else if (parmData._parmInfo.type == HAPI_ParmType.HAPI_PARMTYPE_FLOAT)
            {
                // Display a float: parmData._floatValues[0];

                // You can set a float this way
                HEU_ParameterUtility.SetFloat(_evergreenAsset, parmData._name, 1f);

                // Or this way (the index is 0, unless its for array of floats)
                parmData._floatValues[0] = 1;
            }
        }
        // Make sure to cook after changing
        _evergreenAsset.RequestCook(true, false, true, true);

        // Start a repeating updater
        InvokeRepeating("UpdateGravity", _updateRate, _updateRate);
    }
    /// <summary>
    /// Query each geometry container's parts to get the actual geometry data.
    /// A HAPI_GeoInfo represents a SOP geometry container that might have one or more
    /// HAPI_PartInfos.A geometry containing more than one part could mean different
    /// geometry types merged together, or different layers in a heightfield volume.
    /// </summary>
    /// <param name="session">Houdini Engine session</param>
    /// <param name="geoInfo">The HEU_GeoInfo pertaining to the geometry to query</param>
    public static void QueryGeoParts(HEU_SessionBase session, ref HAPI_GeoInfo geoInfo)
    {
        int numParts = geoInfo.partCount;

        for (int i = 0; i < numParts; ++i)
        {
            HAPI_PartInfo partInfo = new HAPI_PartInfo();
            if (!session.GetPartInfo(geoInfo.nodeId, 0, ref partInfo))
            {
                continue;
            }

            StringBuilder sb = new StringBuilder();

            // Process each geometry by its type
            if (partInfo.type == HAPI_PartType.HAPI_PARTTYPE_MESH)
            {
                // Meshes
                sb.AppendLine(string.Format("Mesh part at {0} with vertex count {1}, point count {2}, and primitive count {3}",
                                            i, partInfo.vertexCount, partInfo.pointCount, partInfo.faceCount));
            }
            else if (partInfo.type == HAPI_PartType.HAPI_PARTTYPE_VOLUME)
            {
                // Heightfield / terrain
                sb.AppendLine(string.Format("Volume part at {0}", i));
            }
            else if (partInfo.type == HAPI_PartType.HAPI_PARTTYPE_CURVE)
            {
                // Curves
                sb.AppendLine(string.Format("Curve part at {0}", i));
            }
            else if (partInfo.type == HAPI_PartType.HAPI_PARTTYPE_INSTANCER)
            {
                // Instancer
                sb.AppendLine(string.Format("Instancer part at {0}", i));
            }
            else if (partInfo.type == HAPI_PartType.HAPI_PARTTYPE_INVALID)
            {
                // Not valid Houdini Engine type - ignore
                sb.AppendLine(string.Format("Invalid part at {0}", i));
            }

            // Query attributes for each part
            QueryPartAttributeByOwner(session, geoInfo.nodeId, i, HAPI_AttributeOwner.HAPI_ATTROWNER_DETAIL, partInfo.detailAttributeCount, sb);
            QueryPartAttributeByOwner(session, geoInfo.nodeId, i, HAPI_AttributeOwner.HAPI_ATTROWNER_PRIM, partInfo.primitiveAttributeCount, sb);
            QueryPartAttributeByOwner(session, geoInfo.nodeId, i, HAPI_AttributeOwner.HAPI_ATTROWNER_POINT, partInfo.pointAttributeCount, sb);
            QueryPartAttributeByOwner(session, geoInfo.nodeId, i, HAPI_AttributeOwner.HAPI_ATTROWNER_VERTEX, partInfo.vertexAttributeCount, sb);

            HEU_Logger.Log("Part: \n" + sb.ToString());
        }
    }
    /// <summary>
    /// Query the parameters in the HDA, and change some values.
    /// </summary>
    /// <param name="houdiniAsset">The HEU_HoudiniAsset of the loaded asset</param>
    public static void ChangeParmsAndCook(HEU_HoudiniAsset houdiniAsset)
    {
        // Always get the latest parms after each cook
        List <HEU_ParameterData> parms = houdiniAsset.Parameters.GetParameters();

        if (parms == null || parms.Count == 0)
        {
            HEU_Logger.LogFormat("No parms found");
            return;
        }

        // --------------------------------------------------------------------
        // Example to loop over each parm, checking its type and name. Then setting value.
        StringBuilder sb = new StringBuilder();

        foreach (HEU_ParameterData parmData in parms)
        {
            sb.AppendLine(string.Format("Parm: name={0}, type={1}", parmData._labelName, parmData._parmInfo.type));

            if (parmData._parmInfo.type == HAPI_ParmType.HAPI_PARMTYPE_BUTTON)
            {
                // Display a button: parmData._intValues[0];
            }
            else if (parmData._parmInfo.type == HAPI_ParmType.HAPI_PARMTYPE_FLOAT)
            {
                // Display a float: parmData._floatValues[0];

                // You can set a float this way
                HEU_ParameterUtility.SetFloat(houdiniAsset, parmData._name, 1f);

                // Or this way (the index is 0, unless its for array of floats)
                parmData._floatValues[0] = 1;
            }
        }
        HEU_Logger.Log("Parameters: \n" + sb.ToString());

        // --------------------------------------------------------------------
        // Examples to look up a parm via name, and set it.

        // Use helper to set float parameter with name
        HEU_ParameterUtility.SetFloat(houdiniAsset, "gravity", 5f);

        // Use helper to set random color
        HEU_ParameterUtility.SetColor(houdiniAsset, "branch_vtx_color_color", Random.ColorHSV());

        // Make sure to cook after changing parms
        CookAsset(houdiniAsset);
    }
    static void LogArray <T>(string name, T[] arr, int tupleSize)
    {
        int           index = 0;
        int           count = arr.Length / tupleSize;
        StringBuilder sb    = new StringBuilder();

        for (int i = 0; i < count; ++i)
        {
            sb.AppendFormat("{0}[{1}] = ", name, i);

            if (tupleSize > 1)
            {
                sb.Append("[");

                for (int j = 0; j < tupleSize; ++j)
                {
                    index = i * tupleSize + j;

                    if (j != 0)
                    {
                        sb.Append(",");
                    }

                    sb.AppendFormat("{0}", arr[index]);
                }

                sb.AppendLine("]");
            }
            else
            {
                sb.AppendFormat("{0}\n", arr[i]);
            }
        }

        HEU_Logger.Log(sb.ToString());
    }