using UnityEngine; using FTRuntime.Internal; using System.Collections.Generic; namespace FTRuntime { [ExecuteInEditMode, DisallowMultipleComponent] public class SwfManager : MonoBehaviour { SwfAssocList _clips = new SwfAssocList(); SwfAssocList _controllers = new SwfAssocList(); SwfList _safeUpdates = new SwfList(); bool _isPaused = false; float _rateScale = 1.0f; HashSet _groupPauses = new HashSet(); Dictionary _groupRateScales = new Dictionary(); // --------------------------------------------------------------------- // // Instance // // --------------------------------------------------------------------- static SwfManager _instance; /// /// Get cached manager instance from scene or create it (if allowed) /// /// The manager instance /// If set to true allow create public static SwfManager GetInstance(bool allow_create) { if ( !_instance ) { _instance = FindObjectOfType(); if ( allow_create && !_instance ) { var go = new GameObject("[SwfManager]"); _instance = go.AddComponent(); } } return _instance; } // --------------------------------------------------------------------- // // Properties // // --------------------------------------------------------------------- /// /// Get animation clip count on scene /// /// Clip count public int clipCount { get { return _clips.Count; } } /// /// Get animation clip controller count on scene /// /// Clip controller count public int controllerCount { get { return _controllers.Count; } } /// /// Get or set a value indicating whether animation updates is paused /// /// true if is paused; otherwise, false. public bool isPaused { get { return _isPaused; } set { _isPaused = value; } } /// /// Get or set a value indicating whether animation updates is playing /// /// true if is playing; otherwise, false. public bool isPlaying { get { return !_isPaused; } set { _isPaused = !value; } } /// /// Get or set the global animation rate scale /// /// Global rate scale public float rateScale { get { return _rateScale; } set { _rateScale = Mathf.Clamp(value, 0.0f, float.MaxValue); } } // --------------------------------------------------------------------- // // Functions // // --------------------------------------------------------------------- /// /// Pause animation updates /// public void Pause() { isPaused = true; } /// /// Resume animation updates /// public void Resume() { isPlaying = true; } /// /// Pause the group of animations by name /// /// Group name public void PauseGroup(string group_name) { if ( !string.IsNullOrEmpty(group_name) ) { _groupPauses.Add(group_name); } } /// /// Resume the group of animations by name /// /// Group name public void ResumeGroup(string group_name) { if ( !string.IsNullOrEmpty(group_name) ) { _groupPauses.Remove(group_name); } } /// /// Determines whether group of animations is paused /// /// true if group is paused; otherwise, false. /// Group name public bool IsGroupPaused(string group_name) { return _groupPauses.Contains(group_name); } /// /// Determines whether group of animations is playing /// /// true if group is playing; otherwise, false. /// Group name public bool IsGroupPlaying(string group_name) { return !IsGroupPaused(group_name); } /// /// Set the group of animations rate scale /// /// Group name /// Rate scale public void SetGroupRateScale(string group_name, float rate_scale) { if ( !string.IsNullOrEmpty(group_name) ) { _groupRateScales[group_name] = Mathf.Clamp(rate_scale, 0.0f, float.MaxValue); } } /// /// Get the group of animations rate scale /// /// The group rate scale. /// Group name. public float GetGroupRateScale(string group_name) { float rate_scale; return _groupRateScales.TryGetValue(group_name, out rate_scale) ? rate_scale : 1.0f; } // --------------------------------------------------------------------- // // Internal // // --------------------------------------------------------------------- internal void AddClip(SwfClip clip) { _clips.Add(clip); } internal void RemoveClip(SwfClip clip) { _clips.Remove(clip); } internal void GetAllClips(List clips) { _clips.AssignTo(clips); } internal void AddController(SwfClipController controller) { _controllers.Add(controller); } internal void RemoveController(SwfClipController controller) { _controllers.Remove(controller); } void GrabEnabledClips() { var clips = FindObjectsOfType(); for ( int i = 0, e = clips.Length; i < e; ++i ) { var clip = clips[i]; if ( clip.enabled ) { _clips.Add(clip); } } } void GrabEnabledControllers() { var controllers = FindObjectsOfType(); for ( int i = 0, e = controllers.Length; i < e; ++i ) { var controller = controllers[i]; if ( controller.enabled ) { _controllers.Add(controller); } } } void DropClips() { _clips.Clear(); } void DropControllers() { _controllers.Clear(); } void UpdateControllers(float dt) { _controllers.AssignTo(_safeUpdates); for ( int i = 0, e = _safeUpdates.Count; i < e; ++i ) { var ctrl = _safeUpdates[i]; if ( ctrl ) { var group_name = ctrl.groupName; if ( string.IsNullOrEmpty(group_name) ) { ctrl.Internal_Update(dt); } else if ( IsGroupPlaying(group_name) ) { var group_rate_scale = GetGroupRateScale(group_name); ctrl.Internal_Update(group_rate_scale * dt); } } } _safeUpdates.Clear(); } void LateUpdateClips() { for ( int i = 0, e = _clips.Count; i < e; ++i ) { var clip = _clips[i]; if ( clip ) { clip.Internal_LateUpdate(); } } } // --------------------------------------------------------------------- // // Messages // // --------------------------------------------------------------------- void OnEnable() { GrabEnabledClips(); GrabEnabledControllers(); } void OnDisable() { DropClips(); DropControllers(); } void Update() { if ( isPlaying ) { var dt = Time.deltaTime; UpdateControllers(rateScale * dt); } } void LateUpdate() { LateUpdateClips(); } } }