Executing a method on a SimSet or SimGroup collection
During game play we may want to call the same method on all the SimObject
instances that belong to a SimSet
or SimGroup
collection. Rather than iterate
through each SimObject
instance in the collection and execute its method, TorqueScript has a handy one-line shortcut that we'll make use of in this recipe.
Getting ready
We will be adding a new TorqueScript function to a project based on the Torque 3D Full
template and try it out using the Empty Terrain
level. If you haven't already, use the Torque Project Manager (Project Manager.exe
) to create a new project from the Full
template. It will be found under the My Projects
directory. Then start up your favorite script editor, such as Torsion, and let's get going!
How to do it...
We are going to write a TorqueScript function that will demonstrate how to execute a method on all the SimObject
instances in a SimGroup
collection as follows:
Open the
game/scripts/server/game.cs
script file and add the following code to the bottom:function executeMethodOnGroup1() { // Create a SimGroup new SimGroup(MyGroup); // Create some script objects with some properties and // add each one to our SimGroup. Give each a class // property so they belong to the same subclass and have // access to the same method. // The ScriptObject class is just a generic SimObject that // we can create in TorqueScript. %so = new ScriptObject() { class = "MyClass1"; internalName = "name1"; myValue1 = "abc"; }; MyGroup.add(%so); %so = new ScriptObject() { class = "MyClass1"; internalName = "name2"; myValue1 = "123"; }; MyGroup.add(%so); %so = new ScriptObject() { class = "MyClass1"; internalName = "name3"; myValue1 = "a1b2"; }; MyGroup.add(%so); // Execute our method on all SimObjects in the group. // This is the same as iterating through the group // and calling object.method() on each of them. echo("-- Starting callOnChildren()"); MyGroup.callOnChildren(outputProperties, "myValue1"); echo("-- Finished callOnChildren()"); // Clean up the SimGroup and all of the script obejcts MyGroup.delete(); } // A method for our custom script class function MyClass1::outputProperties(%this, %propertyName) { // Get the script object's SimObject ID %id = %this.getId(); // Get the script object's internal name %name = %this.internalName; // Get the value of the passed-in property name %value = %this.getFieldValue(%propertyName); // Print out to the console echo("ScriptObject ID:" @ %id @ " Name:" @ %name @ " Value:" @ %value); }
Start up our game under the
My Projects
directory and load theEmpty Terrain
level. Open the console using the tilde (~) key and enter the following at the bottom of the screen:executeMethodOnGroup1();
In the console we will see the following output:
==>executeFunctionOnGroup1(); -- Starting callOnChildren() ScriptObject ID:4153 Name:name1 Value:abc ScriptObject ID:4154 Name:name2 Value:123 ScriptObject ID:4155 Name:name3 Value:a1b2 -- Finished callOnChildren()
How it works...
The SimGroup
and
SimSet
callOnChildren()
methods automatically step through each child SimObject
instance and if the requested method is valid on the object, it is called with the passed-in arguments. The
callOnChildren()
method has the following form:
SimGroup.callOnChildren( method, args… );
Here, the method
parameter is the method to be called on each of the SimObject
objects in the collection, and the
args…
parameter is actually a variable number of arguments that will be passed-in to the method. In our previous example we pass-in one argument, which is the name of the property we wish our method to process.
The
callOnChildren()
method doesn't just process the child SimObject
instances that are part of a SimGroup
or SimSet
collection, it also traverses any child SimGroup
or SimSet
collection, and executes the method on their SimObject
instances.
There's more...
If we want to call a method only on all the SimObject
objects that are the immediate children of a SimGroup
or SimSet
collection and not traverse through the hierarchy of the collection, we can use the
callOnChildrenNoRecurse()
method.
It has the same form as callOnChildren()
as follows:
SimGroup.callOnChildrenNoRecurse( method, args… );
We could modify the method call of the SimGroup
collection from our previous example and replace it with callOnchildrenNoRecurse()
as follows:
MyGroup.callOnChildrenNoRecurse(outputProperties, "myValue1");
With our particular example, we end up with the same output to the console, as there are no child SimGroup
or SimSet
objects that would be skipped by using callOnChildrenNoRecurse()
.
See also
Iterating on objects in a SimSet or SimGroup collection
Getting a random object from a SimSet or SimGroup collection
Finding an object in a SimSet or SimGroup collection using its internal name