Access prefab Sub Objects from torquescript
by Andrew Edmonds · 01/30/2010 (3:13 pm) · 4 comments
I use a prefab that I have created containing one object and 8 lights. I wanted a way to turn the lights on and off in-game and couldn't find a way to access the sub objects of a prefab through script (without exploding the prefab). These functions will allow you to access any object inside of a prefab.
Usage:
%prefab.getSubObjectCount() -- returns the number of objects inside the prefab
%prefab.getSubObject(%objectIndex) -- returns the id of the object at the specified index
The code:
In T3D\prefab.h at line 72 (in public declarations), add
Add to the end of T3D\prefab.cpp:
Recompile and you're done!
Usage:
%prefab.getSubObjectCount() -- returns the number of objects inside the prefab
%prefab.getSubObject(%objectIndex) -- returns the id of the object at the specified index
The code:
In T3D\prefab.h at line 72 (in public declarations), add
// getSubObjectCount and getSubObject >>> S32 getSubObjectCount(); S32 getSubObject(S32 subObjectIndex); // getSubObjectCount and getSubObject <<<
Add to the end of T3D\prefab.cpp:
// getSubObjectCount and getSubObject >>>
S32 Prefab::getSubObjectCount()
{
if (!mChildGroup) {
Con::errorf("Not a prefab or no subObjects found.");
return NULL;
}
SimGroup *group = mChildGroup;
Vector<SceneObject*> foundObjects;
group->findObjectByType(foundObjects);
return foundObjects.size();
}
ConsoleMethod(Prefab, getSubObjectCount, S32, 2, 2, "prefab.getSubObjectCount() returns the number of subObjects inside the prefab.")
{
TORQUE_UNUSED(argc); TORQUE_UNUSED(argv);
return object->getSubObjectCount();
}
S32 Prefab::getSubObject(S32 subObjectIndex)
{
if (!mChildGroup) {
Con::errorf("Not a prefab or no subObjects found.");
return NULL;
}
SimGroup *group = mChildGroup;
Vector<SceneObject*> foundObjects;
group->findObjectByType(foundObjects);
S32 subObjectsCount = foundObjects.size();
if (subObjectIndex >= subObjectsCount) {
Con::errorf("%i out of bounds.", subObjectIndex);
return NULL;
}
SceneObject *child = foundObjects[subObjectIndex];
return child->getId();
}
ConsoleMethod(Prefab, getSubObject, S32, 3, 3, "prefab.getSubObject(index) returns an object within the prefab.")
{
TORQUE_UNUSED(argc);
S32 subObjectIndex = dAtoi(argv[2]);
return object->getSubObject(subObjectIndex);
}
// getSubObjectCount and getSubObject <<<Recompile and you're done!
About the author
Formed in 2005, EiKON Games is an indie games development project based in the UK working on the tactical first person shooter "Epoch: Incursion". See the Join Us or Contact Us pages at http://www.eikon-games.com/
#2
03/13/2010 (7:32 pm)
The next release will include a Prefab::onLoad( %this, %simgroup ) callback where %simgroup contains all child objects of the prefab. I'll also add %prefab.getChildGroup() or something similar.
#3
In prefab.h at the end of the prefab class make the last two members public, by changing:
To:
And insert the following at the end of prefab.cpp:
I'm not sure if exposing those ChildToPrefabMap variables has any negative side-effects, though in using it I haven't noticed anything detrimental.
05/19/2010 (9:24 pm)
This is very useful! Something it led me to was the need to get the prefab by the sub object's ID. What I did to make that work were the following changes...In prefab.h at the end of the prefab class make the last two members public, by changing:
/// Lookup from a child object's id to its transform in /// this Prefab's object space. ChildToMatMap mChildMap; typedef Map<SimObjectId,SimObjectId> ChildToPrefabMap; /// Lookup from a SimObject to its parent Prefab if it has one. static ChildToPrefabMap smChildToPrefabMap; };
To:
/// Lookup from a child object's id to its transform in /// this Prefab's object space. ChildToMatMap mChildMap; public: //<<<--Insert this typedef Map<SimObjectId,SimObjectId> ChildToPrefabMap; /// Lookup from a SimObject to its parent Prefab if it has one. static ChildToPrefabMap smChildToPrefabMap; };
And insert the following at the end of prefab.cpp:
ConsoleFunction(getPrefabByChildID, S32, 2, 2, "getPrefabByChildID(id) returns the object's owning prefab.")
{
TORQUE_UNUSED(argc);
S32 subObjectIndex = dAtoi(argv[1]);
Prefab::ChildToPrefabMap::Iterator itr = Prefab::smChildToPrefabMap.find( subObjectIndex );
if ( itr == Prefab::smChildToPrefabMap.end() )
return NULL;
Prefab *prefab;
if ( !Sim::findObject( itr->value, prefab ) )
{
Con::errorf( "Prefab::getPrefabByChildID - child object mapped to a prefab that no longer exists." );
return NULL;
}
return prefab->getId();
}I'm not sure if exposing those ChildToPrefabMap variables has any negative side-effects, though in using it I haven't noticed anything detrimental.
#4
Create scripts/server/prefabsExt.cs
12/10/2012 (4:26 pm)
This can also be done only with torqueScript in T3D 1.2 (MIT) : Create scripts/server/prefabsExt.cs
function Prefab::onLoad(%prefab,%sim)
{
%prefab.TheSimGroup = %sim;
}
function Prefab::getSubObjectCount(%prefab)
{
return %prefab.TheSimGroup.getObjectCount();
}
function Prefab::getSubObject(%prefab,%idx)
{
return %prefab.TheSimGroup.getObject(%idx);
}And in scripts/server/game.cs, after execs, addexec("scripts/server/prefabsExt.cs");That's done. 
Associate Konrad Kiss
Bitgap Games