2015-02-04 15 views
8

Ho guardato il gioco di Banana da WWDC che è scritto in Objective - C stava cercando di convertire il codice in swift per importare animazioni e transizioni tra di loro ma sto avendo problemi nell'esecuzione delle animazioni in rapido da DAE File.Aggiunta e transizione di animazioni in SceneKit

Ho esportato file DAE in entrambi i formati AutoDesk da 3DSMAx e in formato openCollada. L'autodeskformat dell'animazione è per ogni osso quindi non riesco a chiamare un'animazione per nome, quindi mi limito a importare la scena e faccio quanto segue per l'animazione per iniziare non appena il file viene caricato.

scene = SCNScene(named: "monster.scnassets/monsterScene.DAE") 
    scene2 = SCNScene(named:"monster.scnassets/monster.DAE") 

    var heroNode = SCNNode() 
    heroNode = scene.rootNode.childNodeWithName("heroNode", recursively: false)! 

    var nodeArray = scene2.rootNode.childNodes 
     for childNode in nodeArray { 
     heroNode.addChildNode(childNode as SCNNode) 
    } 

Anche se l'animazione viene riprodotta non appena inizia la scena, ho capito come memorizzare l'animazione.

Se esporto il file collada utilizzando openCollada. È possibile utilizzare quanto segue per eseguire l'acquisizione ed eseguire l'animazione in quanto vi è una sola animazione per l'intero oggetto invece di ogni osso nel caso del formato Collada di AutoDesk. In questo modo posso memorizzare l'animazione anche usando CAAnimation.

 var anim = scene2.rootNode.animationForKey("monster-1") 
     childNode.addAnimation(anim, forKey: "monster-1") 

Ma poi il personaggio corre ad angolo e corre avanti e indietro invece di correre nello stesso punto.

Anche l'illuminazione è migliore con OpenCollada. Vorrei solo usare openCollada invece di autodesk collada export. In questo momento sto usando il formato openCollada per esportare la scena e autodesk per esportare caratteri.

Come animare le animazioni in SceneKit e passare da una all'altra? Grazie. : D

risposta

13

Se non si modificano le opzioni predefinite quando si carica una scena da un file, tutte le animazioni nella scena vengono immediatamente allegate ai propri nodi di destinazione e riprodotte. (Vedere Animation Import Options nel riferimento all'API di SceneKit.)

Se si desidera caricare le animazioni da un file di scena e trattenerle per il collegamento ai nodi (ovvero, la riproduzione) in un secondo momento, è meglio caricarle con la classe SCNSceneSource. Inoltre, puoi (ma non devi) memorizzare il tuo modello base in un file e le animazioni in altri file.


Basta guardare questo codice di caricamento dell'ananas Bananas. Basta guardarlo. *

// In AAPLGameLevel.m: 
SCNNode *monkeyNode = [AAPLGameSimulation loadNodeWithName:nil fromSceneNamed:@"art.scnassets/characters/monkey/monkey_skinned.dae"]; 
AAPLMonkeyCharacter *monkey = [[AAPLMonkeyCharacter alloc] initWithNode:monkeyNode]; 
[monkey createAnimations]; 

// In AAPLSkinnedCharacter.m (parent class of AAPLMonkeyCharacter): 
+ (CAAnimation *)loadAnimationNamed:(NSString *)animationName fromSceneNamed:(NSString *)sceneName 
{ 
    NSURL *url = [[NSBundle mainBundle] URLForResource:sceneName withExtension:@"dae"]; 
    SCNSceneSource *sceneSource = [SCNSceneSource sceneSourceWithURL:url options:nil ]; 
    CAAnimation *animation = [sceneSource entryWithIdentifier:animationName withClass:[CAAnimation class]]; 
    //... 
} 

// In AAPLMonkeyCharacter.m: 
- (void)update:(NSTimeInterval)deltaTime 
{ 
    // bunch of stuff to decide whether/when to play animation, then... 
    [self.mainSkeleton addAnimation:[self cachedAnimationForKey:@"monkey_get_coconut-1"] forKey:nil]; 
    //... 
} 

quello che sta succedendo qui:

  1. C'è una classe personalizzata gestione del personaggio animato. Possiede un SCNNode contenente il modello di carattere, nonché un gruppo di CAAnimation s per tutte le cose che il modello può fare (inattivo/salta/lancia/ecc.).
  2. Quella classe viene inizializzata passando il nodo di carattere caricato da un file DAE. (AAPLGameSimulation loadNodeWithName:fromSceneNamed: è un comodo wrapper che carica il SCNScene da un file e ne estrae un nodo con nome.) Quel file DAE contiene solo il modello di carattere, senza animazioni.
  3. Quindi, AAPLMonkeyCharacter carica (e memorizza riferimenti a) le animazioni di cui ha bisogno dai file DAE separati contenenti ciascuna animazione. Qui entra in gioco lo SCNSceneSource - ti consente di estrarre le animazioni dal file senza riprodurle.
  4. Quando è il momento di giocare, la classe scimmia chiama addAnimation:forKey: per eseguire l'animazione sul suo nodo principale.

Traducendo a Swift e l'applicazione al vostro problema - in cui ti sembra di avere tutte le animazioni nello stesso file - mi piacerebbe fare qualcosa di simile (vaga sagoma di una classe ipotetica):

class Monster { 
    let node: SCNNode 
    let attackAnimation: CAAnimation 

    init() { 
     let url = NSBundle.mainBundle().URLForResource(/* dae file */) 
     let sceneSource = SCNSceneSource(URL: url, options: [ 
      SCNSceneSourceAnimationImportPolicyKey : SCNSceneSourceAnimationImportPolicyDoNotPlay 
     ]) 
     node = sceneSource.entryWithIdentifier("monster", withClass: SCNNode.self) 
     attackAnimation = sceneSource.entryWithIdentifier("monsterIdle", withClass: CAAnimation.self) 
    } 

    func playAttackAnimation() { 
     node.addAnimation(attackAnimation, forKey: "attack") 
    } 
} 

I bit chiave:

  • SCNSceneSourceAnimationImportPolicyDoNotPlay fa in modo che i nodi caricati dalla sorgente scena non cominciano con le animazioni collegate/gioco.
  • È necessario caricare le animazioni separatamente con entryWithIdentifier:withClass:. Assicurati di configurarli come preferisci (ripetere, sbiadire la durata, ecc.) Prima di collegarli ai nodi.
+0

Grazie controllerò. : D. non riesci nemmeno a far valere la tua risposta. Bisogno di 15 rep –

Problemi correlati