[SOLVED]Trying to delete all objects of a specific class.
by Vlad I · in Torque Game Builder · 05/18/2012 (6:18 am) · 16 replies
As the topic says. Trying to delete all objects of a class onLevelLoaded using this thread
www.garagegames.com/community/forums/viewthread/58156
$sceneItemsLeft2 == 0 is clearly zero onLevelLoaded, so it should be deleting it, instead the console says something about:
Object Bullet(2025) Bullet -> Boxes -> 2TdTextObject -> 2TdSceneObject -> BehaviorComponent -> DynamicCollisionMethodComponent -> SimCOmponent -> SimObject
www.garagegames.com/community/forums/viewthread/58156
$sceneItemsLeft2 == 0 is clearly zero onLevelLoaded, so it should be deleting it, instead the console says something about:
Object Bullet(2025) Bullet -> Boxes -> 2TdTextObject -> 2TdSceneObject -> BehaviorComponent -> DynamicCollisionMethodComponent -> SimCOmponent -> SimObject
function HoLabelsHoPt02Room01 :: onLevelLoaded (%this)
{
//if( $sceneItemsLeft2 == 0 )
// {
%cnt = MySceneGraph01.getSceneObjectCount(); //named MySceneGraph01 in Scene Graph scripting in the tgb editor
for( %i = 0; %i < %cnt; %i++ )
{
%object = MySceneGraph01.getSceneObject( %i );
if( %object.getClassName() $= "Boxes" ) // change to classes you want
{ if( $sceneItemsLeft2 == 0 )
{
Bullet.safeDelete(); // do something with the object
}
}
}
}What am I doing wrong?About the author
#2
Object Bullet(2025) Bullet -> Boxes -> 2TdTextObject -> 2TdSceneObject -> BehaviorComponent -> DynamicCollisionMethodComponent -> SimCOmponent -> SimObject
05/18/2012 (8:40 am)
%object.safeDelete() doesn't help I still get the same Object Bullet(2025) Bullet -> Boxes -> 2TdTextObject -> 2TdSceneObject -> BehaviorComponent -> DynamicCollisionMethodComponent -> SimCOmponent -> SimObject
#3
05/18/2012 (11:41 am)
What is Bullet and where is it defined?
#4
Bullet is a Text Object I created in tgb editor using class "Boxes".
There are other Text Objects with different names but using the same class "Boxes".
They (objects with class Boxes) should be all deleted on levelLoaded. I can't think of anything going wrong.
Harry pointed out %object.safeDelete() , which is the way it should be, but still cant make all objects deleted.
05/18/2012 (12:36 pm)
Hey Michael!Bullet is a Text Object I created in tgb editor using class "Boxes".
There are other Text Objects with different names but using the same class "Boxes".
They (objects with class Boxes) should be all deleted on levelLoaded. I can't think of anything going wrong.
Harry pointed out %object.safeDelete() , which is the way it should be, but still cant make all objects deleted.
#5
05/18/2012 (12:48 pm)
Edit: Redacted, went too quick and realized I reiterated your exact code. Ill re-edit to offer better solutions when I have time. Though you can check the "class" field directly, instead of using a function. That probably doesn't help.
#7
for( %i = %cnt; %i > -1; %i-- )
It's been a while, but I seem to recall there being something about always wanting to use Previous rather than Next when deleting, because of the way items get reordered when you delete one out.
05/18/2012 (1:50 pm)
Is it deleting some, but not all objects? You may want to change the looping to:for( %i = %cnt; %i > -1; %i-- )
It's been a while, but I seem to recall there being something about always wanting to use Previous rather than Next when deleting, because of the way items get reordered when you delete one out.
#8
Also, I only now noticed console giving me
" Unknown command getSceneObjectCount." in line 5
"Object MySceneGraph01 (1916) MySceneGraph01 -> thescene -> t2dSceneObject -> BehaviorComponent -> DynamicCollisionMethodComponent -> SimCOmponent -> SimObject
But if I use this code below, it disappears and starts telling me Object Bullet(2025) Bullet -> Boxes -> 2TdTextObject -> 2TdSceneObject -> BehaviorComponent -> DynamicCollisionMethodComponent -> SimCOmponent -> SimObject
05/20/2012 (5:54 am)
Harry changig the loop didnt help either.Also, I only now noticed console giving me
" Unknown command getSceneObjectCount." in line 5
"Object MySceneGraph01 (1916) MySceneGraph01 -> thescene -> t2dSceneObject -> BehaviorComponent -> DynamicCollisionMethodComponent -> SimCOmponent -> SimObject
But if I use this code below, it disappears and starts telling me Object Bullet(2025) Bullet -> Boxes -> 2TdTextObject -> 2TdSceneObject -> BehaviorComponent -> DynamicCollisionMethodComponent -> SimCOmponent -> SimObject
function HoLabelsHoPt02Room01 :: onLevelLoaded (%this)
{
if( $sceneItemsLeft2 == 0 )
{
%cnt = MySceneGraph01.getSceneObjectCount();
for( %i = 0; %i < %cnt; %i++ )
{
%object = MySceneGraph01.getSceneObject( %i );
if( %object.getClassName() $= "Boxes" ) // change to classes you want
{ //if( $sceneItemsLeft2 == 0 )
//{
%object.safeDelete(); // do something with the object
}
}
}
}
#9
Use an echo statement to verify each step of the process, something like below:
This should give you all the information you need to pinpoint the source of failure.
If this doesn't help, if you could post a full log of your console, that might also help.
05/20/2012 (9:03 pm)
Okay, here's what were going to try:Use an echo statement to verify each step of the process, something like below:
function HoLabelsHoPt02Room01 :: onLevelLoaded (%this)
{
echo("$sceneItemsLeft2: " @ $sceneItemsLeft2);
if( $sceneItemsLeft2 == 0 )
{
echo("Scenegraph: " @ MySceneGraph01);
%cnt = MySceneGraph01.getSceneObjectCount();
echo("Scenegraph count: " @ %cnt);
for( %i = 0; %i < %cnt; %i++ )
{
%object = MySceneGraph01.getSceneObject( %i );
echo("Object: " @ %object @ " - " @ %object.getClassName());
if( %object.getClassName() $= "Boxes" ) // change to classes you want
{
echo("Object is in fact a box");
%object.safeDelete(); // do something with the object
}
}
}This should give you all the information you need to pinpoint the source of failure.
If this doesn't help, if you could post a full log of your console, that might also help.
#10
Thank you guys for your help.
Here is what I found out, or there is something wrong with this world :)
More like smth. is wrong with me.
Anyway. Using your code Justin, and thanks again for your help, I noticed the console giving me that it spots 2 objects every time $sceneItemsLeft2 2 , when I load the level, when I switch to another one and come back, it still finds 2 $sceneItemsLeft2.
Here is my entire code for this:
05/21/2012 (10:52 am)
Ok I've been banging my head on this one nearly 3 days.Thank you guys for your help.
Here is what I found out, or there is something wrong with this world :)
More like smth. is wrong with me.
Anyway. Using your code Justin, and thanks again for your help, I noticed the console giving me that it spots 2 objects every time $sceneItemsLeft2 2 , when I load the level, when I switch to another one and come back, it still finds 2 $sceneItemsLeft2.
Here is my entire code for this:
new ScriptObject(Player);
function Player::getItem( %this, %item )
{
%this.heldItem[%item] = true;
}
function Player::hasItem( %this, %item )
{
return %this.heldItem[%item];
}
$sceneItemsLeft2 = 0;
function counterHoPt02Room01 :: onLevelLoaded (%this)
{
%i = %this.getCount();
while( %i-- >= 0 )
{
%obj = %this.getObject( %i );
if( Player.hasItem( %obj.getName() ) ) // Here we delete all objects when we come
// back to the level where we previously clicked on objects we needed to find,
// so they dont appear again
{
%obj.delete(); // or setVisible(false)?
LevelTrHo031.setVisible(true); // this turns level button
//visible so we could go to the next level
//Bullet_word.safeDelete();
}
}
}
// Here we add the numbers of objects to find to the count counterHoPt02Room01
function HoPt01Room01::onAdd(%this)
{
// %this.setUseMouseEvents( true ); // enabling mouse event
$sceneItemsLeft2++;
}
// Problem lays here the objects we clicked on are deleted when we come
// back to the level but the labels stay on
function HoLabelsHoPt02Room01 :: onLevelLoaded (%this)
{
echo("$sceneItemsLeft2: " @ $sceneItemsLeft2);
if( $sceneItemsLeft2 == 0 )
{
echo("Scenegraph: " @ MySceneGraph01);
%cnt = MySceneGraph01.getSceneObjectCount();
echo("Scenegraph count: " @ %cnt);
for( %i = 0; %i < %cnt; %i++ )
{
%object = MySceneGraph01.getSceneObject( %i );
echo("Object: " @ %object @ " - " @ %object.getClassName());
if( %object.getClassName() $= "Boxes" ) // change to classes you want
{
echo("Object is in fact a box");
%object.safeDelete(); // do something with the object
}
}
}
}
// This is where the objects we need to find are deleted, so are the
// lables, but when we come back the labels stay , while the objects are gone
function HoPt01Room01::onMouseDown( %this, %modifier, %worldPosition, %click)
{
Player.getItem( %this.getName() );
if(%this.found)
return;
%str = strreplace(%this.getname(), "obj","word");
// fadeoutandkill(%str, 500); // deletes the label
// fadeoutandkill(%this, 500); // deletes the object in the scene
%str.safedelete();
%this.safedelete();
%this.found = 1;
playEffect(%this);
$sceneItemsLeft2--;
if( $sceneItemsLeft2 == 0 )
{
//LevelTrHo03.setUseMouseEvents( true );
//LevelTrHo03.setVisible(true);
LevelTrHo031.setVisible(true);
updateSceneSave(%this);
}
}
#11
So now when I click on 2 objects they are deleted and $sceneItemsLeft2 is zero, when I come back to the level it echoes and says $sceneItemsLeft2 0, it also correctly echoes Scenegraph as MySceneGraph01, and it echoes 60 objects and then goes a long list of the objects like:
Object: 1986 - 2TdTilemap
Object: 1987 - 2TdStaticSprite
etc. all 60 of them.
But it doesn't echo anything after no echo("Object: " @ %object @ " - " @ %object.getClassName()); and no echo("Object is in fact a box"); , just nothing else.
I tried to change if( %object.getClassName() $= "Boxes" )
to just Class if( %object.getClass() $= "Boxes" )
and the console said Unknown Command , so I guess getClassName is the right one.
But still the problem persists.
05/21/2012 (6:03 pm)
Ok, to make $sceneItemsLeft2 absolutely zero when I come back onlevelLoaded I removed function HoPt01Room01::onAdd(%this) , and set global $sceneItemsLeft2 =2;So now when I click on 2 objects they are deleted and $sceneItemsLeft2 is zero, when I come back to the level it echoes and says $sceneItemsLeft2 0, it also correctly echoes Scenegraph as MySceneGraph01, and it echoes 60 objects and then goes a long list of the objects like:
Object: 1986 - 2TdTilemap
Object: 1987 - 2TdStaticSprite
etc. all 60 of them.
But it doesn't echo anything after no echo("Object: " @ %object @ " - " @ %object.getClassName()); and no echo("Object is in fact a box"); , just nothing else.
I tried to change if( %object.getClassName() $= "Boxes" )
to just Class if( %object.getClass() $= "Boxes" )
and the console said Unknown Command , so I guess getClassName is the right one.
But still the problem persists.
#12
Now from your results, it sounds like were actually getting to "echo("Object: " @ %object @ " - " @ %object.getClassName());" -- that is what is listing all the objects. So from here, I would look at your list of objects and see if you can manually find your "Boxes" class objects in the printed list. If not, then that means those objects are not in the scenegraph or their class is not "Boxes," and we'll have to look into that. If you do see them, then that means for whatever reason the if statement is failing when it should succeed.
I have a feeling it is the former case.
I will ask this: Are you setting the boxes class as "class" or "superclass"? For instance, in this case you could have an object with the class "Bullet," and the superclass "Boxes," and the two would not be interchangable. Here, lets modify our code slightly, change
To
Edit:
Figured it out. I don't use "getClassName", so when I was looking up a similar function for super classes in the online TGB reference, I found that this method returns the actual class of the object, such as if it is a t2dstaticsprite, or t2dscroller, or t2dtilelayer, etc., not the class namespace you define.
So change "%object.getClassName()" to "%object.class" and I bet combined with your other fix, it'll start working.
05/22/2012 (11:43 am)
Okay, the sceneitems variable makes sense now that I see your code: the onAdd function gets called everytime the object it is associated with is added, including everytime a level it is contained in is loaded. So you will want to keep the intialization of information about your object count separate from your code for loading rooms, perhaps set it in an initialization function.Now from your results, it sounds like were actually getting to "echo("Object: " @ %object @ " - " @ %object.getClassName());" -- that is what is listing all the objects. So from here, I would look at your list of objects and see if you can manually find your "Boxes" class objects in the printed list. If not, then that means those objects are not in the scenegraph or their class is not "Boxes," and we'll have to look into that. If you do see them, then that means for whatever reason the if statement is failing when it should succeed.
I have a feeling it is the former case.
I will ask this: Are you setting the boxes class as "class" or "superclass"? For instance, in this case you could have an object with the class "Bullet," and the superclass "Boxes," and the two would not be interchangable. Here, lets modify our code slightly, change
echo("Object: " @ %object @ " - " @ %object.getClassName());To
echo("Object: " @ %object @ " - " @ %object.class @ " (Class) - " @ %object.superClass @ " (Super Class)");Edit:
Figured it out. I don't use "getClassName", so when I was looking up a similar function for super classes in the online TGB reference, I found that this method returns the actual class of the object, such as if it is a t2dstaticsprite, or t2dscroller, or t2dtilelayer, etc., not the class namespace you define.
So change "%object.getClassName()" to "%object.class" and I bet combined with your other fix, it'll start working.
#13
"Apple_word" is an object using class "Boxes"
I don't have any superclass at the moment.
I chnaged echo as you told me and now it's giving me :
Object: 1986 - (Class) - (Super Class)
Object: 1987 - (Class) - (Super Class)
etc.
Also I found this down the list:
Object: 2031 - Boxes (Class) - (Super Class)
Object: 2032 - Boxes (Class) - (Super Class)
Object: 2033 - (Class) - (Super Class)
etc. all 60 objects
But it doesn't echo echo("Object is in fact a box"); and the proble still persists.
05/22/2012 (12:36 pm)
"Boxes" is a class, "Bullet_word" is a name of the object using class "Boxes""Apple_word" is an object using class "Boxes"
I don't have any superclass at the moment.
I chnaged echo as you told me and now it's giving me :
Object: 1986 - (Class) - (Super Class)
Object: 1987 - (Class) - (Super Class)
etc.
Also I found this down the list:
Object: 2031 - Boxes (Class) - (Super Class)
Object: 2032 - Boxes (Class) - (Super Class)
Object: 2033 - (Class) - (Super Class)
etc. all 60 objects
But it doesn't echo echo("Object is in fact a box"); and the proble still persists.
#14
05/22/2012 (12:50 pm)
Can I use something like this (%this).Boxes.safeDelete();Why wouldn't it delete all objects using class "Boxes" on levelLoaded if I put this in :
function Boxes:: onLevelLoaded (%this)
{
if( $sceneItemsLeft2 == 0 )
{
(%this).Boxes.safeDelete();// And I stick this line here to
// delete all objects using class "Boxes", why don't this work?
}
}If it worked like that, it would have saved lot's of time.
#15
Now, you could keep all your boxes in one simgroup or simset object, and write a quick function for deleting all of the objects in a simset. This is in fact the technique that I use, here is an example function for clearing a simset:
Implementation might look like this:
Also you should re-read my last post, I edited it with what I believe is the solution.
05/22/2012 (2:16 pm)
That wouldn't work, because the class "Boxes" isn't an object and therefore cannot have a method called on it like that. The class only describes a bunch of objects and helps identify their purposes and properties, and aren't instantiated like objects are (i.e. you don't declare one instance of a new class). So you can't manipulate classes like you can objects.Now, you could keep all your boxes in one simgroup or simset object, and write a quick function for deleting all of the objects in a simset. This is in fact the technique that I use, here is an example function for clearing a simset:
function SimSet::deleteContents( %this ) {
while( %this.getCount() > 0 ) {
%obj = %this.getObject(0); // Get first object in set
%this.remove(%obj); // Remove this object from the set
%obj.safeDelete(); // Delete the object
}
}
function SimSet::safeDelete( %this ) {
while( %this.getCount() > 0 ) {
%obj = %this.getObject(0); // Get first object in set
%this.remove(%obj); // Remove this object from the set
%obj.safeDelete(); // Delete the object
}
%this.delete(); // Delete the simset
}Implementation might look like this:
function Boxes::onAdd( %this ) {
if(!isObject(BoxesSet)) // If there isn't a list of Boxes, make one
new SimSet(BoxesSet);
BoxesSet.add(%this) // Add this object to that list
}
...
BoxesSet.deleteContents();
...Also you should re-read my last post, I edited it with what I believe is the solution.
#16
Just when I was gonna give up! :)
Damn, it only took these two small functions to add to my code and remove the old function HoPt01Room01::onAdd(%this) from the script
Here it is if anyone interested:
05/22/2012 (4:39 pm)
Thanks Justin !!! Brilliant!Just when I was gonna give up! :)
Damn, it only took these two small functions to add to my code and remove the old function HoPt01Room01::onAdd(%this) from the script
Here it is if anyone interested:
function Boxes::onAdd( %this )
{
if(!isObject(BoxesSet)) // If there isn't a list of Boxes, make one
new SimSet(BoxesSet);
BoxesSet.add(%this); // Add this object to that list
}
function Boxes:: onLevelLoaded (%this)
{
if( $sceneItemsLeft2 == 0 )
{
%this.safeDelete();
}
}
Torque 3D Owner Harry Durnan