FSequence.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836
  1. using UnityEngine;
  2. using UnityEngine.Events;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. /**
  6. * @brief Flux is top namespace for everything pertaining to the runtime.
  7. */
  8. namespace Flux
  9. {
  10. public enum ActionOnStart
  11. {
  12. None = 0,
  13. Initialize,
  14. Play
  15. }
  16. /**
  17. * @brief FSequence is the main runtime class. It holds all the timelines and controls their behaviour.
  18. * @sa FTimeline, FTrack, FEvent
  19. */
  20. public class FSequence : FObject
  21. {
  22. public const int DEFAULT_FRAMES_PER_SECOND = 60;
  23. public const int DEFAULT_LENGTH = 10;
  24. public const float DEFAULT_SPEED = 1f;
  25. public static FSequence CreateSequence()
  26. {
  27. return CreateSequence( new GameObject("FSequence") );
  28. }
  29. public static FSequence CreateSequence( GameObject gameObject )
  30. {
  31. FSequence sequence = gameObject.AddComponent<FSequence>();
  32. sequence._content = new GameObject("SequenceContent").transform;
  33. sequence._content.hideFlags |= HideFlags.HideInHierarchy;
  34. sequence._content.parent = sequence.transform;
  35. sequence.Add( FContainer.Create(FContainer.DEFAULT_COLOR) );
  36. sequence.Version = FUtility.FLUX_VERSION;
  37. return sequence;
  38. }
  39. [SerializeField]
  40. [HideInInspector]
  41. private GameObject _CasterActor = null;
  42. public GameObject CasterActor
  43. {
  44. get { return _CasterActor; }
  45. set
  46. {
  47. if(_CasterActor!=null)
  48. {
  49. _CasterActor = value;
  50. ResetDefaultVal();
  51. }
  52. }
  53. }
  54. [SerializeField]
  55. [HideInInspector]
  56. private GameObject _TargetActor = null;
  57. public GameObject TargetActor
  58. {
  59. get { return _TargetActor; }
  60. set {
  61. if(_TargetActor!=value)
  62. {
  63. _TargetActor = value;
  64. ResetDefaultVal();
  65. }
  66. }
  67. }
  68. [SerializeField]
  69. private GameObject _CameraGo = null;
  70. public GameObject CameraGo
  71. {
  72. get { return _CameraGo; }
  73. set { _CameraGo = value; }
  74. }
  75. [SerializeField]
  76. private Transform _content = null;
  77. /// @brief Child Transform (hidden by default) that holds the containers.
  78. public Transform Content { get { return _content; } set { _content = value; _content.parent = transform; } }
  79. [SerializeField]
  80. private List<FContainer> _containers = new List<FContainer>();
  81. /// @brief Containers inside the sequence.
  82. public List<FContainer> Containers { get { return _containers; } }
  83. [SerializeField]
  84. [HideInInspector]
  85. private int _version = 0;
  86. public int Version { get { return _version; } set { _version = value; } }
  87. [SerializeField]
  88. [Tooltip("What should be the default action when Start() gets called?\n\tNone\n\tInitialize\n\tPlay")]
  89. private ActionOnStart _actionOnStart = ActionOnStart.None;
  90. /// @brief What should be the default action when Start() gets called?
  91. public ActionOnStart ActionOnStart { get{ return _actionOnStart; } set { _actionOnStart = value; } }
  92. [SerializeField]
  93. private bool _loop = false;
  94. /// @brief Does the sequence loop when it reaches the end?
  95. public bool Loop { get { return _loop; } set { _loop = value; } }
  96. [SerializeField]
  97. private float _defaultSpeed = DEFAULT_SPEED;
  98. /// @brief Speed that is used when sequence is loaded. When you want to change runtime see, use Speed instead
  99. public float DefaultSpeed { get { return _defaultSpeed; } set { _defaultSpeed = value; } }
  100. private float _speed = DEFAULT_SPEED;
  101. /// @brief Current speed, used to control the speed of the sequence. If negative, sequence will play backwards.
  102. public float Speed {
  103. get{ return _speed; }
  104. set{
  105. bool wasPlayingForward = _isPlayingForward;
  106. _speed = value;
  107. _isPlayingForward = Speed * Time.timeScale >= 0;
  108. // if we change the speed to playing back while it is playing already we need
  109. // to create the track caches to handle going backwards
  110. if( (wasPlayingForward != _isPlayingForward) && Application.isPlaying && IsInit )
  111. CreateTrackCaches();
  112. }
  113. }
  114. /// @brief Should it update on FixedUpdate? If false, it will update on Update.
  115. [SerializeField]
  116. private AnimatorUpdateMode _updateMode = AnimatorUpdateMode.Normal;
  117. public AnimatorUpdateMode UpdateMode { get { return _updateMode; } set { _updateMode = value; } }
  118. /// @brief The length of this sequence in frames.
  119. [SerializeField]
  120. private int _length = DEFAULT_LENGTH * DEFAULT_FRAMES_PER_SECOND;
  121. /// @brief Length of this sequence in frames.
  122. public int Length { get { return _length; } set { _length = value; } }
  123. /// @brief Returns the length of this sequence in seconds.
  124. /// @Warning This value isn't cached internally, so avoid calling it all the time.
  125. public float LengthTime { get { return (float)_length * _inverseFrameRate; } }
  126. [SerializeField]
  127. [HideInInspector]
  128. private SequenceFinishedEvent _onFinishedCallback = new SequenceFinishedEvent();
  129. /// @brief Callback when sequence reaches last frame (or frame 0 when moving backwards)
  130. public SequenceFinishedEvent OnFinishedCallback { get { return _onFinishedCallback; } }
  131. // private FTimeline _globalTimeline = null;
  132. // /// @brief Global Timeline. It is always visible, doesn't get processed at runtime, and used for things like comment track.
  133. // public FTimeline GlobalTimeline { get { return _globalTimeline; } }
  134. [SerializeField]
  135. [HideInInspector]
  136. private int _frameRate = DEFAULT_FRAMES_PER_SECOND; // frame rate
  137. /** @brief Frame Rate of this sequence.
  138. * @Warning Although we allow you to change this value at runtime, you should be careful in how you use it.
  139. * Changing this value \b will not \b rescale the sequence. Rescaling the sequence should only be done in editor,
  140. * not at runtime.
  141. * @sa CSequenceInspector.Rescale(CSequence, int)
  142. * @sa InverseFrameRate
  143. */
  144. public int FrameRate { get { return _frameRate; } set { _frameRate = value; _inverseFrameRate = 1f / _frameRate; } }
  145. [SerializeField]
  146. [HideInInspector]
  147. private float _inverseFrameRate = 1f / DEFAULT_FRAMES_PER_SECOND;
  148. /// @brief Returns 1 / FrameRate. This value is cached and set automatically when FrameRate is called.
  149. /// @sa FrameRate
  150. public float InverseFrameRate { get { return _inverseFrameRate; } }
  151. // has it been initialized?
  152. private bool _isInit = false;
  153. /// @brief Is the sequence initialized?
  154. public bool IsInit { get { return _isInit; } }
  155. // Is the sequence playing?
  156. private bool _isPlaying = false;
  157. /// @brief Is the sequence playing?
  158. public bool IsPlaying { get { return _isPlaying; } }
  159. // Is the sequence playing forward?
  160. private bool _isPlayingForward = true;
  161. /// @brief Is the sequence moving forward?
  162. public bool IsPlayingForward { get { return _isPlayingForward; } }
  163. // time we last updated
  164. private float _lastUpdateTime = 0;
  165. public override Transform Owner {
  166. get {
  167. return transform;
  168. }
  169. }
  170. public override FSequence Sequence {
  171. get {
  172. return this;
  173. }
  174. }
  175. public void Add( FContainer container )
  176. {
  177. int id = _containers.Count;
  178. _containers.Add( container );
  179. container.SetId( id );
  180. container.SetSequence( this );
  181. }
  182. public void Remove( FContainer container )
  183. {
  184. if( _containers.Remove( container ) )
  185. {
  186. container.SetSequence( null );
  187. UpdateContainerIds();
  188. }
  189. }
  190. // Current frame, i.e. (int)(_currentTime * frameRate)
  191. private int _currentFrame = -1;
  192. // Last frame, to determine if the frame has advanced or not
  193. private int _lastFrame = -1;
  194. // What's the current time
  195. private float _currentTime = -1;
  196. /** @brief Sets the current time, to be used when in editor mode, _not_ for runtime.
  197. * @param time Time.
  198. * @sa SetCurrentTime
  199. */
  200. public void SetCurrentTimeEditor( float time )
  201. {
  202. if( time != _currentTime && _currentFrame != -1 )
  203. Speed = time > _currentTime ? Mathf.Abs(Speed) : -Mathf.Abs(Speed);
  204. CurrentTime = Mathf.Clamp( time, 0, LengthTime );
  205. for( int i = 0; i != _containers.Count; ++i )
  206. {
  207. if( !_containers[i].enabled ) continue;
  208. _containers[i].UpdateTimelinesEditor( _currentFrame, _currentTime );
  209. }
  210. }
  211. /**
  212. * @brief Sets the current time manually, e.g. if you want to jump to a specific point of the
  213. * sequence.
  214. * @param time Time.
  215. * @sa SetCurrentFrame, SetCurrentTimeEditor
  216. */
  217. public void SetCurrentTime( float time )
  218. {
  219. if( !_isInit )
  220. Init();
  221. // if setting the time we're on, or we just started playing, ignore this
  222. if( time != _currentTime && _currentFrame != -1 )
  223. {
  224. // if we're changing time in a direction different from the one we're going,
  225. // we need to clear the tracks in order to be in the proper state when we move to
  226. // a certain time
  227. if( ! (IsPlayingForward && time > _currentTime) )
  228. {
  229. for( int i = 0; i != _containers.Count; ++i )
  230. _containers[i].Stop();
  231. }
  232. }
  233. SetCurrentTimeInternal( time );
  234. }
  235. /** @brief Sets the current time based on the frame, but just calculates it internally for you.
  236. * @param frame Frame.
  237. * @sa SetCurrentTime
  238. */
  239. public void SetCurrentFrame( int frame )
  240. {
  241. SetCurrentTime( frame * InverseFrameRate );
  242. }
  243. /// @brief Sets the current frame based on the time passed.
  244. /// @param time Time in seconds, this will set current frame with time x FrameRate.
  245. protected void SetCurrentTimeInternal( float time )
  246. {
  247. CurrentTime = Mathf.Clamp( time, 0, LengthTime );
  248. for( int i = 0; i != _containers.Count; ++i )
  249. {
  250. if( !_containers[i].enabled ) continue;
  251. _containers[i].UpdateTimelines( _currentFrame, _currentTime );
  252. }
  253. }
  254. /// @brief Returns the current frame.
  255. /// @sa SetCurrentFrame, GetCurrentFrame
  256. public int CurrentFrame {
  257. get {
  258. return _currentFrame;
  259. }
  260. private set {
  261. _lastFrame = value < 0 ? -1 : _currentFrame;
  262. _currentFrame = value;
  263. }
  264. }
  265. /** @brief Returns current time. */
  266. public float CurrentTime {
  267. get {
  268. return _currentTime;
  269. }
  270. private set {
  271. _currentTime = value;
  272. if( _currentTime < 0 )
  273. CurrentFrame = -1;
  274. else
  275. {
  276. float epsilon = 0.001f;
  277. CurrentFrame = IsPlayingForward ? Mathf.FloorToInt(_currentTime * _frameRate + epsilon) : Mathf.CeilToInt(_currentTime*_frameRate - epsilon);
  278. }
  279. }
  280. }
  281. public bool FrameChanged { get { return _lastFrame != _currentFrame; } }
  282. /// @brief Initializes the sequence.
  283. /// This is called at the start of the sequence, it is meant for the
  284. /// user to setup all the cached variables.
  285. /// @note If you want to avoid frame drops, call this function before
  286. /// calling Play.
  287. public override void Init()
  288. {
  289. #if FLUX_DEBUG
  290. Debug.Log("Init");
  291. #endif
  292. #if FLUX_PROFILE
  293. Profiler.BeginSample( "FSequence.Init()" );
  294. #endif
  295. _isInit = true; // set init first so that cache doesn't go into infinite loop
  296. for( int i = 0; i != _containers.Count; ++i )
  297. _containers[i].Init();
  298. // build caches for tracks that require it at runtime
  299. CreateTrackCaches();
  300. _isInit = true; // force again init since create caches can clear it
  301. #if FLUX_PROFILE
  302. Profiler.EndSample();
  303. #endif
  304. }
  305. public void CreateTrackCaches()
  306. {
  307. for( int i = 0; i != _containers.Count; ++i )
  308. {
  309. List<FTimeline> timelines = _containers[i].Timelines;
  310. for( int j = 0; j != timelines.Count; ++j )
  311. {
  312. List<FTrack> tracks = timelines[j].Tracks;
  313. foreach( FTrack track in tracks )
  314. {
  315. #if UNITY_EDITOR
  316. if( ((!Application.isPlaying && track.RequiresEditorCache) || (IsPlayingForward && track.RequiresForwardCache) || (!IsPlayingForward && track.RequiresBackwardsCache)) && !track.HasCache )
  317. track.CreateCache();
  318. #else
  319. if( ((IsPlayingForward && track.RequiresForwardCache) || (!IsPlayingForward && track.RequiresBackwardsCache)) && !track.HasCache )
  320. track.CreateCache();
  321. #endif
  322. }
  323. }
  324. }
  325. }
  326. public void DestroyTrackCaches()
  327. {
  328. foreach( FContainer container in Containers )
  329. {
  330. foreach( FTimeline timeline in container.Timelines )
  331. {
  332. foreach( FTrack track in timeline.Tracks )
  333. {
  334. if( track.HasCache )
  335. track.ClearCache();
  336. }
  337. }
  338. }
  339. }
  340. /// @override Starts playing on a specific frame.
  341. public void Play( int startFrame )
  342. {
  343. Play( startFrame * _inverseFrameRate );
  344. }
  345. /// @brief Starts playing at time.
  346. /// @param startTime What time to start playing from.
  347. /// @sa Init
  348. public void Play( float startTime )
  349. {
  350. if( _isPlaying )
  351. return;
  352. _isPlayingForward = Speed * Time.timeScale >= 0;
  353. if( !_isInit )
  354. Init();
  355. if( !IsStopped )
  356. Resume();
  357. _isPlaying = true;
  358. switch( _updateMode )
  359. {
  360. case AnimatorUpdateMode.Normal:
  361. _lastUpdateTime = Time.time;
  362. break;
  363. case AnimatorUpdateMode.AnimatePhysics:
  364. _lastUpdateTime = Time.fixedTime;
  365. break;
  366. case AnimatorUpdateMode.UnscaledTime:
  367. _lastUpdateTime = Time.unscaledTime;
  368. break;
  369. default:
  370. Debug.LogError("Unsupported Update Mode");
  371. _lastUpdateTime = Time.time;
  372. break;
  373. }
  374. SetCurrentTimeInternal( startTime );
  375. }
  376. /// @brief Starts playing from either the start or the end, depending on which
  377. /// direction it is playing.
  378. /// @sa Init, Stop, Pause
  379. public void Play()
  380. {
  381. if( IsPlayingForward )
  382. Play( 0f );
  383. else
  384. Play( LengthTime );
  385. }
  386. /// @brief Stops sequence.
  387. public override void Stop()
  388. {
  389. Stop( false );
  390. }
  391. /** @brief Stops sequence.
  392. * @param reset If true, it clears Init, i.e. it will force the Init phase to happen again.
  393. */
  394. public void Stop( bool reset )
  395. {
  396. if( reset )
  397. _isInit = false;
  398. if ( IsStopped && !reset )
  399. return;
  400. #if FLUX_DEBUG
  401. Debug.Log ("Stop");
  402. #endif
  403. _isPlaying = false;
  404. _isPlayingForward = Speed*Time.timeScale >= 0;
  405. for( int i = 0; i != _containers.Count; ++i )
  406. _containers[i].Stop();
  407. CurrentTime = -1;
  408. _lastUpdateTime = 0;
  409. }
  410. /**
  411. * @brief Pauses sequence.
  412. * @sa FEvent.OnPause, FEvent.OnResume
  413. */
  414. public void Pause()
  415. {
  416. if( !_isPlaying )
  417. return;
  418. _isPlaying = false;
  419. for( int i = 0; i != _containers.Count; ++i )
  420. _containers[i].Pause();
  421. }
  422. /**
  423. * @brief Resumes a sequence that is paused.
  424. * Doesn't work if the sequence is stopped.
  425. * @sa Play, Stop, Pause
  426. */
  427. public void Resume()
  428. {
  429. if( _isPlaying )
  430. return;
  431. _isPlaying = true;
  432. for( int i = 0; i !=_containers.Count; ++i )
  433. _containers[i].Resume();
  434. switch( _updateMode )
  435. {
  436. case AnimatorUpdateMode.Normal:
  437. _lastUpdateTime = Time.time;
  438. break;
  439. case AnimatorUpdateMode.AnimatePhysics:
  440. _lastUpdateTime = Time.fixedTime;
  441. break;
  442. case AnimatorUpdateMode.UnscaledTime:
  443. _lastUpdateTime = Time.unscaledTime;
  444. break;
  445. default:
  446. Debug.LogError("Unsupported Update Mode");
  447. _lastUpdateTime = Time.time;
  448. break;
  449. }
  450. }
  451. /// @brief Is the sequence paused?
  452. public bool IsPaused { get { return !_isPlaying && _currentFrame >= 0; } }
  453. /// @brief Is the sequence stopped?
  454. public bool IsStopped { get { return _currentFrame < 0; } }
  455. /// @brief Is the sequence finished? Does not finish when it loops.
  456. public bool IsFinished { get { return IsPaused && ((IsPlayingForward && _currentTime == LengthTime) || (!IsPlayingForward && _currentTime == 0)); } }
  457. /// @brief Does the sequence have no events?
  458. public bool IsEmpty()
  459. {
  460. foreach( FContainer container in _containers )
  461. {
  462. if( !container.IsEmpty() )
  463. return false;
  464. }
  465. return true;
  466. }
  467. /// @brief Determines wether it has any timelines.
  468. public bool HasTimelines()
  469. {
  470. foreach( FContainer container in _containers )
  471. {
  472. if( container.Timelines.Count > 0 )
  473. return true;
  474. }
  475. return false;
  476. }
  477. protected virtual void Awake()
  478. {
  479. Speed = DefaultSpeed;
  480. _isPlayingForward = Speed * Time.timeScale >= 0;
  481. }
  482. protected virtual void Start()
  483. {
  484. switch( _actionOnStart )
  485. {
  486. case ActionOnStart.None:
  487. // do nothing
  488. break;
  489. case ActionOnStart.Initialize:
  490. Init();
  491. break;
  492. case ActionOnStart.Play:
  493. Play();
  494. break;
  495. }
  496. }
  497. // Updates the sequence when update mode is NOT AnimatePhysics
  498. protected virtual void Update()
  499. {
  500. if( _updateMode == AnimatorUpdateMode.AnimatePhysics || !_isPlaying )
  501. {
  502. return;
  503. }
  504. InternalUpdate( _updateMode == AnimatorUpdateMode.Normal ? Time.time : Time.unscaledTime );
  505. }
  506. // Updates the sequence when update mode is AnimatePhysics
  507. protected virtual void FixedUpdate()
  508. {
  509. if( _updateMode != AnimatorUpdateMode.AnimatePhysics || !_isPlaying )
  510. {
  511. return;
  512. }
  513. InternalUpdate( Time.fixedTime );
  514. }
  515. protected virtual void InternalUpdate( float time )
  516. {
  517. float delta = time - _lastUpdateTime;
  518. if( delta != 0 )
  519. {
  520. SetCurrentTimeInternal( _currentTime + delta * Speed );
  521. if( _isPlayingForward )
  522. {
  523. if( _currentTime == LengthTime )
  524. {
  525. OnFinishedCallback.Invoke( this );
  526. if( _loop )
  527. {
  528. Stop();
  529. Play();
  530. }
  531. else
  532. {
  533. Pause();
  534. }
  535. }
  536. }
  537. else
  538. {
  539. if( _currentTime == 0 )
  540. {
  541. OnFinishedCallback.Invoke( this );
  542. if( _loop )
  543. {
  544. Stop();
  545. Play(); // @TODO Play backwards
  546. }
  547. else
  548. {
  549. Pause();
  550. }
  551. }
  552. }
  553. _lastUpdateTime = time;
  554. }
  555. }
  556. public void Rebuild()
  557. {
  558. #if FLUX_DEBUG
  559. Debug.Log("Rebuilding");
  560. #endif
  561. _containers.Clear();
  562. Transform t = Content;
  563. for( int i = 0; i != t.childCount; ++i )
  564. {
  565. FContainer container = t.GetChild( i ).GetComponent<FContainer>();
  566. if( container != null )
  567. {
  568. _containers.Add( container );
  569. container.SetSequence( this );
  570. container.Rebuild();
  571. }
  572. }
  573. UpdateContainerIds();
  574. }
  575. private void UpdateContainerIds()
  576. {
  577. for( int i = 0; i != _containers.Count; ++i )
  578. {
  579. _containers[i].SetId( i );
  580. }
  581. }
  582. public void ReplaceOwner( Transform oldOwner, Transform newOwner )
  583. {
  584. foreach( FContainer container in _containers )
  585. {
  586. foreach( FTimeline timeline in container.Timelines )
  587. {
  588. if( timeline.Owner == oldOwner )
  589. timeline.SetOwner( newOwner );
  590. }
  591. }
  592. }
  593. public void ReplaceOwner( string timelineName, Transform newOwner )
  594. {
  595. foreach( FContainer container in _containers )
  596. {
  597. foreach( FTimeline timeline in container.Timelines )
  598. {
  599. if( timeline.gameObject.name == timelineName )
  600. timeline.SetOwner( newOwner );
  601. }
  602. }
  603. }
  604. public void ReplaceOwnerByPath( string ownerPath, Transform newOwner )
  605. {
  606. foreach( FContainer container in _containers )
  607. {
  608. foreach( FTimeline timeline in container.Timelines )
  609. {
  610. if( timeline.OwnerPath == ownerPath )
  611. timeline.SetOwner( newOwner );
  612. }
  613. }
  614. }
  615. public void ReplaceOwner( params KeyValuePair<Transform, Transform>[] replacements )
  616. {
  617. foreach( FContainer container in _containers )
  618. {
  619. foreach( FTimeline timeline in container.Timelines )
  620. {
  621. foreach( KeyValuePair<Transform, Transform> replacement in replacements )
  622. {
  623. if( timeline.Owner == replacement.Key )
  624. {
  625. timeline.SetOwner( replacement.Value );
  626. break;
  627. }
  628. }
  629. }
  630. }
  631. }
  632. #if UNITY_EDITOR
  633. public void SaveToXml()
  634. {
  635. foreach (FContainer container in _containers)
  636. {
  637. foreach(FTimeline timeline in container.Timelines )
  638. {
  639. timeline.SaveToXml();
  640. }
  641. }
  642. }
  643. public void LoadFromXml()
  644. {
  645. }
  646. #endif
  647. public void ResetDefaultVal()
  648. {
  649. if(Containers!=null)
  650. {
  651. for(int idx =0; idx < Containers.Count;idx++)
  652. {
  653. FContainer c = Containers[idx];
  654. for (int jdx = 0; jdx < c.Timelines.Count;jdx++)
  655. {
  656. FTimeline tline = c.Timelines[jdx];
  657. for(int kdx = 0; kdx < tline.Tracks.Count;kdx++ )
  658. {
  659. FTrack track = tline.Tracks[kdx];
  660. for(int edx = 0; edx < track.Events.Count;edx++)
  661. {
  662. FEvent evt = track.Events[edx];
  663. evt.SetDefaultValues();
  664. }
  665. }
  666. }
  667. }
  668. }
  669. }
  670. #if FLUX_TRIAL
  671. private Rect _watermarkLabelRect = new Rect(0,0,0,0);
  672. private GUIStyle _watermarkLabelStyle;
  673. private float _watermarkEndTime;
  674. private float _watermarkAlpha;
  675. private void OnGUI()
  676. {
  677. if( !IsPlaying )
  678. return;
  679. float watermarkDuration = 3f;
  680. GUIContent watermark = new GUIContent("..::FLUX TRIAL::..");
  681. if( _watermarkLabelRect.width == 0 )
  682. {
  683. _watermarkLabelStyle = new GUIStyle(GUI.skin.label);
  684. _watermarkLabelStyle.fontSize = 24;
  685. Vector2 size = _watermarkLabelStyle.CalcSize( watermark );
  686. _watermarkLabelRect.x = Random.Range(0, Screen.width-size.x);
  687. _watermarkLabelRect.y = Random.Range(0, 2);
  688. if( _watermarkLabelRect.y == 1 )
  689. _watermarkLabelRect.y = Screen.height-size.y;
  690. _watermarkLabelRect.width = size.x;
  691. _watermarkLabelRect.height = size.y;
  692. _watermarkEndTime = Time.time + watermarkDuration;
  693. _watermarkAlpha = 1.6f;
  694. }
  695. GUI.color = new Color(1f, 1f, 1f, _watermarkAlpha + 0.4f );
  696. GUI.Label( _watermarkLabelRect, watermark, _watermarkLabelStyle );
  697. if( Time.time < _watermarkEndTime )
  698. {
  699. _watermarkAlpha -= Time.deltaTime / watermarkDuration;
  700. if( _watermarkAlpha < 0 )
  701. _watermarkAlpha = 0;
  702. }
  703. }
  704. #endif
  705. }
  706. [System.Serializable]
  707. public class SequenceFinishedEvent : UnityEvent<FSequence>
  708. {
  709. }
  710. }