Multiple objects not obeying behavior
by John Turner · in Torque Game Builder · 11/03/2007 (7:01 am) · 7 replies
I am creating objects(ghost shapes) when entering trigger area - see function below
function chapeltrigger::onenter(%this,%obj)
{
if (%obj.getName() $= "Fishplayer")
{
chapel.setimagemap("chapelimagemap",1);
createGhost(%pos,10,"ghost_stopped_S","9 9");
}
}
The ghost/object picks up behavior in code below :-
function createGhost(%pos,%speed,%ghostname,%size)
{
//$bug= new t2dAnimatedSprite() {scenegraph = scenewindow2d.getSceneGraph();};
%ghost= new t2dAnimatedSprite(%ghostname)
{
scenegraph = scenewindow2d.getSceneGraph();
class ="ghostClass";
layer=0;
Size=%size;
collisioncallback="true";
};
%ghost.playAnimation(%ghostname @ "Animation");
%ghost.enableUpdateCallback();
%ghost.setWorldLimit(clamp,"-60 -46 60 55",true);
%ghost.setCollisionActive( true,true );
// send,receive
%ghost.setCollisionPhysics(true,true);
%ghost.config=AiPlayerConfig;
%ghost.position=%pos;
%moveToward = MoveTowardBehavior.createInstance();
%moveToward.object=$fishplayer;
%moveToward.speed=%speed;
%ghost.addbehavior(%moveToward);
// why is this needed : %moveToward = %ghost.getBehavior("moveTowardBehavior");
//%moveToward.onAddToScene();
GhostSet.add(%ghost);
}
it is the simpe movetowards behavior form tgb
HOWEVER, the first ghost/object is ok and appears and uses movetowards behavior BUT when a new one is spawned it then loses its behavior -( the new ghost/object does have the behavior)
Any thoughts would be much appreciated as I want to attach my own behavior to the ghost/object asap
thanks john
function chapeltrigger::onenter(%this,%obj)
{
if (%obj.getName() $= "Fishplayer")
{
chapel.setimagemap("chapelimagemap",1);
createGhost(%pos,10,"ghost_stopped_S","9 9");
}
}
The ghost/object picks up behavior in code below :-
function createGhost(%pos,%speed,%ghostname,%size)
{
//$bug= new t2dAnimatedSprite() {scenegraph = scenewindow2d.getSceneGraph();};
%ghost= new t2dAnimatedSprite(%ghostname)
{
scenegraph = scenewindow2d.getSceneGraph();
class ="ghostClass";
layer=0;
Size=%size;
collisioncallback="true";
};
%ghost.playAnimation(%ghostname @ "Animation");
%ghost.enableUpdateCallback();
%ghost.setWorldLimit(clamp,"-60 -46 60 55",true);
%ghost.setCollisionActive( true,true );
// send,receive
%ghost.setCollisionPhysics(true,true);
%ghost.config=AiPlayerConfig;
%ghost.position=%pos;
%moveToward = MoveTowardBehavior.createInstance();
%moveToward.object=$fishplayer;
%moveToward.speed=%speed;
%ghost.addbehavior(%moveToward);
// why is this needed : %moveToward = %ghost.getBehavior("moveTowardBehavior");
//%moveToward.onAddToScene();
GhostSet.add(%ghost);
}
it is the simpe movetowards behavior form tgb
HOWEVER, the first ghost/object is ok and appears and uses movetowards behavior BUT when a new one is spawned it then loses its behavior -( the new ghost/object does have the behavior)
Any thoughts would be much appreciated as I want to attach my own behavior to the ghost/object asap
thanks john
About the author
#2
What I do when I have a bunch of the same type of object, is give them names like simCloud1, simCloud2, simCloud3 etc.. Maybe adding them to a group also.
01/07/2008 (9:50 pm)
You're better off using unique names for your objects. You can give them the same class if you want, but not the same exact name. Otherwise I think there are other issues you will run into besides this.What I do when I have a bunch of the same type of object, is give them names like simCloud1, simCloud2, simCloud3 etc.. Maybe adding them to a group also.
#3
however Joe, i do not know how to dynamically assign names as simCloud1, simCloud2 etc as in my code in original question above
01/08/2008 (11:39 am)
I welcome both replies - thanxhowever Joe, i do not know how to dynamically assign names as simCloud1, simCloud2 etc as in my code in original question above
#4
01/08/2008 (12:03 pm)
You'd have to add a number to the end of the name, incrementing it each time. It could be tricky if you're not doing it in a loop though. I'm not sure if you already know this but you don't have to name them, unless you need to reference them by name in your scripts. If it's all inside a behavior there are functions you can use to access the behaviors in an object. So you may be able to get away with not naming them.
#5
You probably aren't having such a noobish problem, but just in case I thought I'd throw that in.
02/21/2008 (9:46 am)
I had a similar problem. I had copy/paste a behavior and forgot to rename the behavior in the copied file. All the objects were confused on which behavior to actually use.You probably aren't having such a noobish problem, but just in case I thought I'd throw that in.
#6
Second, does what you're saying above mean that I can't use a loop to create objects because they'll all have the same instance of the behavior? For instance (no pun) I create a SimGroup:
new SimGroup(AttackGroup);
Then if I loop through and add a behavior (once I figure out how to)
for (%i = 0; %i < AttackGroup.getCount(); %i++)
{
AttackGroup.getObject(%i).addBehavior("WorldLimitWrap");
}
Then all my AttackGroup objects will have the same instance of WorldWrapLimit and if a faster object hits it's limit before the others than all of them will execute the behavior at the same time?
Thanks,
Joe B
03/06/2008 (9:48 am)
I am so not in the same league as you folks (yet) but I am trying to work with behaviors. I have a couple of questions. First, how do I programatically add a behavior to an object? For instance, I've downloaded the WorldLimitWrap behavior and it works just fine for anything I create statically but I am creating animated objects on the fly and would like to add the behavior. I've tried $object.addBehavior("WorldLimitWrap"); and $object.addBehavior(WorlLimitWrap); and neither works.Second, does what you're saying above mean that I can't use a loop to create objects because they'll all have the same instance of the behavior? For instance (no pun) I create a SimGroup:
new SimGroup(AttackGroup);
Then if I loop through and add a behavior (once I figure out how to)
for (%i = 0; %i < AttackGroup.getCount(); %i++)
{
AttackGroup.getObject(%i).addBehavior("WorldLimitWrap");
}
Then all my AttackGroup objects will have the same instance of WorldWrapLimit and if a faster object hits it's limit before the others than all of them will execute the behavior at the same time?
Thanks,
Joe B
#7
Now that I know what the root problem is, I can work around it. Knowing what's happening also gives me some notion of where to look in the source code to possibly come up with a patch for an engine-level fix.
10/06/2010 (7:37 pm)
I can confirm this is still a problem in 1.7.4. It's shocking to me more people don't get bitten by this... if not "bug," at least "unintended consequence". This is probably the very reason why cloneWithBehaviors doesn't copy the template's name. Also can't believe that this is the only thread I could find on this problem, AND how hard it was to find it. (Here are some keywords, so the next poor schmuck like me will hopefully have it a little easier: tgb clone behavior owner bug.)Now that I know what the root problem is, I can work around it. Knowing what's happening also gives me some notion of where to look in the source code to possibly come up with a patch for an engine-level fix.
Torque Owner D. Robert Duke
It appears that if you assign a behavior to an object with a name ( as in %obj.getName() !$= "" ), the behaviorInstance's .owner field is set to the object's name instead of its ID number. This is a problem if you have multiple objects with the same name, because each behaviorInstance's .owner field will only point to the most recently created of those objects.
Example - you have three objects named simCloud:
Id Name
145 simCloud
146 simCloud
147 simCloud
And you've added the same behavior to each, and part of that behavior is this:
function BehaviorTest::onMouseMove(%this)
{
echo(%this.owner);
echo(%this.owner.getId());
}
This will output "simCloud" and "147" three times whenever the mouse moves because the .owner field is set to a name instead of an id. But if you create the objects without a name, .owner is filled with the correct Id number and it works correctly.
Try changing your line
"%ghost= new t2dAnimatedSprite(%ghostname)" to
"%ghost= new t2dAnimatedSprite()"
Are we the only two people to try assigning behaviors to objects with non-unique names? This has got to be a common thing, but I can't find any other threads on this subject.