實現效果
核心功能
- 支持選定模型(帶Animator)在非運行模式下,播放/暫停/中止動做。
- 支持動做單幀前進,單幀回退(幀時間默認0.05f,能夠代碼設置)。
- 支持滾動條拖拽,將動做調整到指定時間。
- 支持調整播放速度。
其餘功能
- 支持循環播放。
- 支持選中Animator下的任一動做。
- 編輯器關閉時,會刪除中間產生的臨時GameObject
- 選中Project中的Prefab,若是符合條件,將會本身建立一份Clone到Hierarchy中。
效果圖

實現原理
總體思路
- 獲取指定GameObject上的Animator,並記錄其全部的AniamtionClip。
- 模擬播放時間,經過AnimationMode.SampleAnimationClip方法設置播放位置。
- 添加進度條,單幀執行等方式修改播放時間。
注意細節
- 若是模型勾選了OptimizeGameObject選項,優化骨骼,那麼動做可能會由於找不到骨骼而沒法播放。須要使用AnimatorUtility.DeoptimizeTransformHierarchy方法,暫時屏蔽骨骼優化。
- 在使用AnimationMode.SampleAnimationClip方法時,參數的GameObject應該設置爲Animator所對應的GameObject而不是根節點。
- 由於不是運行狀態,因此Update須要由EditorApplication.update提供。(工具關閉時,須要反註冊)
- OnGUI方法不是每幀都執行,當使用滾動條( Slider )和進度條(ProgressBar)時,顯示不會及時更新,因此當數據更新時,須要調用Repaint方法,強制刷新UI。
- EditorWindow下,OnSelectionChange方法能夠用來監聽選擇變化。可是在這個方法內部,修改當前選中的對象(Selection的屬性)無效。
- ProgressBar不能使用Layout,須要本身設置Position。在Layout中獲取上一個Rect的位置,而後計算ProcessBar的位置,實現方式:
if(Event.current.type == EventType.Repaint)
{
var lastRect = GUILayoutUtility.GetLastRect();
EditorGUI.ProgressBar(new Rect(lastRect.x, lastRect.y + lastRect.height, lastRect.width, 20), animationCtrl.escapeTime / animationCtrl.length, "");
}
存在疑問
- AnimationMode文檔中說在使用 SampleAnimationClip時須要 StartAnimationMode,但沒有調用,也是能夠正常運行。BeginSampling,EndSampling做用什麼?不加也能夠正常運行。
- 在使用AnimatorUtility.OptimizeTransformHierarchy去還原模型時,須要知道exposedTransforms即須要保留的骨骼。可是沒有找到獲取exposedTransforms的方法,因此GameObject在被DeoptimizeTransformHierarchy以後沒法還原。一種的思路是在調用DeoptimizeTransformHierarchy以前記錄子Transform,而且去掉包含SkinnedMeshRender的Transform,使用這些Transform來當作exposedTransforms。可是這種方式不精確,對模型有限制。
ToDo
- 倒播。修改時間變化方式,添加符號判斷。
- ParticleSystem.Simulate能夠在非運行模式下制定特效播放到制定時間,能夠用這個方法實現一套特效的播放回退機制。(特效比較複雜可能包含多個ParticleSystem,也可能包含動畫)
- 結合動做和特效,實現特效與模型動做的匹配,指定特效延時時間,而且能夠同時處理多個特效。(相似技能編輯器的表現)
源碼下載html
轉載請註明出處:http://www.cnblogs.com/chiguozi/p/6862571.html編輯器