Qustion on GUI Buttons in Max

If you feel like you're up to the challenge of building your own Ages in Blender or 3ds Max, this is the place for you!

Qustion on GUI Buttons in Max

Postby TheMagician » Sun Dec 04, 2011 12:52 pm

Hi everyone.

I want to have a clickable button in my GUI that triggers an animation in the age (think of the rings puzzle GUI in Kadish).
My questions are:

1) Which components do I need to assign to a GUI button?

2) Is it possible to activate the animation triggered by the button inside Max (with responders) or is this only possible via Python scripts?
TheMagician
 
Posts: 110
Joined: Mon Mar 29, 2010 3:14 pm

Re: Qustion on GUI Buttons in Max

Postby Christopher » Sun Dec 04, 2011 1:19 pm

First of all you need a new Page in your Age-file. Then you need a Camera, which points to your button. Later in Uru you see the button through this camera. Then your Camera and your Button needs a "GUI Dialog"-Component. This is something like a PageInfo for GUIs, so you don't need to assign a PageInfo-Component to GUIs. That's all the Camera needs. The GUI-Button also needs a "GUI Button" Component (i think there is nothing to change) and a "GUI ID Tag"-Component. In this Component you have to set a special number, which is later used in your Pythonfile to identify your Button. That's all I think.

To your second question: You have to do it through Python.
Here a simple template:
Code: Select all
from Plasma import *
from PlasmaTypes import *
from PlasmaConstants import *
from PlasmaKITypes import *
# define the attributes that will be entered in max
GUIDiag4b   = ptAttribGUIDialog(1, "GUI Dialog 4b")
ClickToShow = ptAttribActivator(2, "Activator to show your GUI") #You have to click something to show the GUI...
#globals
kButtonID = 1 #this is the Tag ID you defined in Max
kGUIName = "MyDialog" #Enter here the Name of the .prp from your GUI (without the age_district_ at the beginning)

class xyz(ptModifier):
    def __init__(self):
        [...]
   
    def OnFirstUpdate(self):
        PtLoadDialog(kGUIName,self.key,PtGetAgeName()) #Load the Dialog into your Cache

    def OnNotify(self,state,id,events):
        if id == ClickToShow.id:
            if PtGetLocalAvatar() == PtFindAvatar(events): #Is it your Avatar who clicked the Button?
                PtShowDialog(kGUIName) #Finally show the dialog
   
    def OnGUINotify(self,id,control,event):
        if control:   
            tagID = control.getTagID() #get the Tag ID from the triggered Component
        if id == GUIDiag4b.id: #Is it really your GUI?
            if  tagID == kButtonID: #Is it your Button?
                #enter here what you want to happen if the button is pressed       


Christopher

EDIT: You can also have to hide the dialog with PtHideDialog(dialogname), e.g. with an additional button in the GUI.
Last edited by Christopher on Wed Dec 07, 2011 5:16 am, edited 2 times in total.
User avatar
Christopher
 
Posts: 276
Joined: Mon Jul 19, 2010 3:25 am

Re: Qustion on GUI Buttons in Max

Postby TheMagician » Sun Dec 04, 2011 3:39 pm

And where do I have to place the Python file? Do I have to attach it to the object that also triggers the GUI?
Also, does it have to be a ptModifier or ptResponder class? (I don't actually get the difference there)
TheMagician
 
Posts: 110
Joined: Mon Mar 29, 2010 3:14 pm

Re: Qustion on GUI Buttons in Max

Postby Christopher » Sun Dec 04, 2011 3:48 pm

It doesn't really matter on which object you apply the Python component, as long as you give the right inputs to it. I also don't really know what's the difference between ptModifier and ptResponder, but I would use the second one, because you want to do something, which you would normally do with a Responder-Component in Max.

Christopher

EDIT: I saw in Cyans code, that they are using ptModifier. There are also some other things I forget to say, but I have to go to bed now. I will update my Python code tomorow.
User avatar
Christopher
 
Posts: 276
Joined: Mon Jul 19, 2010 3:25 am

Re: Qustion on GUI Buttons in Max

Postby TheMagician » Sun Dec 04, 2011 4:01 pm

Well then good night - it's midnight here as well :)
I'll play around with the information you've provided me with so far and am looking forward to your update.
TheMagician
 
Posts: 110
Joined: Mon Mar 29, 2010 3:14 pm

Re: Qustion on GUI Buttons in Max

Postby TheMagician » Tue Dec 06, 2011 2:03 pm

I've got the script up and running! :)

However, the line
Code: Select all
if PtGetLocalAvatar = PtFindAvatar(events):

needs to be updated to
Code: Select all
if PtGetLocalAvatar == PtFindAvatar(events):


I understand most of the script but could you explain what the 'control' refers to in this part:
Code: Select all
def OnGUINotify(self,id,control,event):
        if control:   
            tagID = control.getTagID() #get the Tag ID from the triggered Component

Is it the TagID of the GUI Dialog component that I've assigned in Max?

And finally, is there a list where you get an overview over all the different constants that 'event' can be? I saw Cyan use stuff like
Code: Select all
if event == kDialogLoaded

or
Code: Select all
if event == kMultiStageEvent
TheMagician
 
Posts: 110
Joined: Mon Mar 29, 2010 3:14 pm

Re: Qustion on GUI Buttons in Max

Postby Tsar Hoikas » Tue Dec 06, 2011 3:54 pm

[Beware of lazy formatting]

Even better:

Code: Select all
if PtGetLocalAvatar() == PtFindAvatar(events):


PtGetLocalAvatar will never equal PtFindAvatar(events) because PtGetLocalAvatar is a method :P. You need to actually execute the method and compare the returned value.

------

The control is a ptGUIControl. We want to make sure it's not None (nothing, null, etc), then we grab the tagID (which is what you set in max). We then compare this tagID with the tagIDs for all the controls we have and do the appropriate logic.


------

PlasmaConstants.py and PlasmaTypes.py are helpful
Image
Tsar Hoikas
Councilor of Technical Direction
 
Posts: 2180
Joined: Fri Nov 16, 2007 9:45 pm
Location: South Georgia

Re: Qustion on GUI Buttons in Max

Postby TheMagician » Tue Dec 06, 2011 4:47 pm

PtGetLocalAvatar will never equal PtFindAvatar(events) because PtGetLocalAvatar is a method

Now that explains why WITH this line the script never triggered the action ;)

Thanks also for the information on ptGUIControl and constants.

Right now I'm working on exiting back out of my GUI. I copied this section from one of Cyan's files:
Code: Select all
def OnControlKeyEvent(self, controlKey, activeFlag):
        if (controlKey == PlasmaControlKeys.kKeyExitMode):
            print 'CONTROL KEY PRESSED'
            self.ICloseGUI()           
        elif ((controlKey == PlasmaControlKeys.kKeyMoveBackward) or ((controlKey == PlasmaControlKeys.kKeyRotateLeft) or (controlKey == PlasmaControlKeys.kKeyRotateRight))):
            print 'CONTROL KEY PRESSED'
            self.ICloseGUI()

I also set
Code: Select all
PtEnableControlKeyEvents(self.key)

when the GUI is opened.

And I also have the line
Code: Select all
import PlasmaControlKeys

at the top of my script.

Unfortunately no key presses (like ESCAPE or LEFT / RIGHT ARROW) are recognized. The log file shows that the commands are never triggered.
Any idea what I'm missing?
TheMagician
 
Posts: 110
Joined: Mon Mar 29, 2010 3:14 pm

Re: Qustion on GUI Buttons in Max

Postby Tsar Hoikas » Tue Dec 06, 2011 5:31 pm

Hmmm... Where exactly is "at the top of my script?" PtEnableControlKeys() should really only be used once your GUI is engaged, and it definitely should not be used before OnFirstUpdate executes. Once the player disengages from it, you will want to stop catching control key events.
Image
Tsar Hoikas
Councilor of Technical Direction
 
Posts: 2180
Joined: Fri Nov 16, 2007 9:45 pm
Location: South Georgia

Re: Qustion on GUI Buttons in Max

Postby TheMagician » Wed Dec 07, 2011 2:41 am

I hope this isn't asked for too much but perhaps you could have a look at my Python file.
I think I followed all your pieces of advice but still the log file shows that the keystrokes are not recognized.

Code: Select all
from Plasma import *
from PlasmaTypes import *
from PlasmaConstants import *
from PlasmaKITypes import *
import PlasmaControlKeys

GUIDiag   = ptAttribGUIDialog(1, 'GUI Dialog')

GUIActivator = ptAttribActivator(2, 'Activator: Sub Camera')

SubmarineAnimPart1 = ptAttribAnimation(3, 'anim: Sub Part 1')
SubmarineAnimPart2 = ptAttribAnimation(4, 'anim: Sub Part 2')
SubmarineAnimPart3 = ptAttribAnimation(5, 'anim: Sub Part 3')

SubCamera = ptAttribSceneobject(6, 'Sub Camera')

kGUIName = 'gui_subvignette'
kGUICamSubButton1 = 101

boolGUIActivated = 0

class tageSubCam(ptModifier):
    __module__ = __name__
   
    def __init__(self):
        ptModifier.__init__(self)
        self.id = 555003
        self.version = 1


    def OnFirstUpdate(self):
        PtLoadDialog(kGUIName, self.key, PtGetAgeName())
       
    def OnServerInitComplete(self):
        ageSDL = PtGetAgeSDL()
        ageSDL.setNotify(self.key, 'CamSubPart', 0.0)
        solo = true
        if len(PtGetPlayerList()):
            solo = false
        boolGUIActivated = ageSDL['CamGUIActivated'][0]
        if boolGUIActivated:
            if solo:
                print ('Correcting AgeSDL Variable boolGUIActivated to 0')
                boolGUIActivated = 0
                ageSDL['CamGUIActivated'] = (0,)

       
    def OnNotify(self, state, id, events):
        ageSDL = PtGetAgeSDL()
        if id == GUIActivator.id:
            print 'ACTIVATOR PRESSED'
            if PtGetLocalAvatar() == PtFindAvatar(events):
                if ageSDL['CamGUIActivated'][0] == 0:
                    self.IOpenGUI()
                               
   
    def OnGUINotify(self, id, control, event):
        ageSDL = PtGetAgeSDL()
        if control:   
            tagID = control.getTagID()
        if id == GUIDiag.id:
            if  tagID == kGUICamSubButton1:
                print 'BUTTON PRESSED'
                newstate = (ageSDL['CamSubPart'][0] + 1)
                if newstate == 4:
                    newstate = 1
                ageSDL['CamSubPart'] = (newstate,)


    def OnSDLNotify(self, VARname, SDLname, playerID, tag):
        ageSDL = PtGetAgeSDL()
        newstate = ageSDL[VARname][0]
        code = (('SubmarineAnimPart' +  str(newstate)) + '.animation.play()')
        exec code
   
   
    def OnControlKeyEvent(self, controlKey, activeFlag):
        if (controlKey == PlasmaControlKeys.kKeyExitMode):
            print 'CONTROL KEY PRESSED'
            self.ICloseGUI()           
        elif ((controlKey == PlasmaControlKeys.kKeyMoveBackward) or ((controlKey == PlasmaControlKeys.kKeyRotateLeft) or (controlKey == PlasmaControlKeys.kKeyRotateRight))):
            print 'CONTROL KEY PRESSED'
            self.ICloseGUI()
           
   
    def IOpenGUI(self):
        ageSDL = PtGetAgeSDL()
        print 'OPENING GUI'
        ageSDL['CamGUIActivated'] = (1,)
        PtSendKIMessage(kDisableKIandBB, 0)
        PtEnableControlKeyEvents(self.key)
        cam = ptCamera()
        cam.undoFirstPerson()
        cam.disableFirstPersonOverride()
        virtCam = ptCamera()
        virtCam.save(SubCamera.sceneobject.getKey())
        PtShowDialog(kGUIName)
   
   
    def ICloseGUI(self):
        ageSDL = PtGetAgeSDL()
        print 'CLOSING GUI'
        PtHideDialog(kGUIName)
        virtCam = ptCamera()
        virtCam.restore(SubCamera.sceneobject.getKey())
        PtDisableControlKeyEvents(self.key)
        PtSendKIMessage(kEnableKIandBB, 0)
        cam = ptCamera()
        cam.enableFirstPersonOverride()
        ageSDL['CamGUIActivated'] = (0,)

TheMagician
 
Posts: 110
Joined: Mon Mar 29, 2010 3:14 pm

Next

Return to Building

Who is online

Users browsing this forum: No registered users and 2 guests

cron