Game Development Community

Global Variables from Editor?

by Eric Robinson · in Torque Game Builder · 02/19/2007 (5:42 pm) · 15 replies

I've started a new project in TGB 1.1.3. I'm currently playing around with the new t2dTextObjects and I put three of them into the level. I gave the them each a distinct "Name" in the Scripting rollout. I try to access them from both the console using console commands and from script and I get "Object not found" errors.

Anyone have any ideas on what I could be doing incorrectly?

Edit: I just checked and found that i can access the objects by their internal object identifiers (2106, for instance). It's as if something isn't properly getting saved.

Also, and this may be related, I'm having issues with Namespaces. I set a "class" variable upon object creation and then try to call a function written as [classvariable]::init() and it says that it can't find an 'init()' function. Ideas?

#1
02/19/2007 (8:58 pm)
@Eric [classvariable] would mean %var or $var ... which would make the :: calling syntax incorrect;

new t2dSceneObject(myObject)
{
  // config here
};

function myObject::init(%this)
{
  // code here
}

myObject.init();
#2
02/19/2007 (10:03 pm)
Back with Torque 1.1.2 I was able to do the following:
%obj = new t2dTextObject()
{
	class = "myClassName";
	...
};
Then I could use functions defined as in the following:
function myClassName::helloWorld()
{
	...
}
without issue. As far as I understood it, defining the "class" member variable for an object was enough to add it to the namespace. Is that incorrect?
#3
02/19/2007 (10:15 pm)
The number isn't static, it will change all over again.
What you would use is the name. This one is static and you can access named objects through name.someMethod() for example
#4
02/19/2007 (10:22 pm)
@Marc: Look at the MiniPlatformerTutorial. You add the "Name" variable to give an object a global identifier. In the MiniPlatformerTutorial, the player gets called "pGuy". You can then access him script-side by calling $pGuy.blah(), etc.

We give the player the "Class" variable "playerClass" and then define functions script-side using "playerClass::someFunction(%this)", etc. When you look at the level.t2d file you see that the class variable comes out as a member variable "class = playerClass". The object is created as "new t2dSceneObject(pGuy)" which I don't completely understand... but that's where the 'name' goes.

Is that how the name is passed? Such that calling "%obj.getName()" on $pGuy would return "pGuy"? And aren't those supposed to be object-unique?

Also, I know that the number isn't entirely static... it's static for the duration of its instantiated life, however. As I understand it, that's the name that the engine gives the object for internal use...
#5
02/19/2007 (10:48 pm)
@Eric - Names don't get converted into $ variables, you just use the name directly, so you would use pGuy.someFunction() not $pGuy.someFunction() . I'm guessing that this part of that tutorial caused your confusion:
Quote:
function playerClass::onLevelLoaded(%this, %scenegraph)
{
$pGuy = %this;

moveMap.bindCmd(keyboard, "left", "playerLeft();", "playerLeftStop();");
moveMap.bindCmd(keyboard, "right", "playerRight();", "playerRightStop();");
moveMap.bindCmd(keyboard, "space", "playerJump();", "");
}
$pGuy working like that is a special case in the tutorial because of that line of code (which really only works if there's exactly one object of that class), not a general feature of torquescript.
#6
02/19/2007 (10:59 pm)
@Dan: Okay. But I gave each one of my t2dTextObjects it's own, unique "Name" variable in the editor rollout. So why can't I access those variables using the $ symbol? Note that I did not add a "Class" name to these objects. Thoughts? How do those differ, anyway (a global variable and one from the editor given a 'name')? I thought we always needed to use either $ or % for objects/variables in script...

Thanks for the help, by the way...

[Edited. I can do something I originally said I couldn't.]
#7
02/19/2007 (11:12 pm)
@Eric - No, you don't always need either $ or %. Here are three potentially different objects:

pGuy
$pGuy
%pGuy

If you gave your objects the names Alpha, Beta, and Gamma, you would do:

Alpha.someFunction()
Beta.someFunction()
Gamma.someFunction()

You wouldn't do $Alpha.someFunction() because $Alpha doesn't exist (unless you did some tricks somewhere to create it, like they did in that tutorial).
#8
02/19/2007 (11:18 pm)
As Dan said you do not need the $ operator for accessing objects via name. Just use the name directly.

Here is the difference:
new t2dSceneObject(myObject)
{
};
This assigns the object the name in parenthesis.

$myObject = new t2dSceneObject()
{
};
This assigns the object to global variable $myObject which has no name.

Essentially, the editor creates the former of the two when you assign it a name in the roll out so you would access it directly by name.
#9
02/19/2007 (11:20 pm)
@Dan: Okay, I think I'm starting to get it. Giving objects names is akin to giving them a Human-Readable-ID, right? The 'internal number' I mentioned above was the internal object ID.

I *also* found something out about my implementation. The trouble I was having with namespaces wasn't with the t2dTextObjects. I was doing the following:
%player1 = new SimObject()
{
	class = Player;
};
The problem came with the object being a SimObject(). Apparently Namespaces aren't appropriately calculated on those types of objects(?). I changed it to a t2dSceneObject and things worked perfectly.

The idea was that the "Player" object would be an 'abstract' [gamewise] object that pointed to all of the player data and was added to a SimSet called "Players". Calling "SimSet.getObject(%i).value.getText()" would ideally retrieve the text from the t2dTextObject who's reference was stored in the Players(%i) "Player" object, for instance.

Barring the fact that getText() appears to not be callable from script (yet), everything seemed like it should work out dandily. Why are SimObject's not aware of namespaces?
#10
02/19/2007 (11:41 pm)
@Eric -
Quote:Giving objects names is akin to giving them a Human-Readable-ID, right?
Yes, exactly.
Quote:Why are SimObject's not aware of namespaces?
I don't really know (or care :) ) why a lot of things work the way they do. But, I might suggest that you could solve your problem by using ScriptObject instead.
#11
02/20/2007 (8:07 am)
It's not that (as you suggested) that "SimObjects aren't aware of namespaces"--it's that when you create an object as a SimObject, you greatly reduce the available namespaces of that object--including the use of class and superclass.

Class and Superclass are designed specifically for use with either ScriptObjects, or anything that derives from t2dSceneObject--and SimObject isn't one of those classes.
#12
02/20/2007 (3:37 pm)
@Stephen/Dan: So how exactly do you use ScriptObjects? The Checkers tutorial shows the following code:
new ScriptClass(CheckerBoard);
From the TGB Reference it also appears that you only make one ScriptObject(?). The wording is weird:
Quote:ScriptObject is a dummy object that is used to store information. Creating a ScriptObject is similar to creating a class. You can define methods for it and add member variables to it. It is also derived from SimObject and thus includes all of the functionality provided by that as well.
My current, most-likely-incorrect understanding is that essentially you define the ScriptObject which makes a 'script class' of sorts. You then add methods to that class by using the namespace operator as in "function [ScriptObjectName]::foobar()". My understanding is that you would not instantiate objects of the ScriptObject type but offer [ScriptObjectName] to the "class" or "superClass" field of an object that derives from t2dSceneObject.

?

But then if that interpretation is correct then why even bother really when you can just add functions to a 'namespace' by typing "[namespacename]::foobar()"?

Just when you think you're getting the hang of TorqueScript, something else pops up and you're back at n00b.
#13
02/20/2007 (3:44 pm)
@Eric - The point of a ScriptObject is to have the same kind of namespace functionality as a t2dSceneObject without actually being an object in the graphical simulation. You give it a class, just like you would for a t2dSceneObject or t2dStaticSprite or whatever, and you define methods in the namespace just like those.
Quote:Creating a ScriptObject is similar to creating a class.
I find this to be confusing and possibly misleading.

ScriptObjects can have classes, just like t2dSceneObjects can.
#14
02/20/2007 (11:05 pm)
Okay. I understand ScriptObjects now. I changed t2dSceneObject into ScriptObject in my code and things worked perfectly. Thanks!

Here's something strange, though:
new ScriptClass(CheckerBoard);
contains the only reference to "ScriptClass" in the Documentation. Is that supposed to be ScriptObject? Was there a ScriptClass at one point that's been deprecated/removed?
#15
02/23/2007 (1:31 pm)
@Luke
Quote:...you do not need the $ operator for accessing objects via name. Just use the name directly.
One thing that might clarify the point is that when you do
new t2dSceneObject(myObject) { } ;
it is the same as if you had said (more formally)
new t2dSceneObject( "myObject" ) { } ;
that is, the name of the object is the string "myObject". The first statement is idiomatic and relies on TorqueScript's feature of converting MyObject to a string as it is parsing your code.

@Dan
Quote:"Creating a ScriptObject is similar to creating a class."
I find this to be confusing and possibly misleading.
I agree. Explaining to people how namespaces work is difficult, and the difficulty is compounded by the fact that how namespaces work is not at all easy to understand. I still do not feel secure in my understanding.

@Eric
Quote:Here's something strange, though:
new ScriptClass(CheckerBoard);
ScriptClass is obsolete and deprecated. Too bad the Checkers demo has not been updated to reflect that fact.

From my notes:
Quote:Interfaces

Object
Member Fields:
class = "" [ScriptObject] [t2dSceneObject] [t2dSceneObjectGroup] [t2dSceneGraph] [GuiControl] [UndoScriptAction]
superclass = ""
Methods:
getClassNamespace() - [t2dSceneObject]
getSuperClassNamespace() - [t2dSceneObject]
setClassNamespace() - [t2dSceneObject]
setSuperClassNamespace() - [t2dSceneObject]
getClass() - [t2dSceneGraph]
getSuperClass() - [t2dSceneGraph]
setClass() - [t2dSceneGraph]
setSuperClass() - [t2dSceneGraph]
That is, five classes have member fields class and superClass. But different class's accessor methods for these fields vary.