0
votes

I am trying to rotate a helper in my 3ds max scene by changing the value of a spinner. Currently changing the value of the spinner does drive a rotation on the helper and rotating the helper updates the value on the spinner. There are still a couple of behavioural problems with my script that I need help solving.

1) I want the rotation on the helper to occur only on the local euler Z axis of the helper however currently its rotation is erratic and occurring on multiple axes.

2) I want to constrain the helper's rotation between a range of -90 and 90 degrees currently it rotates much further than that.

My current code is as follows.

Spin_R_Custom_attribute = attributes custom_Attributes
(
 rollout SpinRollout "Helper Controls"
 (

    Spinner TheSpinner "The Spinner" range:[-10,10,0] controller: $Helper_R_Spin.rotation.z_rotation.controller \

    on TheSpinner changed spin do 
    (
        try (in coordsys local $Helper_R_Spin.rotation.z_rotation = spin) catch ()
    )
 )
)

Any help would be greatly appreciated.

2
Your code actually seems to work well if you remove the on TheSpinner changed clause entirely. The spinner is already linked to the rotation through its controller as you've set. And, I believe Rotation should always be in local space by virtue of setting the rotation controller value directly, because the raw controller value is inherently local. If you want to prevent movement beyond +-90 degrees even when manipulated in the viewport, you might have to apply an animation constraint or a scripted controller.MichaelsonBritt
@MichaelsonBritt: the controller value is guaranteed to be local if it's a nested controller like list controller.Swordslayer

2 Answers

0
votes

To have controllers work in local space, you will need to use a subcontroller of a list controller (just like what gets created when you freeze rotation/transform). That way, you also won't need the changed handler (and the try-catch, and the $Helper_R_Spin pathname that can be changed etc) at all since the controller will be instanced to the spinner controller. For limiting the range, see float_limit.

0
votes

The recommended technique for connecting parameters in this way is Parameter Wiring.

  • The custom attribute needs a parameter defined to hold the value, not just a spinner.
  • The very last piece of the code, "z_rotation" "cust_z" is actually a pair of equations that translation from rotation value to spinner and vice versa. So you can enter other mathematics in here, if you want to display the spinner in different units.

Example:

targ = $Helper_R_Spin

-- In case of running this multiple times, start by deleting the cust attrib
if cust_attrib!=undefined then
    custAttributes.delete targ cust_attrib

cust_attrib = attributes cust_attribs
(
    parameters AttribParams rollout:AttribRollout
    (
        cust_z type:#float range:[-10,10] ui:cust_spin
    )

    rollout AttribRollout "Helper Controls"
    (

        Spinner cust_spin "The Spinner" range:[-10,10,0]
    )
)

custAttributes.add targ cust_attrib
paramWire.connect2Way targ.cust_attribs[#cust_z] targ.rotation.controller[#z_rotation] "z_rotation" "cust_z"