[SOLVED]4:32am and my cloned T2DAnimatedSprite has invalid animation data ><
by Bob Dobbs · in Torque X 2D · 09/11/2010 (7:48 pm) · 9 replies
Hey Folks, burning a bit of the midnight oil and come across a strange one and would appreciate anyone's advice / assistance / help.
I hate having to burden peeps with questions but it's 4:32 am and my head's cabbage T_T
I'm making a spawner based on Henry Shillings GameKit and the PlatformerKit
In my Spawner Component I use
The corresponding SceneObject (with the Spawner component attached) takes the following params
Now, the T2DAnimatedSprite I'm cloning / Spawning is actually 3 animated sprites mounted on top of each other (Head, Torso & Legs)
When I spawn just the torso, because it should inherit all Mount properties; the legs and head clone just fine, no problem there.
The issue is in my AIChaseComponent (which is for enemies chasing main player) I need to change which animation is being played for the cloned T2DAnimatedSprite like so
ie as the enemy gets closer his animation is changed into a "lunge"
At runtime, the the template begins to clone and spawn no problems at all but as soon as it hits the PlayEnemyAnimation I get the following Fatal Assert error msg

So I insert a few breakpoints and see if there is Animation Data for the Cloned T2DAnimatedSprite
et viola just after spawning, seems there's AnimationData in there ok

So how about when I call the PlayEnemyAnimation ?

hmmm....Seem there's animationData present
so how about within the PlayEnemyAnimation having a look at both the T2DAnimatedSprite and T2DAnimation Data

seems there's animation data and sprite but just not playing and causing that nasty Fatal assert error above.
I was thinking might be a problem in the
like so
and also same thing in the Spawner component
I've tried just messing around with the built in Spawner Object in the Editor and non mounted sprites, just singles and no matter what each time I clone I cant directly change the sprites animation using TheT2DSprite.PlayAnimation(TheCorrespondingAnimationData);
what am I missing here ? I really need to find a way to change the animations of my cloned items, so would really appreciate any ideas. A 1000 dollars and a newborn calf to any man who can answer
Much obliged
I hate having to burden peeps with questions but it's 4:32 am and my head's cabbage T_T
I'm making a spawner based on Henry Shillings GameKit and the PlatformerKit
In my Spawner Component I use
T2DAnimatedSprite spawnedEnemy = _enemyTorso.Clone() as T2DAnimatedSprite;
The corresponding SceneObject (with the Spawner component attached) takes the following params
public T2DSceneObject SceneObject
{
get { return Owner as T2DSceneObject; }
}
public T2DAnimatedSprite enemyHead
{
set { _enemyHead = value; }
get { return _enemyHead; }
}
public T2DAnimationData enemyHeadAnim
{
set { _enemyHeadAnim = value; }
get { return _enemyHeadAnim; }
}
public T2DAnimatedSprite enemyTorso
{
set { _enemyTorso = value; }
get { return _enemyTorso; }
}
public T2DAnimationData enemyTorsoAnim
{
set { _enemyTorsoAnim = value; }
get { return _enemyTorsoAnim; }
}
public T2DAnimatedSprite enemyLegs
{
set { _enemyLegs = value; }
get { return _enemyLegs; }
}
public T2DAnimationData enemyLegsAnim
{
set { _enemyLegsAnim = value; }
get { return _enemyLegsAnim; }
}
[TorqueXmlSchemaType(DefaultValue = "50")]
public int SpawnCount
{
get { return _spawnCount; }
set { _spawnCount = value; }
}
[TorqueXmlSchemaType(DefaultValue = "2")]
public float SpawnTime
{
get { return _spawnTime; }
set { _spawnTime = value; }
}
[TorqueXmlSchemaType(DefaultValue = "1")]
public float SpawnVariance
{
get { return _spawnVariance; }
set { _spawnVariance = value; }
}
[TorqueXmlSchemaType(DefaultValue = "true")]
public bool SpawnEnabled
{
get { return _spawnEnabled; }
set { _spawnEnabled = value; }
}
public enum SpawnOrientation : int
{
Area, Edges, Center, Top, Left, Right, Bottom, LeftTopRight,
}
[TorqueXmlSchemaType(DefaultValue = "Area")]
public SpawnOrientation SpawnLocation
{
get { return _spawnLocation; }
set { _spawnLocation = value; }
}Now, the T2DAnimatedSprite I'm cloning / Spawning is actually 3 animated sprites mounted on top of each other (Head, Torso & Legs)
When I spawn just the torso, because it should inherit all Mount properties; the legs and head clone just fine, no problem there.
The issue is in my AIChaseComponent (which is for enemies chasing main player) I need to change which animation is being played for the cloned T2DAnimatedSprite like so
if (dist < 200.0f)
{
PlayEnemyAnimation(_enemyHeadAnim, _enemyTorsoAnimLunge, _enemyLegsAnim);
_sceneObject.Physics.Velocity = T2DVectorUtil.VelocityFromTarget(_sceneObject.Position, _TargetObject.Position, _speed + 75);
}
else
{
PlayEnemyAnimation(_enemyHeadAnim, _enemyTorsoAnim, _enemyLegsAnim);
_sceneObject.Physics.Velocity = T2DVectorUtil.VelocityFromTarget(_sceneObject.Position, _TargetObject.Position, _speed);
}ie as the enemy gets closer his animation is changed into a "lunge"
At runtime, the the template begins to clone and spawn no problems at all but as soon as it hits the PlayEnemyAnimation I get the following Fatal Assert error msg

So I insert a few breakpoints and see if there is Animation Data for the Cloned T2DAnimatedSprite
et viola just after spawning, seems there's AnimationData in there ok

So how about when I call the PlayEnemyAnimation ?

hmmm....Seem there's animationData present
so how about within the PlayEnemyAnimation having a look at both the T2DAnimatedSprite and T2DAnimation Data

seems there's animation data and sprite but just not playing and causing that nasty Fatal assert error above.
I was thinking might be a problem in the
public override void CopyTo(TorqueComponent obj)when I'm doing my obj2.Copyto etc but both the spawner and the AiChase Component has the 3 relevant animated sprites AND the animation data copied to the obj
like so
AiPlayerChaseComponent obj2 = (AiPlayerChaseComponent)obj;
obj2.enemyHead = enemyHead;
obj2.enemyTorso = enemyTorso;
obj2.enemyLegs = enemyLegs;
obj2._enemyHeadAnim = _enemyHeadAnim;
obj2._enemyTorsoAnim = _enemyTorsoAnim;
obj2._enemyTorsoAnim2 = _enemyTorsoAnimLunge;
obj2._enemyLegsAnim = _enemyLegsAnim;
obj2.TargetObject = TargetObject;
obj2.AIType = AIType;
obj2.Active = Active;
obj2.Speed = Speed;and also same thing in the Spawner component
I've tried just messing around with the built in Spawner Object in the Editor and non mounted sprites, just singles and no matter what each time I clone I cant directly change the sprites animation using TheT2DSprite.PlayAnimation(TheCorrespondingAnimationData);
what am I missing here ? I really need to find a way to change the animations of my cloned items, so would really appreciate any ideas. A 1000 dollars and a newborn calf to any man who can answer
Much obliged
#2
it looks like this in the playerChaseComponent
and in the spawnerComponent like so
I'll be addign a whole bunch of other animations as well for each of the Head, Torso & Legs like "attack", "die", "wave arms", etc so I kinda need to find a way to get those clones animating (the chase component works fine as does the actual cloning) just no animation (!?)
P'raps Pool with components !? or cross copy the Spawner & Chase component in each copyto respectively ?
I'm at a loss
09/11/2010 (8:12 pm)
wow that was fast ! Much appreciatedit looks like this in the playerChaseComponent
public override void CopyTo(TorqueComponent obj)
{
base.CopyTo(obj);
AiPlayerChaseComponent obj2 = (AiPlayerChaseComponent)obj;
obj2.enemyHead = enemyHead;
obj2.enemyTorso = enemyTorso;
obj2.enemyLegs = enemyLegs;
obj2._enemyHeadAnim = _enemyHeadAnim;
obj2._enemyTorsoAnim = _enemyTorsoAnim;
obj2._enemyTorsoAnimLunge = _enemyTorsoAnimLunge;
obj2._enemyLegsAnim = _enemyLegsAnim;
obj2.TargetObject = TargetObject;
obj2.AIType = AIType;
obj2.Active = Active;
obj2.Speed = Speed;
}and in the spawnerComponent like so
public override void CopyTo(TorqueComponent obj)
{
base.CopyTo(obj);
Spawner obj2 = obj as Spawner;
obj2.enemyHead = enemyHead;
obj2.enemyTorso = enemyTorso;
obj2.enemyLegs = enemyLegs;
obj2._enemyHeadAnim = _enemyHeadAnim;
obj2._enemyTorsoAnim = _enemyTorsoAnim;
obj2._enemyTorsoAnimLunge = _enemyTorsoAnimLunge;
obj2._enemyLegsAnim = _enemyLegsAnim;
obj2.SpawnCount = SpawnCount;
obj2.SpawnTime = SpawnTime;
obj2.SpawnVariance = SpawnVariance;
obj2.SpawnEnabled = SpawnEnabled;
obj2.SpawnLocation = SpawnLocation;
}I'll be addign a whole bunch of other animations as well for each of the Head, Torso & Legs like "attack", "die", "wave arms", etc so I kinda need to find a way to get those clones animating (the chase component works fine as does the actual cloning) just no animation (!?)
P'raps Pool with components !? or cross copy the Spawner & Chase component in each copyto respectively ?
I'm at a loss
#3
09/11/2010 (8:49 pm)
Yeah, pool with components is almost necessary. I have crashes without that being ticked. Try that. If that doesn't work, can you tell me where in the update logic are you changing the animationdata. Is it outside of processtick?
#4
I'm Updating the animation right inside the ProcessTick as expected
the called function UpdateChase is darned simple too
curiouser and curiouser
09/12/2010 (3:29 am)
Thanks for getting back & sorry for delay, had to sleep ! flipped the various options with pool, pool with components but to no success.I'm Updating the animation right inside the ProcessTick as expected
public void ProcessTick(Move move, float elapsed)
{
if (!_active)
return;
switch (_aiType)
{
case EnemyAITypes.Chase:
_UpdateChase(elapsed);
break;
case EnemyAITypes.Avoid:
_UpdateAvoid(elapsed);
break;
}
return;
}the called function UpdateChase is darned simple too
private void _UpdateChase(float elapsed)
{
float angle = T2DVectorUtil.AngleFromTarget(_sceneObject.Position, _TargetObject.Position);
_sceneObject.Rotation = angle;
float dist = Vector2.Distance(_TargetObject.Position, _sceneObject.Position);
if (dist < 200.0f)
{
PlayEnemyAnimation(_enemyHeadAnim, _enemyTorsoAnimLunge, _enemyLegsAnim);
_sceneObject.Physics.Velocity = T2DVectorUtil.VelocityFromTarget(_sceneObject.Position, _TargetObject.Position, _speed + 75);
}
else
{
enemyTorso.PlayAnimation(_enemyTorsoAnim);
//PlayEnemyAnimation(_enemyHeadAnim, _enemyTorsoAnim, _enemyLegsAnim);
_sceneObject.Physics.Velocity = T2DVectorUtil.VelocityFromTarget(_sceneObject.Position, _TargetObject.Position, _speed);
}curiouser and curiouser
#5
www.13hours.net/src/AiPlayerChaseComponent.cs
www.13hours.net/src/Spawner.cs
09/12/2010 (4:11 am)
might be handy I upped the two componentswww.13hours.net/src/AiPlayerChaseComponent.cs
www.13hours.net/src/Spawner.cs
#6
try:
09/12/2010 (4:27 am)
It's gotta be the fact that you are calling PlayAnimation twice in succession with it. I mean, there really isn't a point in it and it's the only thing I see thats related that seems off.try:
public void PlayEnemyAnimation(T2DAnimationData enemyHeadAnimationData, T2DAnimationData enemyTorsoAnimationData, T2DAnimationData enemyLegsAnimationData)
{
if (enemyHead != null)
{
if (enemyHead.AnimationData != enemyHeadAnimationData || !enemyHead.IsAnimationPlaying)
{
enemyHead.PlayAnimation(enemyHeadAnimationData);
}
}
if (enemyTorso != null)
{
if (enemyTorso.AnimationData != enemyTorsoAnimationData || !enemyTorso.IsAnimationPlaying)
{
enemyTorso.PlayAnimation(enemyTorsoAnimationData);
}
}
if (enemyLegs != null)
{
if (enemyLegs.AnimationData != enemyLegsAnimationData || !enemyLegs.IsAnimationPlaying)
{
enemyLegs.PlayAnimation(enemyLegsAnimationData);
}
}
}
#7
Cheers M8
09/12/2010 (11:59 am)
Thanks ! Hmm gave that a try but to no avail, still invalid animation data error...I will doodle around some more see if I can come up with something but in the meantime if you (or anyone else for that matter) notices whats up would be glad of any assistance.Cheers M8
#8
like so
This clones the item from the original template which has the
AiPlayerChaseComponent.cs attached to it.
my AiPlayerChaseComponent.cs updates the animation but it appears to be attempting to update the template's animation and not the cloned item.
Just to make sure; when I spawned the new enemy in the spawner.cs code I added
just after the enemy is spawned and et viola he animates OK
BUT the problem is I want to control animation from the
AiPlayerChaseComponent.cs not from the spawner so its not much use.
How on earth would I find the instance of each individual spawned item (spawnedEnemyHead, etc) in the AiPlayerChaseComponent and then animate it ?
hmm or should I remove the AiPlayerChaseComponent from my template and add it at runtime...
gaahhh my heads in knots ><
09/12/2010 (4:47 pm)
Ahhh Hold on....I think the reason there animation data is invalid is because when I spawn the item in my Spawner.Cs I'm making a new T2DAnimatedSprite named spawnedEnemylike so
T2DAnimatedSprite spawnedEnemy = _enemyTorso.Clone() as T2DAnimatedSprite;
This clones the item from the original template which has the
AiPlayerChaseComponent.cs attached to it.
my AiPlayerChaseComponent.cs updates the animation but it appears to be attempting to update the template's animation and not the cloned item.
Just to make sure; when I spawned the new enemy in the spawner.cs code I added
TorqueObjectDatabase.Instance.Register(spawnedEnemyHead);
TorqueObjectDatabase.Instance.Register(spawnedEnemyTorso);
TorqueObjectDatabase.Instance.Register(spawnedEnemyLegs);
_enemyHeadAnim.Init();
_enemyHeadAnim.AnimationCycle = true;
_enemyTorsoAnim.Init();
_enemyTorsoAnim.AnimationCycle = true;
_enemyLegsAnim.Init();
_enemyLegsAnim.AnimationCycle = true;
spawnedEnemyHead.PlayAnimation(_enemyHeadAnim);
spawnedEnemyTorso.PlayAnimation(_enemyTorsoAnim);
spawnedEnemyLegs.PlayAnimation(_enemyLegsAnim);
_currentCount++;just after the enemy is spawned and et viola he animates OK
BUT the problem is I want to control animation from the
AiPlayerChaseComponent.cs not from the spawner so its not much use.
How on earth would I find the instance of each individual spawned item (spawnedEnemyHead, etc) in the AiPlayerChaseComponent and then animate it ?
hmm or should I remove the AiPlayerChaseComponent from my template and add it at runtime...
gaahhh my heads in knots ><
#9
Then within other components getting the instance of each mounted object you have to use GetMountedObject, otherwise any child mounts of the parent object instance will be null.
09/17/2010 (10:51 am)
SOLVED - After Cloning a sprite with other mounted sprites, the animation data must be initialised; otherwise you get "invalid animation data" error.spawnedEnemyHead.AnimationData.Init(); spawnedEnemyTorso.AnimationData.Init(); spawnedEnemyLegs.AnimationData.Init(); spawnedEnemyHead.AnimationData.AnimationCycle = true; spawnedEnemyTorso.AnimationData.AnimationCycle = true; spawnedEnemyLegs.AnimationData.AnimationCycle = true; TorqueObjectDatabase.Instance.Register(spawnedEnemyHead); TorqueObjectDatabase.Instance.Register(spawnedEnemyTorso); TorqueObjectDatabase.Instance.Register(spawnedEnemyLegs); spawnedEnemyHead.Mount(spawnedEnemyTorso, "Head", true); spawnedEnemyLegs.Mount(spawnedEnemyTorso, "Legs", true); _enemyHeadAnim.Init(); _enemyHeadAnim.AnimationCycle = true; _enemyTorsoAnim.Init(); _enemyTorsoAnim.AnimationCycle = true; _enemyLegsAnim.Init(); _enemyLegsAnim.AnimationCycle = true;
Then within other components getting the instance of each mounted object you have to use GetMountedObject, otherwise any child mounts of the parent object instance will be null.
T2DAnimatedSprite sceneObjectLegs = (T2DAnimatedSprite)_sceneObject.GetMountedObject("Legs");
T2DAnimatedSprite sceneObjectHead = (T2DAnimatedSprite)_sceneObject.GetMountedObject("Head");
Torque Owner Christopher Perkins
I think you just forgot to copy it from the template with CopyTo(it gets called when you clone).