Home Technical Talk

Doubletap maxscript issues (3Ds Max 2016)

polycounter lvl 5
Offline / Send Message
leplatin polycounter lvl 5
I have issues with Doubletap script from this thread. Say I want to toggle Top/Bottom views, single tap does nothing

macroscript Top_Bottom
Category:"_custom"
toolTip:"Top/Bottom Toggle"
(         
    fn checklastClicked = (
        local thisClicked = timeStamp()
        if lastClicked != undefined then (
            if (thisClicked - lastClicked) < 500 do (
            actionMan.executeAction 0 "40063" --DOUBLETAP OK<br>			)
            lastClicked = thisClicked
        )
        else (
        actionMan.executeAction 0 "40059" --SINGLETAP ??? doesn't work<br>        )
        OK        
    )
    checklastClicked()
)


But this variant is working fine (combined with this script) I'm on Max 2016. What I'm doing wrong?

macroscript Top_Bottom
Category:"_custom"
toolTip:"Top/Bottom Toggle"
(
    actionMan.executeAction 0 "40059" --SINGLETAP
    global lastClicked<br>

            
    fn checklastClicked = (
        local thisClicked = timeStamp()
        if lastClicked != undefined then (
            if (thisClicked - lastClicked) < 500 do (
            actionMan.executeAction 0 "40063" --DOUBLETAP OK
			)
            lastClicked = thisClicked
        )
        else (
        actionMan.executeAction 0 "40059" --SINGLETAP ??? doesn't work
        )
        OK        
    )
    checklastClicked()
)
Weird...After restart only single tap working  :/ 
UPD. Its more weird what script is only working after I launched another test script

macroScript toggle
Category:"All Commands Custom Toggles"
toolTip:"Toggle"
(
    max select
    global lastClicked
        
    fn checklastClicked = (
        local thisClicked = timeStamp()
        if lastClicked != undefined then (
            if (thisClicked - lastClicked) < 500 do (
            max rotate
			)
            lastClicked = thisClicked
        )
        else (
            max move 
            lastClicked = timeStamp()
        )
        OK        
    )
    checklastClicked()
)

UPD. As far as I understand I've something to deal with "global lastClicked" variable. But one thing I don't understand why first script (Top/Bottom Toggle) does't work until I'll run second script(Toggle), but this second script working fine in all cases. 

Replies

  • Swordslayer
    Options
    Offline / Send Message
    Swordslayer interpolator
    Because 'global lastClicked' creates the variable that holds last click time in global scope, i.e. for anyone to access. You shouldn't make it a global btw., it should be local to the macro - otherwise clicking one shortcut afer you've run previous shortcut that uses the same variable will be considered double click.
  • leplatin
    Options
    Offline / Send Message
    leplatin polycounter lvl 5
    But is first script from Mark Dygert correct? I tried  local variables but without success.
  • Cathodeus
    Options
    Offline / Send Message
    Cathodeus polycounter lvl 14
    You should probably want to try Keyhydra [Available on 2017, 2018, soon 2019]. it provide double to quadra tap and much more. Installer provide a 2016 version but we don't support it anymore. [no debug] it's a client courtesy.
    https://www.youtube.com/channel/UCfGfWDu0e_aaYBX1CdXzaWw

  • Swordslayer
    Options
    Offline / Send Message
    Swordslayer interpolator
    leplatin said:
    But is first script from Mark Dygert correct? I tried  local variables but without success.
    The one you posted here is also missing the 'on execute' handler so everything in the scope gets recreated everytime. I think it should look like this instead (untested):


    (
    	local lastClicked = -500
    
    	fn checklastClicked = 
    	(
    		local thisClicked = timeStamp()
    
    		if (thisClicked - lastClicked) < 500 do (
    			actionMan.executeAction 0 "40063" --DOUBLETAP
    		)
    		else (
    			actionMan.executeAction 0 "40059" --SINGLETAP
    		)
    		lastClicked = thisClicked    
    	)
    
    	on execute do checklastClicked() -- only this part will now be execute
    )

  • leplatin
    Options
    Offline / Send Message
    leplatin polycounter lvl 5
    Thanks, but it gives
    "-- Syntax error: at else expected <factor
    -- In line else ("

    As far as I know you could't define a local variable from the top level of MAXScript,  because you will receive an error message
  • Axi5
    Options
    Offline / Send Message
    Axi5 interpolator
    Replace "do" in the if statement on line 7 with "then", Maxscript is funny like that.
  • leplatin
    Options
    Offline / Send Message
    leplatin polycounter lvl 5
    Yeah  pretty funny :#
    It works, thank you!
  • leplatin
    Options
    Offline / Send Message
    leplatin polycounter lvl 5
    Another question. Is it possible to toggle between actionMans? Something like this, but script doesn't work too

    (
    global topbottom
    if topbottom != true then 
        (actionMan.executeAction 0 "40059" -- Views: Top View
        topbottom=true
        )
    else 
        (actionMan.executeAction 0 "40063" -- Views: Bottom View
        topbottom = false
            )
    )        
    
    
  • Axi5
    Options
    Offline / Send Message
    Axi5 interpolator
    Any error messages when you run it?
  • leplatin
    Options
    Offline / Send Message
    leplatin polycounter lvl 5
    No error, but viewport only changes to Top view.
  • monster
    Options
    Offline / Send Message
    monster polycounter
    You have a logic error. topbottom will never == true.

    But you can do this action without globals.

    (	
    	viewNumber = if viewport.getType() == #view_top then "40063" else "40059"
    	actionMan.executeAction 0 viewNumber
    ) 

  • Mark Dygert
    Options
    Offline / Send Message
    1) Remove the definition at the top
     You shouldn't use global variables when you don't need to. If you're pulling from my old doubletap script I was declaring globals because I used them in other scripts that where not part of that script. There are better ways to handle it especially if you aren't working between scripts.

    It looks like in this case, you don't need to declare a variable at the top at all, local or global. In fact, that is screwing up the script by always setting it to "undefined" each time the script runs, before it gets to your first check, it gets set to "undefined". Just remove it.

    Normally you only define something at the top of the script that needs to be defined
    Local topbot (returns undefined when topbot is called)
    Local topbot = BobMarley
    (returns undefined because it doesn't know what BobMarley is)
    Local topbot = "BobMarley" (returns "BobMarley" when topbot is called, because the quotes turn it into a string, which is something maxscript understands)
    Local topbot = true (returns true when topbot is called, because it understands true is a boolean)

    2) Switch your variable to something else
    It looks like "topbottom" means something to 3dsmax, I think it's a material class or something, it flags it in green text so that's bad. This means you can't use it as true/false variable, because it will return all kinds of crazy garbage that isn't true or false.Change the variable to something else that doesn't mean anything to 3dsmax, something like  "topbot".

    3) Use proper maxscript commands
    Personally you should try to stay clear of "actionman.executeAction" and find out the actual maxscript is for those actions in this case the maxscript help file says  says your code should look something like this:

    (
    	print ("topbot started as: " + topbot as string)
    	if topbot != true then 
    	(
    		max vpt top
    		topbot = true
    		print ("topbot was set to: " + topbot as string)
    	)
    	else 
    		(
    			max vpt bottom
    			topbot = false
    			print ("topbot was set to: "  + topbot as string)
    		)
    )   


    4) Print will help you debug
    You can check what your variables are set to by using the "print" command and checking the maxscript listener after you run the script.

    Print topbot (returns whatever it is at that point in the script)

    By using the print command at different parts of the script you can see what it's being set to. There are a lot of other helpful commands like:Show $ (shows the properties of selected object) and ClassOf $ (shows the class of the selected object), but we're starting to get off subject =P
  • leplatin
    Options
    Offline / Send Message
    leplatin polycounter lvl 5
    Thank you guys!
Sign In or Register to comment.