2016-11-30 55 views
5

我希望得到一個當前節點位置形成動畫SCNNode 我知道presentationNode,我試圖獲取位置的形式存在,但沒有運氣SceneKit獲取當前SCNNode位置形式動畫SCNNode

這裏是我的代碼

SCNNode * pelvis = [_unit childNodeWithName:@"Bip01_Pelvis" recursively:YES]; 
SCNNode * present = pelvis.presentationNode; 



SCNVector3 position = [self convertPosition:present.position toNode:self.parentNode]; 

我所擁有的位置是SCNNodeCAAnimation應用之前的「休息」模式中的位置。

如何從'presentationNode'獲取位置等屬性?

編輯

類本身相關部分:

@interface UndeadSimple : RepresentationNode <CAAnimationDelegate> 
{ 
    //Animations 
    SCNNode * _undead; 

    CAAnimation * _currentAnimation; 
    NSString * _currAnimationkey; 

    CAAnimation * _death1; 
    ... 

    SCNNode  * _audioNode; 
    SCNAudioSource * _deathSource; 
    SCNAudioPlayer * _player; 
} 

初始化:

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]; 

動畫和事件:

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]]; 

動畫召喚:

- (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方法獲取呈現節點

- (SCNNode *)getSnapNode 
{ 
    SCNNode * repNode = [_undead presentationNode]; 
    _undead.transform = repNode.transform; 
    repNode = _undead.clone; 
    return repNode; 
} 

//回撥電話,並得到位置:

- (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]; 
} 

編輯2

我還試圖簡化它有點:

另一個輔助方法:

//在亡靈/單元類

- (SCNVector3)getPosition 
{ 
    SCNNode * repNode = [[_undead childNodeWithName:@"Bip01_Pelvis" recursively:YES] presentationNode]; 
    return repNode.position; 
} 

在回調:

- (void)finishedDeathAnimation 
{ 
    position = [_unit getPosition]; 
    NSLog(@"pelvis position %lf,%lf,%lf", position.x, position.y, position.z); //Alway 0,0,0 as well :(
} 

回答

1

很難找到像我這樣的人仍然相信客觀C而不是迅速多數民衆贊成爲什麼我想提供全面的幫助。

我對從Blender作爲Collada導出的動畫有問題,但在幾次嘗試後都成功獲取了實際位置。

使用presentationNode是正確的方法,但您需要從製作動畫時獲取它,例如這是如何爲節點運行動畫調用_monkey通知,在最後一個代碼中,我得到了_present從孩子從_monkey.presentationNode .presentationNode不是也有它不後

枚舉期間獲得所以首先我需要定義

NSNode * _present; 

那我就播放動畫

[_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; 
    }]; 

然後,在渲染下,我可以檢查隨着動畫移動而改變的結果(此外,如果您使用過iOS11,則可以檢查worldPosition而不是位置,它也會給出很好的結果)。

- (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); 

} 

最後這是效果

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 

這給我很好的效果。希望它能和你一起工作。

1

沒有動畫正在運行,至少在您向我們顯示的代碼中沒有。檢查演示節點在動畫播放時的位置,可能在renderer:updateAtTime:(請參閱SCNRendererDelegate)。

+0

我確保你的動畫正在運行,我做了一個SCNAnimationEvent來獲取委託,當它接近尾聲 - 試圖從演示節點提取posion - 但它總是返回SCNVectorZero :-( – ColdSteel

+0

請編輯你的問題到向我們展示您實際使用的代碼,包括啓動動畫的代碼。這些東西的時間安排和順序很重要,您還沒有給我們太多的幫助。 –

+0

Mr. Hal,我編輯了我的問題,幾乎添加了所有相關的代碼 – ColdSteel