using UnityEngine; using FTRuntime.Internal; using System.Collections.Generic; namespace FTRuntime { [AddComponentMenu("FlashTools/SwfManager")] [ExecuteInEditMode, DisallowMultipleComponent] public class SwfManager : MonoBehaviour { SwfAssocList _clips = new SwfAssocList(); SwfAssocList _controllers = new SwfAssocList(); SwfList _safeUpdates = new SwfList(); bool _isPaused = false; bool _useUnscaledDt = false; float _rateScale = 1.0f; HashSet _groupPauses = new HashSet(); HashSet _groupUnscales = 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 a value indicating whether animation updates uses unscaled delta time /// /// true if uses unscaled delta time; otherwise, false public bool useUnscaledDt { get { return _useUnscaledDt; } set { _useUnscaledDt = 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 use unscaled delta time /// /// Group name /// true if group will use unscaled delta time; otherwise, false public void SetGroupUseUnscaledDt(string group_name, bool yesno) { if ( !string.IsNullOrEmpty(group_name) ) { if ( yesno ) { _groupUnscales.Add(group_name); } else { _groupUnscales.Remove(group_name); } } } /// /// Determines whether group of animations uses unscaled delta time /// /// true if group uses unscaled delta time; otherwise, false /// Group name public bool IsGroupUseUnscaledDt(string group_name) { return _groupUnscales.Contains(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 SetupCameras() { foreach ( var camera in Camera.allCameras ) { camera.clearStencilAfterLightingPass = true; } } 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 LateUpdateClips() { for ( int i = 0, e = _clips.Count; i < e; ++i ) { var clip = _clips[i]; if ( clip ) { clip.Internal_UpdateMesh(); } } } void LateUpdateControllers(float scaled_dt, float unscaled_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(scaled_dt, unscaled_dt); } else if ( IsGroupPlaying(group_name) ) { var group_rate_scale = GetGroupRateScale(group_name); ctrl.Internal_Update( group_rate_scale * (IsGroupUseUnscaledDt(group_name) ? unscaled_dt : scaled_dt), group_rate_scale * unscaled_dt); } } } _safeUpdates.Clear(); } // --------------------------------------------------------------------- // // Messages // // --------------------------------------------------------------------- void OnEnable() { SetupCameras(); GrabEnabledClips(); GrabEnabledControllers(); } void OnDisable() { DropClips(); DropControllers(); } void LateUpdate() { if ( isPlaying ) { LateUpdateControllers( rateScale * (useUnscaledDt ? Time.unscaledDeltaTime : Time.deltaTime), rateScale * Time.unscaledDeltaTime); } LateUpdateClips(); } } }