Game Development Community

Hiding ScenObjects on client side

by Fabio Luis Stange · in Technical Issues · 05/28/2007 (2:59 pm) · 10 replies

I'm having performance issues, and I'm trying to implement options to hide non essential objects from rendering. The game is multiplayer, but it's not an FPS, and the players are separated by a river, so it's not a problem to have one client seeing some object while the other isn't seeing it - that's exactly what I'm trying to do.

I need to hide TSStatics, FoliageReplicators, and ParticleEffects. So my first try was to add a setHidden method similar to the one in StaticShape in SceneObject, the common parent to those 3:

void SceneObject::setHidden(bool hidden) {
   if (hidden != mHidden) {
      if (mHidden) addToScene();
      else removeFromScene();
      mHidden = hidden;
   }
}
ConsoleMethod( SceneObject, setHidden, void, 3, 3, "(bool show)") {
   object->setHidden(dAtob(argv[2]));
}
ConsoleMethod( SceneObject, isHidden, bool, 2, 2, "") {
   return object->isHidden();
}

Trying to SetHidden in any object does not hide it from rendering, but running through it is clear that the client thinks it's there and the server sends update telling me it's not, so I get that sense that I am at 5 FPS, but I'm still at 60.

This means that the object got hidden correctly on the server side, but not on the client, wich was the opposite of what I was trying to do. I'm not educated enough on Torque's inner workings to get this to work, any help greatly appreciated.

It did work on the foliage replicators, but it did not update correctly. Toggling the editor on / off does the trick. What method should I call to force an update at the time of the call?

Thanks,

Petrucio

#1
05/29/2007 (6:06 am)
I guess it comes down to hiding the ghost objects, and I'm hiding the parent objects

How do I know wich object on the client side is the ghost of wich object on the server side?

I tryied getGhostID, but it's returning -1.
isGhostable, isGhostAlways and isServerObject are returning true, isGhost is false.
#2
05/29/2007 (6:33 am)
Couldn't you use StartFade to fade out the object client side really quickly? (does that exist still in Torque?)
#3
05/29/2007 (6:39 am)
There were some lines on the original SetHidden method on ShapeBase that I intentionally ignored:

// need to set a mask bit to make the ghost manager delete copies of this object
// hacky, but oh well.
setMaskBits(CloakMask);

I guess that would solve my problem if I wanted to hide both the server object and the ghost objects (in some cases I do, not in most I don't).

Usually I would like to explicitly hide only one of the connected client's ghost object. How could I do that?
#4
05/29/2007 (6:42 am)
Quote:
Couldn't you use StartFade to fade out the object client side really quickly? (does that exist still in Torque?)

Yes, that does exist, but only for descendants of ShapeBase. And a quick StartFade would be almost like a SetHidden (collision would still be active though). But these implementations as they are in ShapeBase would hide the object on all clients.

I need to hide it on one client, while keeping it visible on the others. And I need it to be available at SceneObject, not ShapeBase.
#5
05/29/2007 (7:09 am)
My apologies, I missed the important part where you wanted to hide it from one person but have it shown for another.
#6
05/29/2007 (7:16 am)
No problem. I guess I wasn't very clear on that one until I replyed to you.
#7
05/29/2007 (10:05 am)
Took me a while, but I finally found this link:
tdn.garagegames.com/wiki/Torque/Networking/Ghosting/Examples

Now, when a client wants to hide some objects, it will just:

commandToServer('ObjectIdsRequest', <ObjCategory>);

The server will return the ghost ids of all the objects inside the SimGroup defined in the mission:

function serverCmdObjectIdsRequest(%client, %sim_group)
{
   for (%i = 0; %i < %sim_group.getCount(); %i++)
   {
      %server_id = %sim_group.GetObject(%i);
      %ghost_id = %client.getGhostID(%server_id);

      // TODO: Answer all IDs in a single command
      commandToClient(%client, 'ObjectIdResponse', %ghost_id);
   }
}

Now the client resolves those IDs and calls the SetHidden function implemented in C++ at the SceneObject class (in my first post)

function clientCmdObjectIdResponse(%ghost_id)
{
   %client_id = ServerConnection.resolveGhostID(%ghost_id);
   %client_id.SetHidden(true);
}

Maybe I'll post my first resource later with this solution after I polish it and make it generic.
#8
05/29/2007 (10:13 am)
That's cool, glad you found a solution. I think this might come in handy for my sidescroller too!
#9
06/28/2009 (3:28 pm)
Hate to resurrect such an old thread, but I've been trying to do the exact same thing in the same fashion, but I'm not having any success.

My goal is to hide TSStatic objects as well, so I implemented the same functions as in the first post (but in TSStatic.cc rather than SceneObject.cc).

The problem I have is that, when I hide an object, it seems to disappear from the server (I think), but not from the client. So in the editor, I can see that the object's label and its world box vanish, but the mesh is still being rendered. I can move the player through the objects, so the collision mesh has been removed, but the object's mesh is still visible.

So I implemented the functions as in Fabio's last post, but those don't seem to work. When I try to hide a particular SimGroup containing a whole list of TSStatic's, it runs through those functions but for some reason, only a handful of the objects actually get hidden. The setHidden() function is called on all of the objects, but for the majority of them, nothing happens. I can't figure out why that is.

Any help would be appreciated...
#10
06/28/2009 (3:56 pm)
Ah, ignore me. I just wasn't properly initializing mHidden when TSStatic objects are created. Seems to be working now...