Below is an example demonstrating how you can 'freeze' (link) the current state of numeric properties on a node (or multiple nodes) to a controller property so that adjusting the controller property adjusts the linked properties in kind. The DzERCLink created between the “frozen' properties and the controller are setup such that when the controller is set to the value it is at when the 'freeze' is performed, the 'frozen' properties are at the respective values they were at that moment in time.
// Define an anonymous function; // serves as our main loop, // limits the scope of variables (function( oNode ){ /*********************************************************************/ // String : A function for retrieving a translation if one exists function text( sText ) { // If the version of the application supports qsTr() if( typeof( qsTr ) != "undefined" ){ // Return the translated (if any) text return qsTr( sText ); } // Return the original text return sText; }; /*********************************************************************/ // If the application is less than 4.9.3.95 if( App.version64 < 0x000400090003005f ){ // Define message components var sTitle = text("Resource Error"); var sMessage = text("This script requires version 4.9.3.95 or newer."); var sOk = text("&OK"); // Inform the user MessageBox.information( sMessage, sTitle, sOk ); // We're done... return; } // Initialize var oSkeleton = undefined; // If we have a bone if( oNode.inherits( "DzBone" ) ){ // Get its skeleton oSkeleton = oNode.getSkeleton(); // If we have a skeleton } else if( oNode.inherits( "DzSkeleton" ) ){ // That is what we're looking for oSkeleton = oNode; } // Define a controller; prefer a skeleton var oControllerNode = (oSkeleton ? oSkeleton : oNode); // Let the user know we're busy setBusyCursor(); // Declare a property group path var sPropertyGroup = "/ERC Freeze Test"; // Create and setup a controller property var oControllerProperty = new DzFloatProperty( "ERC_Freeze_Controller", false, true ); oControllerProperty.setLabel( "ERC Freeze Controller" ); oControllerProperty.setPath( sPropertyGroup ); oControllerProperty.setMinMax( -1, 1 ); oControllerProperty.setIsClamped( true ); oControllerNode.addProperty( oControllerProperty ); // Create and setup an attenuation property var oAttenuateProperty = new DzFloatProperty( "ERC_Freeze_Attenuate", false, true ); oAttenuateProperty.setLabel( "ERC Freeze Attenuate" ); oAttenuateProperty.setPath( sPropertyGroup ); oAttenuateProperty.setMinMax( -1, 1 ); oAttenuateProperty.setIsClamped( true ); oControllerNode.addProperty( oAttenuateProperty ); // Create the ERC Freeze utility var oFreezer = new DzERCFreeze(); // Set the controller node oFreezer.setControllerNode( oControllerNode ); // Set the controller property oFreezer.setControllerProperty( oControllerProperty ); // Set the type of attentuation oFreezer.setAttenuateMode( DzERCFreeze.SubComponents ); // Set the attentuation property oFreezer.setAttenuateProperty( oAttenuateProperty ); // Declare working variable var oCurNode; // Build the list of nodes with properties to freeze var aNodes = (oSkeleton ? [ oSkeleton ].concat( oSkeleton.getAllBones() ) : [oNode] ); // Iterate over the nodes for( var i = 0, n = aNodes.length; i < n; i += 1 ){ // Get the 'current' node oCurNode = aNodes[ i ]; // Add the node's properties oFreezer.addPropertiesToFreeze( oCurNode ); } // We're not using animated links oFreezer.setKeyed( false ); // Restore the figure when the freeze is complete oFreezer.setRestoreFigure( true ); // Restore the rigging when the freeze is complete oFreezer.setRestoreRigging( true ); // Apply the controller property when the freeze is complete oFreezer.setApplyController( true ); // Begin collecting undo-able operations UndoStack.beginHold(); // If the freeze is successful if( oFreezer.doFreeze() ){ // Create the undo item UndoStack.accept( text("ERC Freeze") ); // If the freeze fails } else { // Cancel the undo item UndoStack.cancel(); } // Let the user know we're done clearBusyCursor(); // Finalize the function and invoke })( Scene.getPrimarySelection() );