Datablock changes take effect called within engine/not script
by Juan Aramburu · in Torque Game Engine · 06/16/2006 (2:35 am) · 3 replies
The objective is to change the vehicle (by changing the datablock which use different models), but it seems it only works if the code was run inside the engine, but I need it to work using a commandToClient/Server (whichever one I should be using).
Why does the first method work, but not the second (which is the way I need it to work):
Method 1 (switchIt() is called when hitting a button on the controller, so processed from inside processInput())
Method 2 (called when user clicks a button from a dialog)
To me this is identical code; just that with method 1, you're already running inside the engine when you call switchIt(), as compared to method 2, where it's a commandToServer.
I've also tried (from within serverCmdChangeVehicle), commandToClient(%client, 'changeVehicleNow',%client.player), which inside, calls %myPlayer.switchIt() (%myPlayer is the %client.player parameter sent from the server).
I've even added Con::printf 'breakpoints' and the exact same code is run in both instances...except only the first one works. No console errors or undefined functions. The datablock is changed to the new one, but the model still remains the same.
Why does the first method work, but not the second (which is the way I need it to work):
Method 1 (switchIt() is called when hitting a button on the controller, so processed from inside processInput())
---engine-----
void MyObject::switchIt() {
Con::executef(this, 1, "SwitchToPlane");
Con::executef(this, 1, "GiveWheels");
}
//switchIt() is also a console method
----script------
MyObject::SwitchToPlane(%this) {
%this.setDatablock(dbPlane);
}Method 2 (called when user clicks a button from a dialog)
---script--------
function clientSideSwitchIt() {
commandToServer('ChangeVehicle');
}
function serverCmdChangeVehicle(%client) {
if (!isObject(%client.player))
return;
%client.player.switchIt();
}To me this is identical code; just that with method 1, you're already running inside the engine when you call switchIt(), as compared to method 2, where it's a commandToServer.
I've also tried (from within serverCmdChangeVehicle), commandToClient(%client, 'changeVehicleNow',%client.player), which inside, calls %myPlayer.switchIt() (%myPlayer is the %client.player parameter sent from the server).
I've even added Con::printf 'breakpoints' and the exact same code is run in both instances...except only the first one works. No console errors or undefined functions. The datablock is changed to the new one, but the model still remains the same.
#2
Is there a better way to switch the datablock of an object 'on the fly'? Do I simply need to refresh the view or something after updating the datablock? Echoing out the datablock after the code runs does in fact display the new datablock, but the old model.
Edit: Sorry, switchIt() is the console method, while the code you see inside of the switchIt() above is actually called "setDB()" (and switchIt() calls it).
06/16/2006 (1:17 pm)
The switchIt() is declared as a console method...I guess the small comment on line 6 was kind of invisible. But the thing is, I do get inside of switchIt() when called from both ways. It's just that it only works when I'm calling it as a general function inside the engine (e.g., switchIt();) instead of through TorqueScript (e.g., %client.player.switchIt();).Is there a better way to switch the datablock of an object 'on the fly'? Do I simply need to refresh the view or something after updating the datablock? Echoing out the datablock after the code runs does in fact display the new datablock, but the old model.
Edit: Sorry, switchIt() is the console method, while the code you see inside of the switchIt() above is actually called "setDB()" (and switchIt() calls it).
//I can't recall the exact syntax to declare a console method, but let's just say the line below is correct
ConsoleMethod(switchIt) {
object->setDB();
}
MyObject::setDB() {
//this does all the work
}
#3
So it seems that the difference between the working method & non-working method is that working method displays:
while the non-working method displays:
In other words, it only works on-client. I have tried doing a commandToClient yet isClientObject: no is displayed.
How can I force calling my console method from the client to the client?
06/16/2006 (7:43 pm)
bool ShapeBase::onNewDataBlock(GameBaseData* dptr)
{
// Even if loadShape succeeds, there may not actually be
// a shape assigned to this object.
if (bool(mDataBlock->shape)) {
Con::errorf("***ShapeBase: shape is true, isClientObject: %s\n",isClientObject() ? "yes":"no");
delete mShapeInstance;
mShapeInstance = new TSShapeInstance(mDataBlock->shape, isClientObject());
if (isClientObject())
mShapeInstance->cloneMaterialList();
mObjBox = mDataBlock->shape->bounds;
...
}So it seems that the difference between the working method & non-working method is that working method displays:
***ShapeBase: shape is true, isClientObject: yes
while the non-working method displays:
***ShapeBase: shape is true, isClientObject: no
In other words, it only works on-client. I have tried doing a commandToClient yet isClientObject: no is displayed.
How can I force calling my console method from the client to the client?
Torque 3D Owner Stephen Zepp
TorqueScript can only execute c++ code that you specifically expose via ConsoleMethods.