參考資料:AnimationState
Unity版本:3.5.6f4
一般在控制AnimationClip播放時,都會使用Animation類別來控制。但如果想要控制播放速度時,確沒有介面可以控制。所以如果要變更播放各個AnimationClip的播放速度的話,就需要直接操作Animation內所儲存的AnimationStates。底下就針對AnimationState的各個屬性與操作介面來進行測試。
I.屬性:
1.enabled:(bool)
此屬性是用來控制目前所對應的AnimationClip能不能進行播放。所以在Animation Clip播放時,將AnimationState.enabled設為false時,時間軸就會停止在當下的時間。之後再把AnimationState.enabled設為true時,時間軸就會從目前停止的時間繼續往下播放。
2.weight:(float)
目前文件寫的看不懂,所以先跳過。
3.wrapMode:(WrapMode)
AnimationClip的播放模式,可以參考[Unity]Animation WarpMode。
4.time:(float)
動畫的播放時間軸,一般是從0到無限大。可以透過強制指定時間軸來讓動畫的時間軸移動到指定的時間,但此時動畫物件本身並不會到達指定時間的狀態,也就是動畫物件會停留在上次停止的位置。當開始播放動畫的時候,就會從指定的時間開始播放。
5.normalizedTime:(float)
normalize的動畫時間。此屬性為0到1。0.5代表動畫的時間的中點。
6.speed:(float)
動畫播放速度,此屬性等於1時,就是正常播放。如要反向播放的話,就只要給定負值就好。為了達到反向播放的效果,也要注意到WrapMode的問題,可以參考[Unity]Animation WarpMode。
7.normalizedSpeed:(float)
normalize的播放速度,一般是做為在兩個動畫間做同步播放使用。根據官方的說法,此屬性會比Animation.SyncLayer()易於使用。
8.length:(float)
Animation Clip的總播放時間,單位為秒。
9.layer:(int)
此屬性用來設定AnimationClip播放時的層級,層級會影響到計算動畫播放時的權重值。越高層級的AnimationClip在計算最後繪製權重時,比較可以優先得到自已所預期需要的權重值。而低層級的AnimationClip僅能使用高層級所不需用到的權重值,換句話說,也就是低層級的僅能撿高層級剩下的來用。
10.clip:(AnimationClip)
要用來播放的AnimationClip。
11.name:(String)
AnimationClip的名稱。
12.blendMode:(AnimationBlendMode)
動畫的繪製模式。可參考 。
II.操作介面:
1.AddMixingTransform(Transform mix, bool recursive = true):
把要有相同的動畫效果的GameObject.transform加到AnimationState內,這樣就可以使用同一個動畫效果套用到不同的GameObject上。這樣可以減少AnimationClip的製作數量。
recursive設為true時,代表所有混合的transform的子物件都將會被以同樣的方式播放動畫。
(目前未測試成功)
2.RemoveMixingTransform(Transform mix):
把加到AnimationState內的GameObject.transform移除。
Showing posts with label Animation. Show all posts
Showing posts with label Animation. Show all posts
[Unity]Animation WarpMode
參考資料:Animation.wrapMode、WrapMode。
Unity版本:3.5.6f4
在Unity內Animation的WrapMode可以透過Script來變更。以下針對各個參數進行說明:
1.WrapMode.Default:
直接拿Amination Clip內設定的wrapMode來進行動畫播放。預設的wrapMode為WrapMode.Once。
2.WrapMode.Once:
當動畫時間軸到達Animation Clip終點時,正在播放中的Animation Clip會被自動的停止播放,並且時間軸會被重設回Animation Clip的一開始。
不過當Animation Clip是從終點反向播放到起點時,雖然在播放到起點時會也會被自動停止,但是時間軸並不會被重置回終點,而是留在起點。
3.WrapMode.Loop:
當動畫時間軸到達Animation Clip的終點時,時間軸會又回到起點的位置,並且繼續播放動畫。如果將播放模式設為反向時(即將Animation[ClipName].speed設為負值),則會從反向播放動畫,而播放的起點與終點都會跟正向播放時相反。
Note:根據官方的說法,將AnimationState.speed設為負值時,Animation Clip就會被反向播放(A negative playback speed will play the animation backwards.)。但目前測試由3dMax匯出的Animation以及使用Unity Animation所做出的Clip,在播放移動Animation時,把AnimationState.speed設為-1,播放的結果是物件直接跳到起始位置,並沒在從終點移動到起點位置。這邊還需要再確認問題點在那邊。
Note(2012/11/20):
今找到原因了,原先測試時,只有變更AnimationState.speed,而沒有去變更AnimationState.time。所以播放時,時間軸就已經在0的位置了,也因此看不到動畫做動。如要反向播放動畫則需變更AnimationState.Speed為負值以及設定AnimationState.time不為起點。
4.WrapMode.PingPong:
當動畫時間軸到達Animation Clip的終點時,時間軸會在往起點的方向前進。這個動畫效果會使物件重複的在Animation Clip的起點與終點之間來回的播放動畫。對於需要來回反複播放的動畫而言,就可以設定成此狀態。
5.WrapMode.ClampForever:
當動畫時間軸到達Animation Clip的終點時,時間軸將會停止在Animaiton Clip的終點,且動畫播放狀態依然是播放中,也就是Animation不會停止Animation Clip的動畫播放。而如果設定為反向播放時,時間軸到達起點時,也一樣會停止在起點,且Animaiton Clip也是在播放中的狀態。也因此,此設定會使Animation Clip只播放一次。
根據官方文件的說法,這個設定可以用在播放時間軸到達終點後不打算結束的Additive Animation上。根據測試的結果為,動畫物件是會停在時間軸的結束狀態下,但AnimationStates[].time還是會持續的增加或是減少(依據設定的播放時間值)。
在Animation以及Animation Clip上都有WrapMode的屬性,而透過Script去設定時,卻有些許的不同。對於wrapMode這個屬性,在Animation本身上,是可以在播放中就去設定,而且會立即生效;但是當Animation Clip正在播放中的時後,AnimationClip.wrapMode是不能被變更的(唯讀狀態)。
以下為操作測試:
I.在Script內去變更Animation.wrapMode時,WrapMode會立即的套用在Animation Clip的播放上(如果是透過Inspector來變更,則WrapMode不會立即的套用在Animation Clip的播放上),但Animation Clip.warpMode還是保持原本的設定。
例如:Animation.wrapMode原本設定為WrapMode.Once,Animation Clip.wrapMode也設定為WrapMode.Once。在Animation.Play()之後,且Animation Clip播放完畢之前,將 Animation.wrapMode改為WrapMode.PingPong。則此時看到的動畫效果就變成來回播放,但是Animation Clip.wrapMode還是依舊為WrapMode.Once。
II.在Script內去變更Animation Clip.wrapMode時,WrapMode會立即套用到Animation Clip.wrapMode,但是並不會影響到正在播放的Animation。
例如:Animation.wrapMode原本設定為WrapMode.Once,Animation Clip.wrapMode也設定為WrapMode.Once。在Animation.Play()之後,且Animation Clip播放完畢之前,將 Animation.wrapMode改為WrapMode.PingPong。則此時看到的動畫還是播完後就停止了,但此時又再重新播放動畫的話,動畫效果還是一樣只播一次。不過在Animation Clip.wrapMode的設定上,是有被變更為WrapMode.PingPong。
例外原因:
會出現上面的狀況是因為Animation是透過AnimationState來控制動畫的播放。根據目前的測試,在編輯模式下,AnimationStates是一個空的陣列(圖1.)。當啟用Play模式時,Animation會把在Animations內所指定的Animation Clip的name以及wrapMode新增到AnimationStates內(圖2.)(Animation Clip的設定請參考圖3.)。由這邊看出Unity看起來是在Animation初始化的時候取得AnimationClip.wrapMode,並加到AnimationState內。
在上述的狀況下,變更Animation Clip.wrapMode(圖4.),此時卻發現一開始加到AnimationStates的wrapMode卻沒有變更。所以由此推測,這邊的wrapMode是從AnimationClip.wrapMode複製來的,而不是取得參考。這也可以指出,為什麼在Animation沒有重新取得AnimationClip時,播放的結果總是不同於設定的值。所以之後再怎麼變更AnimacionClip.wrapMode,Animatoin也不可能知到目前指定的AnimationClip已經有任何的變化。
圖4.變更AnimationClip.wrapMode 圖5.[圖4.]狀態下的Animation資訊
解決方案:
i.在使用Unity Editor的模式下,僅需再重新Play Game Mode,就可以使用到變更後的WrapMode。
ii.在使用編譯後的執行檔時,有三種方法可以使用變更後的WrapMode:
1.重新載入場景。
2.刪除目前GameObject所持有的Animation元件,並再重新加入Animation元件與Animation Clip
後。如要用這方法,則需在刪除Animation後的下一個Frame才可以再新增Animation元件,
不然Unity會跳出物件還存在且不可重複加入的錯誤訊息。原因是Object.Destroy()所說的
「物件的刪除總是在Update loop結束之後以及rendering之前發生」。
3.直接將新的Animation Clip.wrapMode指定給Animation[Animation Clip.name].wrapMode。
結論:
1.在Inspector修改Animation.wrapMode並不會立刻套用到目前的播放上。(AnimaitonStates不會被立即變更)
2.透過Script修改Animation.wrapMode會立即套用到所有的AnimationClip(包含目前的播放)在Animation Component內的wrapMode上。(AnimationStates會被立即變更)
3.變更過的AnimationClip.wrapMode需要Animation Component進行重載後,才會更新到AnimaitonStates。
4.播放中的Animation Clip是不能進行wrapMode的變更。
Unity版本:3.5.6f4
在Unity內Animation的WrapMode可以透過Script來變更。以下針對各個參數進行說明:
1.WrapMode.Default:
直接拿Amination Clip內設定的wrapMode來進行動畫播放。預設的wrapMode為WrapMode.Once。
2.WrapMode.Once:
當動畫時間軸到達Animation Clip終點時,正在播放中的Animation Clip會被自動的停止播放,並且時間軸會被重設回Animation Clip的一開始。
不過當Animation Clip是從終點反向播放到起點時,雖然在播放到起點時會也會被自動停止,但是時間軸並不會被重置回終點,而是留在起點。
3.WrapMode.Loop:
當動畫時間軸到達Animation Clip的終點時,時間軸會又回到起點的位置,並且繼續播放動畫。如果將播放模式設為反向時(即將Animation[ClipName].speed設為負值),則會從反向播放動畫,而播放的起點與終點都會跟正向播放時相反。
Note:根據官方的說法,將AnimationState.speed設為負值時,Animation Clip就會被反向播放(A negative playback speed will play the animation backwards.)。
Note(2012/11/20):
今找到原因了,原先測試時,只有變更AnimationState.speed,而沒有去變更AnimationState.time。所以播放時,時間軸就已經在0的位置了,也因此看不到動畫做動。如要反向播放動畫則需變更AnimationState.Speed為負值以及設定AnimationState.time不為起點。
4.WrapMode.PingPong:
當動畫時間軸到達Animation Clip的終點時,時間軸會在往起點的方向前進。這個動畫效果會使物件重複的在Animation Clip的起點與終點之間來回的播放動畫。對於需要來回反複播放的動畫而言,就可以設定成此狀態。
5.WrapMode.ClampForever:
當動畫時間軸到達Animation Clip的終點時,時間軸將會停止在Animaiton Clip的終點,且動畫播放狀態依然是播放中,也就是Animation不會停止Animation Clip的動畫播放。而如果設定為反向播放時,時間軸到達起點時,也一樣會停止在起點,且Animaiton Clip也是在播放中的狀態。也因此,此設定會使Animation Clip只播放一次。
根據官方文件的說法,這個設定可以用在播放時間軸到達終點後不打算結束的Additive Animation上。根據測試的結果為,動畫物件是會停在時間軸的結束狀態下,但AnimationStates[].time還是會持續的增加或是減少(依據設定的播放時間值)。
在Animation以及Animation Clip上都有WrapMode的屬性,而透過Script去設定時,卻有些許的不同。對於wrapMode這個屬性,在Animation本身上,是可以在播放中就去設定,而且會立即生效;但是當Animation Clip正在播放中的時後,AnimationClip.wrapMode是不能被變更的(唯讀狀態)。
以下為操作測試:
I.在Script內去變更Animation.wrapMode時,WrapMode會立即的套用在Animation Clip的播放上(如果是透過Inspector來變更,則WrapMode不會立即的套用在Animation Clip的播放上),但Animation Clip.warpMode還是保持原本的設定。
例如:Animation.wrapMode原本設定為WrapMode.Once,Animation Clip.wrapMode也設定為WrapMode.Once。在Animation.Play()之後,且Animation Clip播放完畢之前,將 Animation.wrapMode改為WrapMode.PingPong。則此時看到的動畫效果就變成來回播放,但是Animation Clip.wrapMode還是依舊為WrapMode.Once。
II.在Script內去變更Animation Clip.wrapMode時,WrapMode會立即套用到Animation Clip.wrapMode,但是並不會影響到正在播放的Animation。
例如:Animation.wrapMode原本設定為WrapMode.Once,Animation Clip.wrapMode也設定為WrapMode.Once。在Animation.Play()之後,且Animation Clip播放完畢之前,將 Animation.wrapMode改為WrapMode.PingPong。則此時看到的動畫還是播完後就停止了,但此時又再重新播放動畫的話,動畫效果還是一樣只播一次。不過在Animation Clip.wrapMode的設定上,是有被變更為WrapMode.PingPong。
例外原因:
會出現上面的狀況是因為Animation是透過AnimationState來控制動畫的播放。根據目前的測試,在編輯模式下,AnimationStates是一個空的陣列(圖1.)。當啟用Play模式時,Animation會把在Animations內所指定的Animation Clip的name以及wrapMode新增到AnimationStates內(圖2.)(Animation Clip的設定請參考圖3.)。由這邊看出Unity看起來是在Animation初始化的時候取得AnimationClip.wrapMode,並加到AnimationState內。
圖1.編輯模式下的Animation States
圖2.Play模式下的Animation States
圖3.AnimationClip的設定
在上述的狀況下,變更Animation Clip.wrapMode(圖4.),此時卻發現一開始加到AnimationStates的wrapMode卻沒有變更。所以由此推測,這邊的wrapMode是從AnimationClip.wrapMode複製來的,而不是取得參考。這也可以指出,為什麼在Animation沒有重新取得AnimationClip時,播放的結果總是不同於設定的值。所以之後再怎麼變更AnimacionClip.wrapMode,Animatoin也不可能知到目前指定的AnimationClip已經有任何的變化。
圖4.變更AnimationClip.wrapMode 圖5.[圖4.]狀態下的Animation資訊
解決方案:
i.在使用Unity Editor的模式下,僅需再重新Play Game Mode,就可以使用到變更後的WrapMode。
ii.在使用編譯後的執行檔時,有三種方法可以使用變更後的WrapMode:
1.重新載入場景。
2.刪除目前GameObject所持有的Animation元件,並再重新加入Animation元件與Animation Clip
後。如要用這方法,則需在刪除Animation後的下一個Frame才可以再新增Animation元件,
不然Unity會跳出物件還存在且不可重複加入的錯誤訊息。原因是Object.Destroy()所說的
「物件的刪除總是在Update loop結束之後以及rendering之前發生」。
3.直接將新的Animation Clip.wrapMode指定給Animation[Animation Clip.name].wrapMode。
結論:
1.在Inspector修改Animation.wrapMode並不會立刻套用到目前的播放上。(AnimaitonStates不會被立即變更)
2.透過Script修改Animation.wrapMode會立即套用到所有的AnimationClip(包含目前的播放)在Animation Component內的wrapMode上。(AnimationStates會被立即變更)
3.變更過的AnimationClip.wrapMode需要Animation Component進行重載後,才會更新到AnimaitonStates。
4.播放中的Animation Clip是不能進行wrapMode的變更。
[Unity]Animation Component - Attributes
參考資料:Scripting > Runtime Classes > Animation
跟據官方的說法,這個元件是用來做動畫播放使用。而整個動畫系統是利用「權重」的方式來進行動畫的播放。相關內容可以參考Unity Manual > Animation Scripting。底下針對Animation所提供的屬性來進行說明。
1.clip:(Animation Clip)
在沒有指定播放的clip時進行播放時,所會播放的Animation clip。即在Script內呼叫Animation.Play()時,Animation Component就會播放此組clip。在Inspector底下所看到的屬性如圖.1的紅框框選處。
2.playAutomatically:(bool)
這個屬性是用來決定在GameObject啟動(Active)時,是否要播放預設的Animation Clip。也就是此值為true時,Animation System則會在GameObject設為啟動(Active)之後,自動播放Animation.clip的動畫內容。在Inspector底下所看到的屬性如圖.1的綠框框選處。
3.wrapMode:(WrapMode)
此屬性是用來決定當Animation Clip播放完畢時,接下來要做何種處理。可以參考[Unity]Animation WarpMode。
4.isPlaying:(bool)
此屬性可用來判斷Animation Clip是否已經被播放完畢。當此屬性為true時,即是指定的Animation Clip還在播放中;反之為false時,則代表指定的Animation Clip已經停止播放了。
5.this[string name]:(AnimationState)
此Indexer可以透過Animation Clip的名稱來取得其所用到的AnimationState。因此如有需要修改AnimationState的屬性時,就可以使用此屬性。說明測試也可以參考[Unity]AnimationState。
6.animatePhysics:(bool)
這個屬性是用來設定Animation播放時,會不會受到物理引擎的影響。當此屬性設為true時,Animation Clip播放時,就會被加到物理引擎內進行計算。但如要使此設定有效時,還必需先在要播放Animation Clip的GameObject上加上RigidBody,並設定成會受物理引擎影響。在Inspector底下所看到的屬性如圖1.的黃框框選處。
Note:目前測試在播放水平移動的動畫時,再加上重力影響時,高度座標的的確是有所改變。
但其變化量比無播放動畫時的狀況還要來的小很多。
7.cullingType:(AnimationCullingType)
跟據官的說法,當culling被起動時(也就是設定不是AnimationCullingType.AlwaysAnimate),Unity會在animation不會被使用者看到時,自動的停止AnimatoinClip的播放。因此這個設定是用來節省效能消耗。當動畫元件被culled的時候,AnimatoinState、Event或是Sample Animation(可以參考animation.sample() usage)都不會有做用。在Inspector底下所看到的屬性如圖1.的紫框框選處。(不過目前測試沒有成功的試出來。)
8.localBounds:(Bounds)
此屬性為Animation的動畫元件(animation component)在區域座標(local space)下的Axis-aligned minimum bounding box(AABB)。跟據官方的說法,此屬性在預設的條件下,是跟據動畫狀態(animation state,也就是所附加的Animation Clip)來計算的。而使用者也可以透過重新指定數值來變更目前的localBounds。
如有要數值更改回原設定值,就僅需將Animation.cullingType設定為AnimationCullingType.BasedOnClipBounds即可。在Animation.cullingType沒有設定為AnimationCullingType.BasedOnClipBounds或是AnimationCullingType.BasedonUse的時候,此屬性是沒有被定義的。然而當Animation.localBounds被設定時,系統就會自動將Animation.cullingType設定為AnimationCullingType.BasedOnUserBounds。
跟據官方的說法,這個元件是用來做動畫播放使用。而整個動畫系統是利用「權重」的方式來進行動畫的播放。相關內容可以參考Unity Manual > Animation Scripting。底下針對Animation所提供的屬性來進行說明。
1.clip:(Animation Clip)
在沒有指定播放的clip時進行播放時,所會播放的Animation clip。即在Script內呼叫Animation.Play()時,Animation Component就會播放此組clip。在Inspector底下所看到的屬性如圖.1的紅框框選處。
圖1.Animation設定介面
2.playAutomatically:(bool)
這個屬性是用來決定在GameObject啟動(Active)時,是否要播放預設的Animation Clip。也就是此值為true時,Animation System則會在GameObject設為啟動(Active)之後,自動播放Animation.clip的動畫內容。在Inspector底下所看到的屬性如圖.1的綠框框選處。
3.wrapMode:(WrapMode)
此屬性是用來決定當Animation Clip播放完畢時,接下來要做何種處理。可以參考[Unity]Animation WarpMode。
4.isPlaying:(bool)
此屬性可用來判斷Animation Clip是否已經被播放完畢。當此屬性為true時,即是指定的Animation Clip還在播放中;反之為false時,則代表指定的Animation Clip已經停止播放了。
5.this[string name]:(AnimationState)
此Indexer可以透過Animation Clip的名稱來取得其所用到的AnimationState。因此如有需要修改AnimationState的屬性時,就可以使用此屬性。說明測試也可以參考[Unity]AnimationState。
6.animatePhysics:(bool)
這個屬性是用來設定Animation播放時,會不會受到物理引擎的影響。當此屬性設為true時,Animation Clip播放時,就會被加到物理引擎內進行計算。但如要使此設定有效時,還必需先在要播放Animation Clip的GameObject上加上RigidBody,並設定成會受物理引擎影響。在Inspector底下所看到的屬性如圖1.的黃框框選處。
Note:目前測試在播放水平移動的動畫時,再加上重力影響時,高度座標的的確是有所改變。
但其變化量比無播放動畫時的狀況還要來的小很多。
7.cullingType:(AnimationCullingType)
跟據官的說法,當culling被起動時(也就是設定不是AnimationCullingType.AlwaysAnimate),Unity會在animation不會被使用者看到時,自動的停止AnimatoinClip的播放。因此這個設定是用來節省效能消耗。當動畫元件被culled的時候,AnimatoinState、Event或是Sample Animation(可以參考animation.sample() usage)都不會有做用。在Inspector底下所看到的屬性如圖1.的紫框框選處。(不過目前測試沒有成功的試出來。)
8.localBounds:(Bounds)
此屬性為Animation的動畫元件(animation component)在區域座標(local space)下的Axis-aligned minimum bounding box(AABB)。跟據官方的說法,此屬性在預設的條件下,是跟據動畫狀態(animation state,也就是所附加的Animation Clip)來計算的。而使用者也可以透過重新指定數值來變更目前的localBounds。
如有要數值更改回原設定值,就僅需將Animation.cullingType設定為AnimationCullingType.BasedOnClipBounds即可。在Animation.cullingType沒有設定為AnimationCullingType.BasedOnClipBounds或是AnimationCullingType.BasedonUse的時候,此屬性是沒有被定義的。然而當Animation.localBounds被設定時,系統就會自動將Animation.cullingType設定為AnimationCullingType.BasedOnUserBounds。
Subscribe to:
Posts (Atom)
Build docker image from multiple build contexts
Build docker image from multiple build contexts ...
-
參考資料: Input Input Manager 測試手把 :PS Analog gamepad Script語言:C# Unity 版本:3.4 Unity提供了3種輸入裝置可以使用,鍵盤、滑鼠、以及遊戲手把。 ...
-
寫法很簡單,就像下列寫法: if ( *szStr ) { .... } 因為*szStr == szStr[0],且char[]是以NULL-Terminate來判定字串是否結束,所以只要判定陣列的第一個值是不是為零,就可知道是否為空字串。 如需檢查是否為空字...