Game Development Community

Mini Behavior Tutorial

by Phillip O'Shea · in Torque Game Builder · 10/12/2007 (3:53 am) · 24 replies

Creation:

Behaviors are created in the same manner as regular script entities are. Below is some example code of how to create a behavior, and some of its various features:

if (!isObject(ExampleBehavior))
{
    %template = new BehaviorTemplate(ExampleBehavior);
	
    %template.friendlyName = "My Example Behavior";
    %template.behaviorType = "Example";
    %template.description  = "Just showing you a few properties";
	
    %template.addBehaviorField(eName, "Example Field", default, "Default Value");
}

It is pretty simple stuff when you look at it like that, however, there are some really awesome properties that you should take advantage of when managing behaviors. One of which are the different field types. I will list all of the field types and their descriptions below:

1. Default - Plain ol' input text box, nothing really fancy here,
2. Int - Input text box, which requires an integer to be entered,
3. Float - Input text box, requiring a float with 3 decimal points,
4. Point2F - Two input boxes, registering as a vector,
5. Bool - Nice lil checkbox,
6. Enum - Drop down list, data is controlled by the userData field,
7. Object - Drop down list, containing any object with the class defined in the userData field,
8. Keybind - Drop down list, containing all of the keyboard and joystick keys available,
9. Color - Color picker popup,
10. polygon - Creates a polygon using the parent object,
11. localpointlist - Local point using the parent object.

There are 9 different fields, many of them are self explanatory, however, the "Enum" and "Object" field types may be confusing for some.

Enum

%template.addBehaviorField(eList, "Example List", Enum, "Second Item", "First Item" NL "Second Item\nThird Item");

When you specify the "Enum" field type, you must specify what values go into that list. It is done in the last parameter of the "addBehaviorField" function, named "userData". To create the list, you just specify it like above. Each item should be separated by a new line (NL) operator, or, using the "\n" escape sequence. Be careful of spaces! To specify a default value you must type out the full name of the list item. I could be wrong, but I do not think you can just specify which index value the item is.

This wraps up the Enum field type.

Object

%template.addBehaviorField(eAnimation, "Example Animation", Object, "exampleAnimation", t2dAnimationDatablock);

In the above example, I have specified that the list object must contain all of the objects within the "t2dAnimationDatablock" class. I have been scripting an animation behavior for a series of scene objects and found it rather handy to have a list of all of the animations available, rather than having to type them all out.

You can specify any class type in your userData field and it will list each of the objects in that subset, handy huh?

Custom Field Types

//Specify the Name of the object type, and the function that is called to create the field
BehaviorEditor::registerFieldType("NewObject", "createNewObjectGui");


function BehaviorFieldStack::createNewObjectGui(%this, %behavior, %fieldIndex)
{
   %fieldInfo = %behavior.template.getBehaviorField(%fieldIndex);
   %name = getField(%fieldInfo, 0);
   %description = %behavior.template.getBehaviorFieldDescription(%fieldIndex);
   
   %control = %this.createTextEditProperty(%name, "TEXT", %name, %description);
   %editField = %control.findObjectByInternalName(%name @ "TextEdit");
   %editField.object = %behavior;
}

You must first register your new object, then you must specify a function name that is called when an object using your behavior is selected. In this example, I have just created a regular text box which inputs ordinary text. However, it acts just like regular GUI objects do, in that you create them, specify names and other properties through script.

I hope this has helped out with some of the unknown things about behaviors!

Update: Added the two new field types added in 1.7.X.

About the author

Head of Violent Tulip, a small independent software development company working in Wollongong, Australia. Go to http://www.violent-tulip.com/ to see our latest offerings.

Page «Previous 1 2
#1
10/12/2007 (7:24 am)
Fantastic! Thanks. You should add this to the Wiki.

Thanks for a listing of all of the field types.

I did not quite get the Object one but from what I can gather from it, I think it may be something I want to use. I'd like to study/research the Object and Custom Field Types a bit more.

Thanks again. I just keep enjoying Behaviors more and more.
#2
10/12/2007 (1:17 pm)
Steven, if you want to check out custom field types a little more, I suggest you check out the "fieldTypes.ed.cs" file located in "InstallDir\TorqueGameBuilder\tgb\tools\behaviorEditor\Scripts". It contains all of the information listed above, and will help out in explaining a few more things about custom fields that I have not.

With regards to the Object field type, basically, it will list every object that has the class that you specify in the userData field. I used "t2dAnimationDatablock" to list all of the animated sprites available, you could change it to "t2dImageMapDatablock" to get all of the regular imagemaps. Finally, you could change it to "MyClass", and any object that is within your level with class "MyClass" will appear on that list.

I'll throw it up on the wiki one day, just thought I'd put it here first.

Glad I could help.
#3
10/12/2007 (3:14 pm)
I will check out fileldType.ed.cs. Thanks for the pointer.

Regarding Object field type: That's what I was hoping you meant! Actually, turns out I've been using it all this time. But I only used it for one type (t2dSceneObject) as that was the example I saw for it. It never occured to me to try different types of objects.
#4
10/12/2007 (6:53 pm)
Couple of questions:

First of all, your Object example:

%template.addBehaviorField(eAnimation, "Example Animation", [b]Enum[/b], "exampleAnimation", t2dAnimationDatablock);

You listed the fieldtype as Enum. I'm guessing you meant to put Object there?


Second, your Enum example:

%template.addBehaviorField(eList, "Example List", Enum, [b]"Second Item"[/b], "First Item" NL "Second Item \n Third Item");

In the area I added bold to, I can change that string to whatever I want and it doesn't seem to affect anything. I've looked in the fieldTypes.ed.cs as you suggested but I still can't figure out what purpose that string has. In fact, it doesn't seem to do anything at all. So what is the purpose of it?

EDIT: Also, could you supply an example of how/where to put the UserData to give some meaning to the drop down lists?
#5
10/12/2007 (7:36 pm)
Deozaan,

Thank you for the Enum/Object correction.

With regards to the example, the "Second Item" string is the default value of the field. In this case, there is a SPACE after the word "Item" in the list, so, it really should read:

%template.addBehaviorField(eList, "Example List", Enum, "Second Item", "First Item" NL "Second Item\n Third Item");

And now it should display the "Second Item" as the default selection.

As to your final question, I'm not 100% sure I understand it properly. The Enum field type generates a drop down menu, where the userData field specifies what is in that list. Each item is separated by an NL or "\n". That okay?
#6
10/12/2007 (11:15 pm)
Thanks Phillip,

That really clears things up. I guess I didn't understand what you meant by userData in the first post.

Oh, another thing: I copied your example into a test behavior and with the way you have the space around the \n it puts an extra space after Second Item (which you already caught) and before Third Item. So Third Item is indented a space.

Thanks again!
#7
10/13/2007 (2:54 pm)
Okay I've got another question:

Quote:With regards to the Object field type, basically, it will list every object that has the class that you specify in the userData field. I used "t2dAnimationDatablock" to list all of the animated sprites available, you could change it to "t2dImageMapDatablock" to get all of the regular imagemaps. Finally, you could change it to "MyClass", and any object that is within your level with class "MyClass" will appear on that list.

I'm trying to set up an Object list with a custom class. This is my code:

%template.addBehaviorField(testClass, "Test Class", Object, "baddy", mob);

In the Level Builder, I have an object and in the scripting section I have it named "baddy" with the Class "mob" -- But in the dropdown list it just says "None"

Do I need to define the class somewhere in script or should setting the class in the Level Builder be sufficient?

Thanks in advance.
#8
10/13/2007 (3:12 pm)
if( !%sceneObject.isMemberOfClass( %objectType ) )
         continue;

The above lines are in "fieldTypes.ed.cs". This will only find t2d class objects, not ones that you have written. For example:

t2dStaticSprite
t2dAnimatedSprite
t2dTrigger
t2dScroller
t2dSceneObject
SimSet
SimObject
ect

You could always change that line to:

if( %sceneObject.Class !$= %objectType )
         continue;

This will grab the regular ol' class types that you can specify and use them instead. If you did this, you should probably create your own field type rather than fiddling with theirs.
#9
10/13/2007 (3:19 pm)
Thanks again Phillip!

Would you recommend making my own field type right there in fieldTypes.ed.cs or somewhere else?
#10
10/13/2007 (4:36 pm)
Awesome it works!

In case anyone else wants to do something similar, they'll need to be sure to change that code twice in the custom fieldtype. Once for %sceneObject.Class and once for %object.Class.

Alright now another question or two: Is there an easy way I can customize the list of classes it looks for without hardcoding it into the behavior?

Can I specify more than one class for the dropdown list?
#11
10/22/2007 (11:22 am)
Deozaan,

I am guessing and have tested this, but my guesses are...

Quote:Is there an easy way I can customize the list of classes it looks for without hardcoding it into the behavior?

Object isn't a *list* of classes, but a single class. And yes, it needs to be hard coded, but you can use base object class and then you can use any subclass of the type. See below.

Quote:Can I specify more than one class for the dropdown list?

In a way you can by using a base class. For example, by setting Object to the ChildClass, you can then use both the SonClass and the DaughterClass.
#12
10/22/2007 (11:49 am)
Thanks Chaim.

To be honest I don't understand what you just said, but as you'll see from the rest of this message, clarification probably isn't necessary.

After I thought more about what I needed I realized that the custom entry in the fieldTypes.ed.cs was unnecessary. I think it would still be useful in other situations, but I've adapted the original change to my specific needs, and I've got something fairly flexible worked out with it.

I'll write more details in a .PLAN this week or next probably. Or you can read what I've written about it already at the Docoto Defense blog.

An Aside: It's too bad you can't enter a value in a behavior in the Level Builder and have it auto-populate the drop down list. Now that would be useful!
#13
11/04/2007 (9:41 am)
I have finally started looking at 'fieldTypes.ed.cs'. Unfortunately, I only have the compiled versions of these files. I suspect I need TGB Pro.

I created a behavior to play a sound when you click on an object. You type in the exact sound name. I was hoping to change this behavior so I can use the Object field type and have it display all of the AudioProfile objects. I tried it, but I don't see the AudioProfiles listed in the dropdown list.

%template.addBehaviorField(aSound, "Sound test", Object, "", AudioProfile);

Since AudioProfile derives from SimDataBlock (based on the TGB documentation), I changed to use SimDataBlock just to see if the AudioProfiles would show up.

%template.addBehaviorField(aSound, "Sound test", Object, "", SimDataBlock);

Nope. I just get a listing of all the static sprites for the level.

I currently exec my AudioDatablocks.cs file during initializeProject in main.cs. I changed this to exec from the game/gameScripts/datablocks.cs file thinking it may be some order of loading type of issue, but I still did not see the AudioProfiles.

Anyone know how to access the list of AudioProfiles for the object field of a behavior?
#14
11/04/2007 (4:25 pm)
I think the problem is that fieldTypes.ed.cs looks through all the SceneObjects listed in the SceneGraph. But AudioProfiles have the following heirarchy:

AudioProfile -> SimDatablock -> SimObject

and SceneObjects have the following heirarchy:

SceneObject -> BehaviorComponent -> DynamicConsoleMethodComponent -> SimComponent -> SimObject

So when you're trying to find your objects using the method in fieldTypes.ed.cs, you're way down the list in SceneObject land when you need to back all the way back to SimObject and work your way down to AudioProfile. In other words, using the method in fieldTypes.ed.cs, you get a list of all SceneObjects, and AudioProfiles are not SceneObjects.

If you can figure out how to get a list of all SimObjects then you can get a drop down of all AudioProfiles. If not, then I suggest in the meantime using a manually created SimSet array of all AudioProfiles which you can use to iterate through the list and make a dropdown. But I suppose if you're manually making a list anyway, you might as well manually make the dropdown list itself.
#15
11/04/2007 (5:03 pm)
Steven, Can you create a Custom Field Type to meet your needs?
#16
11/04/2007 (8:38 pm)
Chaim, what is a Custom Field Type?

Deozaan, I am able to show all of the SimDataBlocks, but this does not display the Audio Profiles. I do see all the static sprites for the project.

Yes. I thought of simply making an Enum type, but then I figured it's best to just leave it as an edit box.

I am trying to create some new Behaviors to post on the site. So although they are for my own needs, I am also trying to make them as generic as possible so others can easily use them. I guess what I am trying to say is I am attempting to create the Behaviors so others don't have to edit code or do anything extra.
#17
11/04/2007 (9:14 pm)
Steve, look at the first posting in this thread for info on Custom Field Type.
#18
11/04/2007 (11:15 pm)
Steven,

If you can tell me how to get a list of all SimDatablocks I'll see what I can do to get the AudioProfiles working. I couldn't figure out how to get a list of SimDatablocks.

I could be wrong, but I don't think you're really getting a list of SimDatablocks. I think the static sprites are t2dStaticSprite which are derived from SceneObjects. I've looked over the code in FieldTypes.ed.cs and customized it a lot for my own needs. To my knowledge, everything it gets a list from is from the list of SceneObjects in the SceneGraph. If you look again at my heirarchy, t2dStaticSprites -> SceneObjects are on a completely different tree than AudioProfiles->SimDatablock. I think this is the root of your problem of not being able to get the list of AudioProfiles. Because the methods used in FieldTypes.ed.cs only look through the sceneObjects in the SceneGraph.

I should also note that they also search through the $managedDatablockSet, but I don't think AudioProfiles/SimDatablocks are in the managedDatablockSet, since before responding to your initial question I spent a good amount of time trying to customize the code in FieldTypes.ed.cs to look specifically for AudioProfiles already, so it iterated through all my SceneObjects and the managedDatablockSet and it didn't find them.

So again, in the meantime, if you want a dropdown in the behavior list in the Level Builder, I'd go with the manually built enum list. But if you don't mind typing out your AudioProfiles for each behavior, edit boxes work too.
#19
11/05/2007 (7:17 am)
Chaim: Oops. Thanks. I had skimmed back over the posts looking for Custom Field Types, and missed that. Thanks for pointing it out to me.

Deozaan: I used the following code to display SimDataBlocks:

%template.addBehaviorField(aSound, "Sound test", Object, "", SimDataBlock);

This listed all of my ImageMap's, which I am calling the static sprites.

Creating the Enum may work for my own game, but I really want this to be easy for others to use without having to require anyone to write any code. I was hoping for an easy way to get the AudioProfiles to show up in a dropdown. This makes things really easy because then the user does not even need to remember the exact AudioProfile name.
#20
12/28/2007 (7:48 pm)
It seems that as of version 1.6, doing something like this:

%template.addBehaviorField(eAnimation, "Example Animation", Object, "exampleAnimation", t2dAnimationDatablock);

no longer works. It creates a dropdown with only the option for selecting "None". I have only tried using t2dAnimationDatablocks and t2dAnimatedSprites, which should be the default built-in classes that work with the editor, right? Am I missing something incredibly simple?
Page «Previous 1 2