I want to get a current node position form an animated SCNNode
I am aware of presentationNode
and I tried to extract position form there, but no Luck
Here is my Code
SCNNode * pelvis = [_unit childNodeWithName:@"Bip01_Pelvis" recursively:YES];
SCNNode * present = pelvis.presentationNode;
SCNVector3 position = [self convertPosition:present.position toNode:self.parentNode];
The position I have is the position of the SCNNode
in the "rest" mode before the CAAnimation
was applied.
How to get properties like position form the 'presentationNode'?
Edit
Class itself relevant parts:
@interface UndeadSimple : RepresentationNode <CAAnimationDelegate>
{
//Animations
SCNNode * _undead;
CAAnimation * _currentAnimation;
NSString * _currAnimationkey;
CAAnimation * _death1;
...
SCNNode * _audioNode;
SCNAudioSource * _deathSource;
SCNAudioPlayer * _player;
}
Init:
NSString * sceneName = @ZOMBIE;
SCNScene *scene2 = [SCNScene sceneNamed:sceneName];
_undead = [SCNNode node];
for(SCNNode * node in scene2.rootNode.childNodes)
{
[_undead addChildNode:node];
[node removeAllAnimations];
}
[_undead setScale:(SCNVector3Make(0.024, 0.02, 0.024))];
[self addChildNode:_undead];
[_undead removeAllAnimations];
_currentAnimation = _idleAnimation;
_currAnimationkey = @"resting";
[_undead addAnimation:_currentAnimation forKey:_currAnimationkey];
Animation and event:
SCNAnimationEvent * event2 = [SCNAnimationEvent animationEventWithKeyTime:0.9 block:^(CAAnimation * _Nonnull animation, id _Nonnull animatedObject, BOOL playingBackward)
{
[self.delegate finishedDeathAnimation];
}];
_death1 = anims.death1.mutableCopy;
[_death1 setDelegate:self];
[_death1 setFillMode:kCAFillModeForwards];
_death1.removedOnCompletion = NO;
[_death1 setAnimationEvents:@[event2]];
Animation Call:
- (void)die
{
if([_currAnimationkey isEqualToString:@"dead"])
{
return;
}
[_undead removeAllAnimations];
CAAnimation * death = nil;
int anim = arc4random_uniform(3);
if(anim < 1)
{
death = _death1;
}
else if(anim < 2)
{
death = _death2;
}
else
{
death = _death3;
}
_currAnimationkey = @"dead";
_currentAnimation = death;
}
//Helper Method to get presentation Node
- (SCNNode *)getSnapNode
{
SCNNode * repNode = [_undead presentationNode];
_undead.transform = repNode.transform;
repNode = _undead.clone;
return repNode;
}
//On callback call and try to get position:
- (void)finishedDeathAnimation
{
SCNPlane * bloodgeometry = [SCNPlane planeWithWidth:4 height:4];
bloodgeometry.firstMaterial.diffuse.contents = [NSImage imageNamed:@"blood"];
SCNNode * bloodNode = [SCNNode node];
[bloodNode setEulerAngles:SCNVector3Make(-M_PI_2, 0, 0)];
bloodNode.geometry = bloodgeometry;
//Bip01_Pelvis
SCNNode * deadBody = [_unit getSnapNode];
SCNNode * pelvis = [deadBody childNodeWithName:@"Bip01_Pelvis" recursively:YES];
SCNNode * present = pelvis.presentationNode;
SCNVector3 position = [self convertPosition:present.position toNode:self.parentNode];
NSLog(@"pelvis position %lf,%lf,%lf", present.position.x, present.position.y, present.position.z); //Always {0,0,0}
bloodNode.position = SCNVector3Make(position.x, 0.0001, position.z);
[self.parentNode addChildNode:bloodNode];
[self removeFromParentNode];
}
Edit 2
I also tried to simplify it a bit:
another helper method:
//in undead/unit class
- (SCNVector3)getPosition
{
SCNNode * repNode = [[_undead childNodeWithName:@"Bip01_Pelvis" recursively:YES] presentationNode];
return repNode.position;
}
On callback:
- (void)finishedDeathAnimation
{
position = [_unit getPosition];
NSLog(@"pelvis position %lf,%lf,%lf", position.x, position.y, position.z); //Alway 0,0,0 as well :(
}
It is rare to find someone just like me still believe in Objective C rather than swift thats why i would like to offer full help.
I was having this issue for an animation exported from Blender as a Collada but have succeeded to get the actual position after few tries.
Using presentationNode is the correct way but you need to get it from the child while you making the animation for example this is how to run animation for a node Called _monkey notice that at the last Code i got the _present From the child.presentationNode Not from _monkey.presentationNode Also it have to be obtained during the enumeration not after
so first i need to define
NSNode * _present;
then i do play the animation
[_monkey enumerateChildNodesUsingBlock:^(SCNNode *child, BOOL *stop)
{
for(NSString *key in child.animationKeys)
{ // for every animation key
CAAnimation *animation = [child animationForKey:key]; // get the animation
animation.usesSceneTimeBase = NO; // make it system time based
animation.repeatCount = FLT_MAX; // make it repeat forever
animation.speed = 0.2;
[child addAnimation:animation forKey:key]; // animations are copied upon addition, so we have to replace the previous animation
}
_present = child.presentationNode;
}];
Then Under the render i can check the Results which is changing as the animation moves (Also if you have worked with iOS11 you can check worldPosition instead of position it gives great results too).
- (void)renderer:(id <SCNSceneRenderer>)renderer didSimulatePhysicsAtTime:(NSTimeInterval)time
{
NSLog(@" Location X:%f Y:%f Z:%f", _present.position.x, _present.position.y, _present.position.z);
}
Finally Here Is The Results
Y:-2.505034 Z:4.426160
2017-10-11 04:42:19.700435+0200 monkey[547:137368] Location X:-5.266642 Y:-2.480119 Z:4.427162
2017-10-11 04:42:19.720763+0200 monkey[547:137368] Location X:-5.215315 Y:-2.455228 Z:4.428163
2017-10-11 04:42:19.740449+0200 monkey[547:137346] Location X:-5.163589 Y:-2.430143 Z:4.429171
2017-10-11 04:42:19.760397+0200 monkey[547:137368] Location X:-5.112190 Y:-2.405216 Z:4.430173
2017-10-11 04:42:19.780557+0200 monkey[547:137346] Location X:-5.060925 Y:-2.380355 Z:4.431173
2017-10-11 04:42:19.800418+0200 monkey[547:137342] Location X:-5.008560 Y:-2.355031 Z:4.432024
This Give Me Good Results. Hope it would work with you.
There's no animation running, at least not in the code you've shown us. Check the presentation node's position while the animation is playing, perhaps in renderer:updateAtTime:
(see SCNRendererDelegate).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With