FAnimationEventEditor.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  1. using UnityEngine;
  2. using UnityEditor.Animations;
  3. using UnityEditor;
  4. //using UnityEditorInternal;
  5. using System;
  6. using System.Collections.Generic;
  7. using Flux;
  8. namespace FluxEditor
  9. {
  10. [FEditor( typeof( FPlayAnimationEvent ) )]
  11. public class FAnimationEventEditor : FEventEditor
  12. {
  13. // [SerializeField]
  14. protected FPlayAnimationEvent AnimEvt { get { return (FPlayAnimationEvent)Obj; } }
  15. // [SerializeField]
  16. protected FAnimationTrack AnimTrack { get { return (FAnimationTrack)Owner.Obj; } }
  17. protected AnimatorState _animState;
  18. protected AnimatorStateTransition _transitionToState;
  19. private SerializedObject _animEvtSO;
  20. private SerializedProperty _blendLength;
  21. private SerializedProperty _startOffset;
  22. private SerializedObject _transitionSO;
  23. private SerializedProperty _transitionExitTime;
  24. private SerializedProperty _transitionDuration;
  25. private SerializedProperty _transitionOffset;
  26. private static int _mouseDown = int.MinValue;
  27. // private UndoPropertyModification[] UndoProperties( UndoPropertyModification[] modifications )
  28. // {
  29. // Debug.Log ("UndoProperties");
  30. // foreach( UndoPropertyModification modification in modifications )
  31. // {
  32. // Debug.Log ( "obj ref: " + modification.propertyModification.objectReference + "; path: " + modification.propertyModification.propertyPath + " target:" + modification.propertyModification.target + "; value:" + modification.propertyModification.value );
  33. // }
  34. // return modifications;
  35. // }
  36. public override void OnDelete()
  37. {
  38. FAnimationEventInspector.CheckDeleteAnimation( AnimEvt );
  39. }
  40. private void UpdateEventFromController()
  41. {
  42. bool isBlending = AnimEvt.IsBlending();
  43. if( isBlending )
  44. {
  45. if( _transitionToState == null )
  46. {
  47. _transitionToState = FAnimationTrackInspector.GetTransitionTo( AnimEvt );
  48. if( _transitionToState == null || _transitionToState.conditions.Length > 0 )
  49. {
  50. FAnimationTrackInspector.RebuildStateMachine( (FAnimationTrack)TrackEditor.Track );
  51. _transitionToState = FAnimationTrackInspector.GetTransitionTo( AnimEvt );
  52. }
  53. }
  54. if( _transitionSO == null )
  55. {
  56. if( _transitionToState != null )
  57. {
  58. _transitionSO = new SerializedObject( _transitionToState );
  59. _transitionExitTime = _transitionSO.FindProperty( "m_ExitTime" );
  60. _transitionDuration = _transitionSO.FindProperty( "m_TransitionDuration" );
  61. _transitionOffset = _transitionSO.FindProperty( "m_TransitionOffset" );
  62. }
  63. }
  64. else if( _transitionSO.targetObject == null )
  65. {
  66. _transitionExitTime = null;
  67. _transitionDuration = null;
  68. _transitionOffset = null;
  69. _transitionSO = null;
  70. }
  71. }
  72. else
  73. {
  74. if( _transitionToState != null || _transitionSO != null )
  75. {
  76. _transitionToState = null;
  77. _transitionSO = null;
  78. _transitionExitTime = null;
  79. _transitionOffset = null;
  80. _transitionDuration = null;
  81. }
  82. }
  83. if( _transitionSO != null )
  84. {
  85. _transitionSO.Update();
  86. _animEvtSO.Update();
  87. FPlayAnimationEvent prevAnimEvt = (FPlayAnimationEvent)AnimTrack.Events[AnimEvt.GetId() - 1];
  88. AnimationClip prevAnimEvtClip = prevAnimEvt._animationClip;
  89. if( prevAnimEvtClip != null )
  90. {
  91. float exitTimeNormalized = (prevAnimEvt.Length + prevAnimEvt._startOffset) / (prevAnimEvtClip.frameRate * prevAnimEvtClip.length);
  92. if( !Mathf.Approximately( exitTimeNormalized, _transitionExitTime.floatValue ) )
  93. {
  94. _transitionExitTime.floatValue = exitTimeNormalized;
  95. }
  96. float blendNormalized = (_blendLength.intValue / prevAnimEvtClip.frameRate) / prevAnimEvtClip.length;
  97. if( !Mathf.Approximately( blendNormalized, _transitionDuration.floatValue ) )
  98. {
  99. _blendLength.intValue = Mathf.Clamp( Mathf.RoundToInt( _transitionDuration.floatValue * prevAnimEvtClip.length * prevAnimEvtClip.frameRate ), 0, AnimEvt.Length);
  100. _transitionDuration.floatValue = (_blendLength.intValue / prevAnimEvtClip.frameRate) / prevAnimEvtClip.length;
  101. _animEvtSO.ApplyModifiedProperties();
  102. }
  103. float startOffsetNorm = (_startOffset.intValue / AnimEvt._animationClip.frameRate) / AnimEvt._animationClip.length;
  104. if( !Mathf.Approximately( startOffsetNorm, _transitionOffset.floatValue ) )
  105. {
  106. _startOffset.intValue = Mathf.RoundToInt( _transitionOffset.floatValue * AnimEvt._animationClip.length * AnimEvt._animationClip.frameRate );
  107. _transitionOffset.floatValue = (_startOffset.intValue / AnimEvt._animationClip.frameRate) / AnimEvt._animationClip.length;
  108. _animEvtSO.ApplyModifiedProperties();
  109. }
  110. }
  111. _transitionSO.ApplyModifiedProperties();
  112. }
  113. }
  114. protected override void RenderEvent( FrameRange viewRange, FrameRange validKeyframeRange )
  115. {
  116. if( _animEvtSO == null )
  117. {
  118. _animEvtSO = new SerializedObject( AnimEvt );
  119. _blendLength = _animEvtSO.FindProperty( "_blendLength" );
  120. _startOffset = _animEvtSO.FindProperty( "_startOffset" );
  121. }
  122. UpdateEventFromController();
  123. _animEvtSO.Update();
  124. FAnimationTrackEditor animTrackEditor = (FAnimationTrackEditor)TrackEditor;
  125. Rect transitionOffsetRect = _eventRect;
  126. int startOffsetHandleId = EditorGUIUtility.GetControlID( FocusType.Passive );
  127. int transitionHandleId = EditorGUIUtility.GetControlID( FocusType.Passive );
  128. bool isBlending = AnimEvt.IsBlending();
  129. bool isAnimEditable = Flux.FUtility.IsAnimationEditable(AnimEvt._animationClip);
  130. if( isBlending )
  131. {
  132. transitionOffsetRect.xMin = Rect.xMin + SequenceEditor.GetXForFrame( AnimEvt.Start + AnimEvt._blendLength ) - 3;
  133. transitionOffsetRect.width = 6;
  134. transitionOffsetRect.yMin = transitionOffsetRect.yMax - 8;
  135. }
  136. switch( Event.current.type )
  137. {
  138. case EventType.MouseDown:
  139. if( EditorGUIUtility.hotControl == 0 && Event.current.alt && !isAnimEditable )
  140. {
  141. if( isBlending && transitionOffsetRect.Contains( Event.current.mousePosition ) )
  142. {
  143. EditorGUIUtility.hotControl = transitionHandleId;
  144. AnimatorWindowProxy.OpenAnimatorWindowWithAnimatorController( (AnimatorController)AnimTrack.AnimatorController );
  145. if( Selection.activeObject != _transitionToState )
  146. Selection.activeObject = _transitionToState;
  147. Event.current.Use();
  148. }
  149. else if( _eventRect.Contains( Event.current.mousePosition ) )
  150. {
  151. _mouseDown = SequenceEditor.GetFrameForX( Event.current.mousePosition.x ) - AnimEvt.Start;
  152. EditorGUIUtility.hotControl = startOffsetHandleId;
  153. Event.current.Use();
  154. }
  155. }
  156. break;
  157. case EventType.Ignore:
  158. case EventType.MouseUp:
  159. if( EditorGUIUtility.hotControl == transitionHandleId
  160. || EditorGUIUtility.hotControl == startOffsetHandleId )
  161. {
  162. EditorGUIUtility.hotControl = 0;
  163. Event.current.Use();
  164. }
  165. break;
  166. case EventType.MouseDrag:
  167. if( EditorGUIUtility.hotControl == transitionHandleId )
  168. {
  169. int mouseDragPos = Mathf.Clamp( SequenceEditor.GetFrameForX( Event.current.mousePosition.x - Rect.x ) - AnimEvt.Start, 0, AnimEvt.Length );
  170. if( _blendLength.intValue != mouseDragPos )
  171. {
  172. _blendLength.intValue = mouseDragPos;
  173. FPlayAnimationEvent prevAnimEvt = (FPlayAnimationEvent)animTrackEditor.Track.GetEvent( AnimEvt.GetId()-1 );
  174. if( _transitionDuration != null )
  175. _transitionDuration.floatValue = (_blendLength.intValue / prevAnimEvt._animationClip.frameRate) / prevAnimEvt._animationClip.length;
  176. Undo.RecordObject( this, "Animation Blending" );
  177. }
  178. Event.current.Use();
  179. }
  180. else if( EditorGUIUtility.hotControl == startOffsetHandleId )
  181. {
  182. int mouseDragPos = Mathf.Clamp( SequenceEditor.GetFrameForX( Event.current.mousePosition.x - Rect.x ) - AnimEvt.Start, 0, AnimEvt.Length );
  183. int delta = _mouseDown - mouseDragPos;
  184. _mouseDown = mouseDragPos;
  185. _startOffset.intValue = Mathf.Clamp( _startOffset.intValue + delta, 0, AnimEvt._animationClip.isLooping ? AnimEvt.Length : Mathf.RoundToInt( AnimEvt._animationClip.length * AnimEvt._animationClip.frameRate ) - AnimEvt.Length );
  186. if( _transitionOffset != null )
  187. _transitionOffset.floatValue = (_startOffset.intValue / AnimEvt._animationClip.frameRate) / AnimEvt._animationClip.length;
  188. Undo.RecordObject( this, "Animation Offset" );
  189. Event.current.Use();
  190. }
  191. break;
  192. }
  193. _animEvtSO.ApplyModifiedProperties();
  194. if( _transitionSO != null )
  195. _transitionSO.ApplyModifiedProperties();
  196. switch( Event.current.type )
  197. {
  198. case EventType.DragUpdated:
  199. if( _eventRect.Contains( Event.current.mousePosition ) )
  200. {
  201. int numAnimationsDragged = FAnimationEventInspector.NumAnimationsDragAndDrop( Evt.Sequence.FrameRate );
  202. DragAndDrop.visualMode = numAnimationsDragged > 0 ? DragAndDropVisualMode.Link : DragAndDropVisualMode.Rejected;
  203. Event.current.Use();
  204. }
  205. break;
  206. case EventType.DragPerform:
  207. if( _eventRect.Contains( Event.current.mousePosition ) )
  208. {
  209. AnimationClip animationClipDragged = FAnimationEventInspector.GetAnimationClipDragAndDrop( Evt.Sequence.FrameRate );
  210. if( animationClipDragged )
  211. {
  212. int animFrameLength = Mathf.RoundToInt(animationClipDragged.length * animationClipDragged.frameRate);
  213. FAnimationEventInspector.SetAnimationClip( AnimEvt, animationClipDragged );
  214. FrameRange maxRange = AnimEvt.GetMaxFrameRange();
  215. SequenceEditor.MoveEvent( AnimEvt, new FrameRange( AnimEvt.Start, Mathf.Min( AnimEvt.Start+animFrameLength, maxRange.End ) ) );
  216. DragAndDrop.AcceptDrag();
  217. Event.current.Use();
  218. }
  219. else
  220. {
  221. Event.current.Use();
  222. }
  223. }
  224. break;
  225. }
  226. // FrameRange currentRange = Evt.FrameRange;
  227. base.RenderEvent( viewRange, validKeyframeRange );
  228. // if( isAnimEditable && currentRange.Length != Evt.FrameRange.Length )
  229. // {
  230. // FAnimationEventInspector.ScaleAnimationClip( AnimEvt._animationClip, Evt.FrameRange );
  231. // }
  232. if( Event.current.type == EventType.Repaint )
  233. {
  234. if( isBlending && !isAnimEditable && viewRange.Contains( AnimEvt.Start+AnimEvt._blendLength ) )
  235. {
  236. GUISkin skin = FUtility.GetFluxSkin();
  237. GUIStyle transitionOffsetStyle = skin.GetStyle( "BlendOffset" );
  238. Texture2D t = FUtility.GetFluxTexture( "EventBlend.png" );
  239. Rect r = new Rect( _eventRect.xMin, _eventRect.yMin+1, transitionOffsetRect.center.x - _eventRect.xMin, _eventRect.height-2 );
  240. Color guiColor = GUI.color;
  241. Color c = new Color(1f, 1f, 1f, 0.3f);
  242. c.a *= guiColor.a;
  243. GUI.color = c;
  244. GUI.DrawTexture( r, t );
  245. if( Event.current.alt )
  246. GUI.color = Color.white;
  247. transitionOffsetStyle.Draw( transitionOffsetRect, false, false, false, false );
  248. GUI.color = guiColor;
  249. }
  250. if( EditorGUIUtility.hotControl == transitionHandleId )
  251. {
  252. Rect transitionOffsetTextRect = transitionOffsetRect;
  253. transitionOffsetTextRect.y -= 16;
  254. transitionOffsetTextRect.height = 20;
  255. transitionOffsetTextRect.width += 50;
  256. GUI.Label( transitionOffsetTextRect, AnimEvt._blendLength.ToString(), EditorStyles.label );
  257. }
  258. if( EditorGUIUtility.hotControl == startOffsetHandleId )
  259. {
  260. Rect startOffsetTextRect = _eventRect;
  261. GUI.Label( startOffsetTextRect, AnimEvt._startOffset.ToString(), EditorStyles.label );
  262. }
  263. }
  264. }
  265. public override void OnEventFinishedMoving( FrameRange oldFrameRange )
  266. {
  267. if( AnimEvt.ControlsAnimation && oldFrameRange.Length != AnimEvt.FrameRange.Length && Flux.FUtility.IsAnimationEditable(AnimEvt._animationClip) )
  268. {
  269. FAnimationEventInspector.ScaleAnimationClip( AnimEvt._animationClip, AnimEvt.FrameRange );
  270. }
  271. }
  272. private TransformCurves _transformCurves = null;
  273. public void CreateTransformCurves()
  274. {
  275. if( _transformCurves == null )
  276. {
  277. _transformCurves = new TransformCurves( AnimEvt.Owner, AnimEvt._animationClip );
  278. }
  279. }
  280. public void RenderTransformCurves( int samplesPerSecond )
  281. {
  282. if( _transformCurves == null || _transformCurves.clip == null )
  283. CreateTransformCurves();
  284. else
  285. _transformCurves.RefreshCurves();
  286. float totalTime = AnimEvt.LengthTime;
  287. float timePerSample = totalTime / samplesPerSecond;
  288. int numSamples = Mathf.RoundToInt( totalTime / timePerSample ) + 1;
  289. Vector3[] pts = new Vector3[numSamples];
  290. float t = 0;
  291. for( int i = 0; i < numSamples; ++i )
  292. {
  293. pts[i] = _transformCurves.GetWorldPosition( t );
  294. t += timePerSample;
  295. }
  296. Handles.DrawPolyLine( pts );
  297. FAnimationTrackEditor animTrackEditor = (FAnimationTrackEditor)TrackEditor;
  298. if( animTrackEditor.ShowKeyframes || animTrackEditor.ShowKeyframeTimes )
  299. {
  300. int animFramerate = Mathf.RoundToInt( _transformCurves.clip.frameRate );
  301. Keyframe[] keyframes = _transformCurves.GetPositionKeyframes();
  302. for( int i = 0; i != keyframes.Length; ++i )
  303. {
  304. Keyframe keyframe = keyframes[i];
  305. Vector3 pos = _transformCurves.GetPosition( keyframe.time );
  306. Quaternion rot = _transformCurves.GetRotation( keyframe.time );
  307. Quaternion toolRot = rot;
  308. bool isGlobalRotation = Tools.pivotRotation == PivotRotation.Global;
  309. if( isGlobalRotation )
  310. toolRot = _globalRotation;
  311. if( animTrackEditor.ShowKeyframes )
  312. {
  313. if( Tools.current == Tool.Move )
  314. {
  315. Vector3 newPos = Handles.DoPositionHandle(pos, toolRot );//Handles.PositionHandle( pos, rot );
  316. if( newPos != pos )
  317. {
  318. Undo.RecordObject( _transformCurves.clip, "Change Keyframe" );
  319. _transformCurves.SetPosition( newPos, keyframe.time );
  320. }
  321. }
  322. else if( Tools.current == Tool.Rotate )
  323. {
  324. Quaternion newRot = Handles.DoRotationHandle( toolRot, pos );
  325. if( newRot != toolRot )
  326. {
  327. Undo.RecordObject( _transformCurves.clip, "Change Keyframe" );
  328. _transformCurves.SetRotation( isGlobalRotation ? (newRot*Quaternion.Inverse(toolRot)) * rot : newRot, keyframe.time );
  329. if( isGlobalRotation )
  330. _globalRotation = newRot;
  331. }
  332. }
  333. }
  334. if( Event.current.type == EventType.MouseUp || Event.current.type == EventType.Ignore )
  335. _globalRotation = Quaternion.identity;
  336. if( animTrackEditor.ShowKeyframeTimes )
  337. {
  338. int frame = Mathf.RoundToInt(keyframe.time * animFramerate);
  339. Handles.Label( pos + new Vector3(0, .25f, 0), FUtility.GetTime( AnimEvt.Start+frame, animFramerate) , EditorStyles.toolbarButton );
  340. }
  341. }
  342. }
  343. }
  344. private static Quaternion _globalRotation = Quaternion.identity;
  345. private void RebuildAnimationTrack()
  346. {
  347. FAnimationTrackInspector.RebuildStateMachine( (FAnimationTrack)AnimEvt.Track );
  348. }
  349. }
  350. public class TransformCurves
  351. {
  352. public Transform bone = null;
  353. public AnimationClip clip = null;
  354. public AnimationCurve xPos = null;
  355. public AnimationCurve yPos = null;
  356. public AnimationCurve zPos = null;
  357. public AnimationCurve xRot = null;
  358. public AnimationCurve yRot = null;
  359. public AnimationCurve zRot = null;
  360. public AnimationCurve wRot = null;
  361. public AnimationCurve xScale = null;
  362. public AnimationCurve yScale = null;
  363. public AnimationCurve zScale = null;
  364. public TransformCurves( Transform transform, AnimationClip clip )
  365. {
  366. bone = transform;
  367. this.clip = clip;
  368. RefreshCurves();
  369. }
  370. public void RefreshCurves()
  371. {
  372. EditorCurveBinding[] bindings = AnimationUtility.GetCurveBindings(clip);
  373. foreach (EditorCurveBinding b in bindings)
  374. ParseCurve(b.type, b.propertyName, AnimationUtility.GetEditorCurve(clip, b));
  375. }
  376. private void ParseCurve(Type type, string propertyName, AnimationCurve curve)
  377. {
  378. System.Type transformType = typeof(Transform);
  379. if( type != transformType )
  380. return;
  381. switch( propertyName )
  382. {
  383. case "m_LocalPosition.x":
  384. xPos = curve;
  385. break;
  386. case "m_LocalPosition.y":
  387. yPos = curve;
  388. break;
  389. case "m_LocalPosition.z":
  390. zPos = curve;
  391. break;
  392. case "m_LocalRotation.x":
  393. xRot = curve;
  394. break;
  395. case "m_LocalRotation.y":
  396. yRot = curve;
  397. break;
  398. case "m_LocalRotation.z":
  399. zRot = curve;
  400. break;
  401. case "m_LocalRotation.w":
  402. wRot = curve;
  403. break;
  404. case "m_LocalScale.x":
  405. xScale = curve;
  406. break;
  407. case "m_LocalScale.y":
  408. yScale = curve;
  409. break;
  410. case "m_LocalScale.z":
  411. zScale = curve;
  412. break;
  413. }
  414. }
  415. public Vector3 GetWorldPosition( float t )
  416. {
  417. Vector3 localPos = GetPosition( t );
  418. if( bone.parent == null )
  419. return localPos;
  420. return bone.parent.TransformPoint( localPos );
  421. }
  422. public Vector3 GetPosition( float t )
  423. {
  424. Vector3 pos = Vector3.zero;
  425. if( xPos != null )
  426. pos.x = xPos.Evaluate(t);
  427. if( yPos != null )
  428. pos.y = yPos.Evaluate(t);
  429. if( zPos != null )
  430. pos.z = zPos.Evaluate(t);
  431. return pos;
  432. }
  433. public void SetPosition( Vector3 pos, int keyframeIndex )
  434. {
  435. Keyframe keyframe;
  436. if( xPos != null )
  437. {
  438. keyframe = xPos.keys[keyframeIndex];
  439. keyframe.value = pos.x;
  440. xPos.MoveKey( keyframeIndex, keyframe );
  441. AnimationUtility.SetEditorCurve( clip, EditorCurveBinding.FloatCurve( string.Empty, typeof(Transform), "m_LocalPosition.x"), xPos );
  442. }
  443. if( yPos != null )
  444. {
  445. keyframe = yPos.keys[keyframeIndex];
  446. keyframe.value = pos.y;
  447. yPos.MoveKey( keyframeIndex, keyframe );
  448. AnimationUtility.SetEditorCurve( clip, EditorCurveBinding.FloatCurve( string.Empty, typeof(Transform), "m_LocalPosition.y"), yPos );
  449. }
  450. if( zPos != null )
  451. {
  452. keyframe = zPos.keys[keyframeIndex];
  453. keyframe.value = pos.z;
  454. zPos.MoveKey( keyframeIndex, keyframe );
  455. AnimationUtility.SetEditorCurve( clip, EditorCurveBinding.FloatCurve( string.Empty, typeof(Transform), "m_LocalPosition.z"), zPos );
  456. }
  457. }
  458. public void SetPosition( Vector3 pos, float t )
  459. {
  460. Keyframe keyframe = new Keyframe();
  461. int keyframeIndex = 0;
  462. if( xPos != null )
  463. {
  464. if( TryGetKeyframeAt(xPos, t, ref keyframe, ref keyframeIndex ) )
  465. {
  466. keyframe.value = pos.x;
  467. xPos.MoveKey( keyframeIndex, keyframe );
  468. }
  469. else
  470. {
  471. xPos.AddKey( t, pos.x );
  472. }
  473. AnimationUtility.SetEditorCurve( clip, EditorCurveBinding.FloatCurve( string.Empty, typeof(Transform), "m_LocalPosition.x"), xPos );
  474. }
  475. if( yPos != null )
  476. {
  477. if( TryGetKeyframeAt(yPos, t, ref keyframe, ref keyframeIndex ) )
  478. {
  479. keyframe.value = pos.y;
  480. yPos.MoveKey( keyframeIndex, keyframe );
  481. }
  482. else
  483. {
  484. yPos.AddKey( t, pos.y );
  485. }
  486. AnimationUtility.SetEditorCurve( clip, EditorCurveBinding.FloatCurve( string.Empty, typeof(Transform), "m_LocalPosition.y"), yPos );
  487. }
  488. if( zPos != null )
  489. {
  490. if( TryGetKeyframeAt(zPos, t, ref keyframe, ref keyframeIndex ) )
  491. {
  492. keyframe.value = pos.z;
  493. zPos.MoveKey( keyframeIndex, keyframe );
  494. }
  495. else
  496. {
  497. zPos.AddKey( t, pos.z );
  498. }
  499. AnimationUtility.SetEditorCurve( clip, EditorCurveBinding.FloatCurve( string.Empty, typeof(Transform), "m_LocalPosition.z"), zPos );
  500. }
  501. AnimationWindowProxy.AnimationWindow.Repaint();
  502. }
  503. public void SetRotation( Quaternion rot, float t )
  504. {
  505. Keyframe keyframe = new Keyframe();
  506. int keyframeIndex = 0;
  507. if( xRot != null )
  508. {
  509. if( TryGetKeyframeAt(xRot, t, ref keyframe, ref keyframeIndex ) )
  510. {
  511. keyframe.value = rot.x;
  512. xRot.MoveKey( keyframeIndex, keyframe );
  513. }
  514. else
  515. {
  516. xRot.AddKey( t, rot.x );
  517. }
  518. AnimationUtility.SetEditorCurve( clip, EditorCurveBinding.FloatCurve( string.Empty, typeof(Transform), "m_LocalRotation.x"), xRot );
  519. }
  520. if( yRot != null )
  521. {
  522. if( TryGetKeyframeAt(yRot, t, ref keyframe, ref keyframeIndex ) )
  523. {
  524. keyframe.value = rot.y;
  525. yRot.MoveKey( keyframeIndex, keyframe );
  526. }
  527. else
  528. {
  529. yRot.AddKey( t, rot.y );
  530. }
  531. AnimationUtility.SetEditorCurve( clip, EditorCurveBinding.FloatCurve( string.Empty, typeof(Transform), "m_LocalRotation.y"), yRot );
  532. }
  533. if( zRot != null )
  534. {
  535. if( TryGetKeyframeAt(zRot, t, ref keyframe, ref keyframeIndex ) )
  536. {
  537. keyframe.value = rot.z;
  538. zRot.MoveKey( keyframeIndex, keyframe );
  539. }
  540. else
  541. {
  542. zRot.AddKey( t, rot.z );
  543. }
  544. AnimationUtility.SetEditorCurve( clip, EditorCurveBinding.FloatCurve( string.Empty, typeof(Transform), "m_LocalRotation.z"), zRot );
  545. }
  546. if( wRot != null )
  547. {
  548. if( TryGetKeyframeAt(wRot, t, ref keyframe, ref keyframeIndex ) )
  549. {
  550. keyframe.value = rot.w;
  551. wRot.MoveKey( keyframeIndex, keyframe );
  552. }
  553. else
  554. {
  555. wRot.AddKey( t, rot.w );
  556. }
  557. AnimationUtility.SetEditorCurve( clip, EditorCurveBinding.FloatCurve( string.Empty, typeof(Transform), "m_LocalRotation.w"), wRot );
  558. }
  559. AnimationWindowProxy.AnimationWindow.Repaint();
  560. }
  561. public bool TryGetKeyframeAt( AnimationCurve curve, float t, ref Keyframe keyframe, ref int keyframeIndex )
  562. {
  563. for( int i = 0; i != curve.keys.Length; ++i )
  564. {
  565. if( Mathf.Approximately( t, curve.keys[i].time ) )
  566. {
  567. keyframe = curve.keys[i];
  568. keyframeIndex = i;
  569. return true;
  570. }
  571. }
  572. return false;
  573. }
  574. public Keyframe[] GetPositionKeyframes()
  575. {
  576. Keyframe[] keyframes = xPos != null ? xPos.keys : (yPos != null ? yPos.keys : (zPos != null ? zPos.keys : new Keyframe[0]));
  577. bool addedFrames = false;
  578. if( yPos != null )
  579. {
  580. foreach( Keyframe k in yPos.keys )
  581. {
  582. if( !HasKeyframe( ref keyframes, k.time ) )
  583. {
  584. ArrayUtility.Add<Keyframe>( ref keyframes, k );
  585. addedFrames = true;
  586. }
  587. }
  588. }
  589. if( zPos != null )
  590. {
  591. foreach( Keyframe k in zPos.keys )
  592. {
  593. if( !HasKeyframe( ref keyframes, k.time ) )
  594. {
  595. ArrayUtility.Add<Keyframe>( ref keyframes, k );
  596. addedFrames = true;
  597. }
  598. }
  599. }
  600. if( addedFrames )
  601. {
  602. Array.Sort<Keyframe>( keyframes, delegate(Keyframe a, Keyframe b) {
  603. return a.time.CompareTo( b.time );
  604. } );
  605. }
  606. return keyframes;
  607. }
  608. private bool HasKeyframe( ref Keyframe[] keyframes, float t )
  609. {
  610. foreach( Keyframe k in keyframes )
  611. {
  612. if( Mathf.Approximately( k.time, t ) )
  613. return true;
  614. if( k.time > t )
  615. break;
  616. }
  617. return false;
  618. }
  619. public Quaternion GetRotation( float t )
  620. {
  621. Quaternion rot = Quaternion.identity;
  622. // since the quaternion may not be normalized, we have to do it ourselves
  623. // Vector4 rotVec = new Vector4( xRot.Evaluate(t), yRot.Evaluate(t), zRot.Evaluate(t), wRot.Evaluate(t) );
  624. // rotVec.Normalize();
  625. // Quaternion rot = new Quaternion( rotVec.x, rotVec.y, rotVec.z, rotVec.w );
  626. // probably this doesn't make sense to check? You need to have the 4 channels
  627. if( xRot != null )
  628. rot.x = xRot.Evaluate( t );
  629. if( yRot != null )
  630. rot.y = yRot.Evaluate( t );
  631. if( zRot != null )
  632. rot.z = zRot.Evaluate( t );
  633. if( wRot != null )
  634. rot.w = wRot.Evaluate( t );
  635. // rot.eulerAngles = new Vector3( xRot2.Evaluate(t), yRot2.Evaluate(t), zRot2.Evaluate(t) );
  636. return rot;
  637. }
  638. public Vector3 GetScale( float t )
  639. {
  640. Vector3 scale = Vector3.one;
  641. if( xScale != null )
  642. scale.x = xScale.Evaluate(t);
  643. if( yScale != null )
  644. scale.y = yScale.Evaluate(t);
  645. if( zScale != null )
  646. scale.z = zScale.Evaluate(t);
  647. return scale;
  648. }
  649. }
  650. }