Game Development Community

T2dSceneObjectGroup addToLevel bug? (Resolved)

by Justin Proffitt · in Torque Game Builder · 08/04/2011 (5:10 pm) · 2 replies

I seem to have run into a annoying bug with sceneobject groups while creating my game GUI. My pause screen works by adding a level to an overlaid GUIWindow. I checked the scenegraph for my pause screen with "listObjects()" and confirmed that it had in fact loaded them, then checked the contained objects and noted that their "Enabled", "Visible", and "Layer" settings were set to 1, 1, and 0, respectively. Yet I saw nothing.

When I tried grouping objects in my main menu scene (which is the first scene that loads), it worked flawlessly! I was really confused, until I noticed that the menu loads using "loadLevel"; when I loaded it with "addToLevel", it broke again.

So, for some reason addToLevel adds t2dSceneObjectGroups and all contained objects to the scenegraph, but does not render them or otherwise acknowledge them in any way.

Edit: I managed to perform the addToLevel() function in the level builder and confirmed without a doubt that the objects in the t2dSceneObjectGroup exist. They show up in the project file tree and I can select them via that, but not directly on the screen. When I edit their position or shape, they suddenly appear and act like normal. So I guess I can write a script that makes all my GUI objects initialize their position or something and that can fix it, it'd be nice to know why it does that though.

Edit2: I figured out the issue, it is this, marked by ##:

(~/common/gameScripts/levelManagement.cs, line 292)
// If the existing scenegraph has objects in it, then the new stuff should probably be
      // organized nicely in its own group.
      if ((%toSceneGraph.getCount() > 0) && (%fromSceneGraph.getCount() > 0))
      {
         %newGroup = new t2dSceneObjectGroup();
      
         while (%fromSceneGraph.getCount() > 0)
         {
            %obj = %fromSceneGraph.getObject(0);
            %fromSceneGraph.removeFromScene(%obj);
            ##%obj.setPosition(%obj.getPosition()); // This sets physics.dirty.... =)
            %newGroup.add(%obj);
         }
         
         %toSceneGraph.add(%newGroup);
         $LevelManagement::newObjects = %newGroup;
      }
      else
      // if it does not then simply move the objects over
      {
         while (%fromSceneGraph.getCount() > 0)
         {
            %obj = %fromSceneGraph.getObject(0);
            %fromSceneGraph.removeFromScene(%obj);
            ##%obj.setPosition(%obj.getPosition()); // This sets physics.dirty.... =)
            %toSceneGraph.addToScene(%obj);
         }
         $LevelManagement::newObjects = %toSceneGraph;
      }
      
      %newScenegraph = %toSceneGraph;
      %fromSceneGraph.delete();
   }

Since the t2dSceneObjectGroups firstly don't have position fields, and secondly contain objects that aren't touched in this script, this does not initialize them properly. I fixed this by changing "%obj.setPosition(%obj.getPosition());" to "obj.initializePosition();", then adding the code below:

function SimObject::initializePosition( %this ){
	for(%i = 0; %i < %this.getCount(); %i++)
		%this.getObject(%i).initializePosition();
}

function t2dSceneObject::initializePosition( %this ){
	%this.setPosition(%this.getPosition());
}

Now it works perfectly fine all the time : )

About the author

I am a college student majoring in physics. As it so happens I like programming, a hobby which extends my profession in web design.


#1
08/05/2011 (1:09 am)
@Justin Is your pause screen level contains objectGroup as topmost object, or a sceneGraph? The part you are fixing is intended to load sceneGraphs, the case for sceneObjectGroup is processed just below it. While I do not think I ever used it, I believe it should do just what you want, or at least all group-related fixes you find necesary should go there.
#2
08/05/2011 (12:03 pm)
My pause screen level contains a sceneGraph at the top most level, as I built it in the level editor (and as far as I know you can't remove sceneGraphs in that). I guess I should give it another look...

Right, I saw that and tried messing with it first, however I noticed that section is ignored because the scenegraph is the top most object.

The problem as I saw it was that the script would only iterate through the objects referenced directly in the sceneGraph's list, while objects contained within objects would go ignored. My fix is probably crappy by most standards, but it isn't intended to load hundreds of objects, just a handful, also it lets me put groups in groups, giving me even more control. : )