2017-05-21 51 views
0

我有一個行爲,我不明白使用SceneKit動畫時的情況。 以下所有代碼均在渲染器的上下文中執行:updateAtTime:delegate調用。SceneKit在動畫開始時閃爍

我建我的動畫是這樣的:

  SCNVector4 startRotation = node.rotation ; 
     SCNVector4 targetRotation = pose.rotation ; 

     CABasicAnimation *rotAnimation = [CABasicAnimation animationWithKeyPath:@"rotation"] ; 
     rotAnimation.fromValue = [NSValue valueWithSCNVector4:startRotation] ; 
     rotAnimation.toValue = [NSValue valueWithSCNVector4:targetRotation] ; 
     rotAnimation.duration = duration ; 

現在,如果我以後這樣做的權利:

  // First change the final rotation state, and then start the animation 
     node.rotation = targetRotation ; 
     [node addAnimation:rotAnimation forKey:animationName] ; 

我的性格在最後位置的快速閃過,然後動畫從startRotation運行到targetRotation並永遠保持在targetRotation位置 - 這是我想要的,除了閃光燈。

如果我這樣做,而不是(只是交換最後兩行排列):

  // First start the animation and then set the final position 
     [node addAnimation:rotAnimation forKey:animationName] ; 
     node.rotation = targetRotation ; 

我沒有閃光燈,但是當動畫結束,字符回到初始位置,這是不是我想要的。

我讀了關於fillMode和removedOnCompletion,但將removedOnCompletion設置爲NO並不是正確的做法,因爲它會讓動畫永遠「運行」。

如何避免初始閃光?

+1

我認爲你應該在'renderer:updateAtTime:'之外做你的動畫,因爲文檔說任何場景變化都會立即應用。 (所以我猜節點在添加動畫之前已經更新了。) –

+0

好吧,差不多......我認爲當你說「在渲染器之外做你的動畫:updateAtTime:」時你是對的。但是,並不是因爲立即應用更改。我經歷了漫長的調查,我想我現在明白髮生了什麼。爲了簡短起見,如果在渲染器內執行,我的代碼完美工作(不閃光):didRenderScene:atTime :.爲了記錄和幫助他人,我會寫詳細的解釋並回答我自己的問題。 –

回答

0

所以這裏是故事。正如它的文檔在蘋果美國,SceneKit呈現發生在一個循環中,一些代表方法被調用的順序如下:

1 - 渲染:updateAtTime:

(SceneKit運行動畫)

2 - 渲染:didApply:AnimationsAtTime:

(...)

4 - 渲染:willRenderSCne:atTime:

SceneKit渲染場景

5 - 渲染:didRenderScene:atTime:

現在,addAnimation的文檔:forKey:也說:「新增的動畫開始的當前運行循環週期後執行結束「。

我追蹤了我的節點及其表示節點的旋轉值。當我在渲染器中添加動畫時:updateAtTime :(第1步),我首先設置節點目標位置,然後添加一個動畫,但在當前運行循環結束之前不會執行該動畫。因此,SceneKit渲染了這個最終位置(在步驟4和5之間),然後在下一個循環中,SceneKit將運行動畫(在步驟1和2之間),並且presentationNode獲取正確的值並在步驟4和5之間再次渲染 - 因此閃光燈。相反,如果我在渲染器didRenderScene:atTime :(步驟5)中添加動畫,則循環結束,則在SceneKit達到渲染時間之前調度動畫並運行(在步驟1和2之間)步驟4和5)。沒有閃光燈。

0

它看起來像你設置節點的旋轉兩次:一次是動畫,一次是直接操作。他們互相干擾。

嘗試完全刪除node.rotation = targetRotation

+1

是的,我這樣做。但這是Apple推薦的動畫製作方式(https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreAnimation_guide/CreatingBasicAnimations/CreatingBasicAnimations.html#//apple_ref/doc/uid/TP40004514-CH3- SW1)。如果您未設置node.rotation,則在動畫結束時,您將回到初始值。問題是,在動畫添加之前似乎需要這樣做 - 這是一個無證的點 - 但是這會使動畫閃爍。 –