├── .gitignore ├── Assets ├── Timers.meta └── Timers │ ├── Example.meta │ ├── Example │ ├── Test.cs │ ├── Test.cs.meta │ ├── test.unity │ └── test.unity.meta │ ├── Special.meta │ ├── Special │ ├── Ability.cs │ └── Ability.cs.meta │ ├── Timer.cs │ ├── Timer.cs.meta │ ├── TimerHelper.cs │ ├── TimerHelper.cs.meta │ ├── Timer_Behaviors.cs │ └── Timer_Behaviors.cs.meta ├── LICENSE ├── LICENSE.meta ├── ProjectSettings ├── AudioManager.asset ├── ClusterInputManager.asset ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset ├── NavMeshAreas.asset ├── NetworkManager.asset ├── Physics2DSettings.asset ├── ProjectSettings.asset ├── ProjectVersion.txt ├── QualitySettings.asset ├── TagManager.asset ├── TimeManager.asset ├── UnityAdsSettings.asset └── UnityConnectSettings.asset ├── README.md ├── Test.meta ├── Timer.cs.meta ├── TimerHelper.cs.meta └── Timer_Behaviors.cs.meta /.gitignore: -------------------------------------------------------------------------------- 1 | /[Ll]ibrary/ 2 | /[Tt]emp/ 3 | /[Oo]bj/ 4 | /[Bb]uild/ 5 | /[Bb]uilds/ 6 | /Assets/AssetStoreTools* 7 | 8 | # Autogenerated VS/MD solution and project files 9 | ExportedObj/ 10 | *.csproj 11 | *.unityproj 12 | *.sln 13 | *.suo 14 | *.tmp 15 | *.user 16 | *.userprefs 17 | *.pidb 18 | *.booproj 19 | *.svd 20 | 21 | 22 | # Unity3D generated meta files 23 | *.pidb.meta 24 | 25 | # Unity3D Generated File On Crash Reports 26 | sysinfo.txt 27 | -------------------------------------------------------------------------------- /Assets/Timers.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c487c5b02ac763a45a5b72c73c3240bb 3 | folderAsset: yes 4 | timeCreated: 1473339839 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Timers/Example.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9b925090b4f7a3e49a7b6e7b3c5d20e7 3 | folderAsset: yes 4 | timeCreated: 1473339839 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Timers/Example/Test.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | public class Test : MonoBehaviour 5 | { 6 | 7 | // Use this for initialization 8 | void Start() 9 | { 10 | //Start simple repeater 11 | Timer.Repeater(5f, () => Debug.Log("Repeater test")); 12 | //Start countdown and call Draw in 2.5 seconds 13 | Timer.Countdown(2.5f, Draw); 14 | 15 | //Start countdown and tell it to ignore Time Scale 16 | Timer.Countdown(10f, () => Debug.Log("Terminating Countdown #2")).SetIgnoreTimeScale(true); 17 | //Start a repeater, if we try to destroy it manually it wont take effect as countdown self destructs on reaching end. 18 | Timer timer = Timer.Countdown(1f, null); 19 | timer.SetCallbacks(() => 20 | { 21 | Debug.Log("Destroyed timer:" + timer.GetHashCode()); timer.Destroy(); 22 | }); 23 | //After we launched sphere repeater we will change its update speed in 8 seconds 24 | Timer.Countdown(8f, () => sphereRepeater.MainInterval = 0.01f); 25 | //Create a timer and modify callback afterwards 26 | Timer t = Timer.Countdown(10f, null); 27 | t.SetCallbacks(() => Debug.Log("Delayed Callback")); 28 | //Pause it 29 | t.Pause(); 30 | //Resume it 31 | t.Unpause(); 32 | 33 | //Make eternal self reseting timer 34 | Timer toreset = Timer.Countdown(1f, null); 35 | //mark as non disposable 36 | toreset.DontDisposeOnComplete = true; 37 | //in callback it resets itself 38 | toreset.SetCallbacks(() => 39 | { 40 | print("resetting timer" + toreset.GetHashCode().ToString()); 41 | toreset.Reset(); 42 | }); 43 | 44 | //Test performance this will create ~500 timers and will rotate them afterwards in the pool eternally with no GC 45 | Timer.Repeater(.01f, SpawnTimers); 46 | } 47 | 48 | void SpawnTimers() 49 | { 50 | Timer t = Timer.Countdown(5f, null); 51 | t.SetCallbacks(() => t.GetHashCode()); 52 | } 53 | 54 | Timer sphereRepeater; 55 | void Draw() 56 | { 57 | //premake some data 58 | GameObject go = GameObject.CreatePrimitive(PrimitiveType.Sphere); 59 | //Start new repeater with parameters that will update our data this is completely stupid in this scenario but it shows the usage. 60 | Debug.Log("Started RepositioningSphere"); 61 | sphereRepeater = Timer.RepeaterParam( 62 | .1f 63 | , x => Reposition(x) 64 | , new object[1] { go }); 65 | } 66 | 67 | //Casting is costly, this is just example 68 | void Reposition(object[] args) 69 | { 70 | //Receive data and process it 71 | var go = args[0] as GameObject; 72 | 73 | var pos = go.transform.position; 74 | pos.y = Mathf.Sin(Time.time) * 2.5f; 75 | go.transform.position = pos; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Assets/Timers/Example/Test.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ab048a25e87eef34992701885c16974e 3 | timeCreated: 1461235087 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Timers/Example/test.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | SceneSettings: 5 | m_ObjectHideFlags: 0 6 | m_PVSData: 7 | m_PVSObjectsArray: [] 8 | m_PVSPortalsArray: [] 9 | m_OcclusionBakeSettings: 10 | smallestOccluder: 5 11 | smallestHole: 0.25 12 | backfaceThreshold: 100 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 7 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 29 | m_HaloStrength: 0.5 30 | m_FlareStrength: 1 31 | m_FlareFadeSpeed: 3 32 | m_HaloTexture: {fileID: 0} 33 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 34 | m_DefaultReflectionMode: 0 35 | m_DefaultReflectionResolution: 128 36 | m_ReflectionBounces: 1 37 | m_ReflectionIntensity: 1 38 | m_CustomReflection: {fileID: 0} 39 | m_Sun: {fileID: 0} 40 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 41 | --- !u!157 &3 42 | LightmapSettings: 43 | m_ObjectHideFlags: 0 44 | serializedVersion: 7 45 | m_GIWorkflowMode: 0 46 | m_GISettings: 47 | serializedVersion: 2 48 | m_BounceScale: 1 49 | m_IndirectOutputScale: 1 50 | m_AlbedoBoost: 1 51 | m_TemporalCoherenceThreshold: 1 52 | m_EnvironmentLightingMode: 0 53 | m_EnableBakedLightmaps: 1 54 | m_EnableRealtimeLightmaps: 1 55 | m_LightmapEditorSettings: 56 | serializedVersion: 4 57 | m_Resolution: 2 58 | m_BakeResolution: 40 59 | m_TextureWidth: 1024 60 | m_TextureHeight: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_Padding: 2 66 | m_LightmapParameters: {fileID: 0} 67 | m_LightmapsBakeMode: 1 68 | m_TextureCompression: 1 69 | m_DirectLightInLightProbes: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_LightingDataAsset: {fileID: 0} 75 | m_RuntimeCPUUsage: 25 76 | --- !u!196 &4 77 | NavMeshSettings: 78 | serializedVersion: 2 79 | m_ObjectHideFlags: 0 80 | m_BuildSettings: 81 | serializedVersion: 2 82 | agentRadius: 0.5 83 | agentHeight: 2 84 | agentSlope: 45 85 | agentClimb: 0.4 86 | ledgeDropHeight: 0 87 | maxJumpAcrossDistance: 0 88 | accuratePlacement: 0 89 | minRegionArea: 2 90 | cellSize: 0.16666667 91 | manualCellSize: 0 92 | m_NavMeshData: {fileID: 0} 93 | --- !u!1 &172517602 94 | GameObject: 95 | m_ObjectHideFlags: 0 96 | m_PrefabParentObject: {fileID: 0} 97 | m_PrefabInternal: {fileID: 0} 98 | serializedVersion: 4 99 | m_Component: 100 | - 4: {fileID: 172517604} 101 | - 114: {fileID: 172517603} 102 | m_Layer: 0 103 | m_Name: CLICKME 104 | m_TagString: Untagged 105 | m_Icon: {fileID: 0} 106 | m_NavMeshLayer: 0 107 | m_StaticEditorFlags: 0 108 | m_IsActive: 1 109 | --- !u!114 &172517603 110 | MonoBehaviour: 111 | m_ObjectHideFlags: 0 112 | m_PrefabParentObject: {fileID: 0} 113 | m_PrefabInternal: {fileID: 0} 114 | m_GameObject: {fileID: 172517602} 115 | m_Enabled: 1 116 | m_EditorHideFlags: 0 117 | m_Script: {fileID: 11500000, guid: ab048a25e87eef34992701885c16974e, type: 3} 118 | m_Name: 119 | m_EditorClassIdentifier: 120 | --- !u!4 &172517604 121 | Transform: 122 | m_ObjectHideFlags: 0 123 | m_PrefabParentObject: {fileID: 0} 124 | m_PrefabInternal: {fileID: 0} 125 | m_GameObject: {fileID: 172517602} 126 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 127 | m_LocalPosition: {x: 0.43013096, y: -0.8892231, z: 0.50918865} 128 | m_LocalScale: {x: 1, y: 1, z: 1} 129 | m_Children: [] 130 | m_Father: {fileID: 0} 131 | m_RootOrder: 0 132 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 133 | --- !u!1 &734489118 134 | GameObject: 135 | m_ObjectHideFlags: 0 136 | m_PrefabParentObject: {fileID: 0} 137 | m_PrefabInternal: {fileID: 0} 138 | serializedVersion: 4 139 | m_Component: 140 | - 4: {fileID: 734489123} 141 | - 20: {fileID: 734489122} 142 | - 92: {fileID: 734489121} 143 | - 124: {fileID: 734489120} 144 | - 81: {fileID: 734489119} 145 | m_Layer: 0 146 | m_Name: Main Camera 147 | m_TagString: MainCamera 148 | m_Icon: {fileID: 0} 149 | m_NavMeshLayer: 0 150 | m_StaticEditorFlags: 0 151 | m_IsActive: 1 152 | --- !u!81 &734489119 153 | AudioListener: 154 | m_ObjectHideFlags: 0 155 | m_PrefabParentObject: {fileID: 0} 156 | m_PrefabInternal: {fileID: 0} 157 | m_GameObject: {fileID: 734489118} 158 | m_Enabled: 1 159 | --- !u!124 &734489120 160 | Behaviour: 161 | m_ObjectHideFlags: 0 162 | m_PrefabParentObject: {fileID: 0} 163 | m_PrefabInternal: {fileID: 0} 164 | m_GameObject: {fileID: 734489118} 165 | m_Enabled: 1 166 | --- !u!92 &734489121 167 | Behaviour: 168 | m_ObjectHideFlags: 0 169 | m_PrefabParentObject: {fileID: 0} 170 | m_PrefabInternal: {fileID: 0} 171 | m_GameObject: {fileID: 734489118} 172 | m_Enabled: 1 173 | --- !u!20 &734489122 174 | Camera: 175 | m_ObjectHideFlags: 0 176 | m_PrefabParentObject: {fileID: 0} 177 | m_PrefabInternal: {fileID: 0} 178 | m_GameObject: {fileID: 734489118} 179 | m_Enabled: 1 180 | serializedVersion: 2 181 | m_ClearFlags: 1 182 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} 183 | m_NormalizedViewPortRect: 184 | serializedVersion: 2 185 | x: 0 186 | y: 0 187 | width: 1 188 | height: 1 189 | near clip plane: 0.3 190 | far clip plane: 1000 191 | field of view: 60 192 | orthographic: 0 193 | orthographic size: 5 194 | m_Depth: -1 195 | m_CullingMask: 196 | serializedVersion: 2 197 | m_Bits: 4294967295 198 | m_RenderingPath: -1 199 | m_TargetTexture: {fileID: 0} 200 | m_TargetDisplay: 0 201 | m_TargetEye: 3 202 | m_HDR: 0 203 | m_OcclusionCulling: 1 204 | m_StereoConvergence: 10 205 | m_StereoSeparation: 0.022 206 | m_StereoMirrorMode: 0 207 | --- !u!4 &734489123 208 | Transform: 209 | m_ObjectHideFlags: 0 210 | m_PrefabParentObject: {fileID: 0} 211 | m_PrefabInternal: {fileID: 0} 212 | m_GameObject: {fileID: 734489118} 213 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 214 | m_LocalPosition: {x: 0, y: 1, z: -10} 215 | m_LocalScale: {x: 1, y: 1, z: 1} 216 | m_Children: [] 217 | m_Father: {fileID: 0} 218 | m_RootOrder: 1 219 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 220 | --- !u!1 &1773092979 221 | GameObject: 222 | m_ObjectHideFlags: 0 223 | m_PrefabParentObject: {fileID: 0} 224 | m_PrefabInternal: {fileID: 0} 225 | serializedVersion: 4 226 | m_Component: 227 | - 4: {fileID: 1773092982} 228 | - 108: {fileID: 1773092981} 229 | m_Layer: 0 230 | m_Name: Directional Light 231 | m_TagString: Untagged 232 | m_Icon: {fileID: 0} 233 | m_NavMeshLayer: 0 234 | m_StaticEditorFlags: 0 235 | m_IsActive: 1 236 | --- !u!108 &1773092981 237 | Light: 238 | m_ObjectHideFlags: 0 239 | m_PrefabParentObject: {fileID: 0} 240 | m_PrefabInternal: {fileID: 0} 241 | m_GameObject: {fileID: 1773092979} 242 | m_Enabled: 1 243 | serializedVersion: 7 244 | m_Type: 1 245 | m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} 246 | m_Intensity: 1 247 | m_Range: 10 248 | m_SpotAngle: 30 249 | m_CookieSize: 10 250 | m_Shadows: 251 | m_Type: 2 252 | m_Resolution: -1 253 | m_Strength: 1 254 | m_Bias: 0.05 255 | m_NormalBias: 0.4 256 | m_NearPlane: 0.2 257 | m_Cookie: {fileID: 0} 258 | m_DrawHalo: 0 259 | m_Flare: {fileID: 0} 260 | m_RenderMode: 0 261 | m_CullingMask: 262 | serializedVersion: 2 263 | m_Bits: 4294967295 264 | m_Lightmapping: 4 265 | m_AreaSize: {x: 1, y: 1} 266 | m_BounceIntensity: 1 267 | m_ShadowRadius: 0 268 | m_ShadowAngle: 0 269 | --- !u!4 &1773092982 270 | Transform: 271 | m_ObjectHideFlags: 0 272 | m_PrefabParentObject: {fileID: 0} 273 | m_PrefabInternal: {fileID: 0} 274 | m_GameObject: {fileID: 1773092979} 275 | m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} 276 | m_LocalPosition: {x: 0, y: 3, z: 0} 277 | m_LocalScale: {x: 1, y: 1, z: 1} 278 | m_Children: [] 279 | m_Father: {fileID: 0} 280 | m_RootOrder: 2 281 | m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} 282 | -------------------------------------------------------------------------------- /Assets/Timers/Example/test.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 54f7720cb4277694b9b382703a233c06 3 | timeCreated: 1461235188 4 | licenseType: Free 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Timers/Special.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9d9ca31be44594a4d88ed5b9f3b96029 3 | folderAsset: yes 4 | timeCreated: 1473340860 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Timers/Special/Ability.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System; 4 | 5 | /// 6 | /// Object that is used to control if action can be fired or not based on internal timer. 7 | /// ON cooldown - means you are cooling down the ability and cant use it yet 8 | /// OFF cooldown - means you finised cooling down and are ready to use it 9 | /// 10 | /// 11 | /// USAGE 12 | /// 1. Create Cooldown object with a constructor and provide starting parameters 13 | /// 2. Use available events to specify cooldown functionality 14 | /// 3. Call "Use" method for "casting" something 15 | /// 4. When not needed anymore, use Destroy 16 | /// 5. parameters are read only, if you need to modify cooldown on runtime, create new one 17 | /// 18 | [Serializable] 19 | public class Ability { 20 | 21 | Timer cooldown_timer; 22 | Timer cast_timer; 23 | 24 | /// 25 | /// What happens right the moment we start action, ignoring the cast time/delay 26 | /// 27 | public event Action onStart; 28 | /// 29 | /// What will happen if cooldown allows action 30 | /// 31 | public event Action onCast; 32 | /// 33 | /// What happens after cooldown ends 34 | /// 35 | public event Action onOffCooldown; 36 | 37 | /// 38 | /// When cancel was explicitly called 39 | /// 40 | public event Action onCancel; 41 | 42 | /// 43 | /// For errors and other purposes 44 | /// 45 | public string name { get; private set; } 46 | 47 | /// 48 | /// Actual cooldown time 49 | /// 50 | public float cooldown_time { get; private set; } 51 | public float cooldown_left { get; private set; } 52 | 53 | public CooldownType cooldowntype; 54 | 55 | /// 56 | /// When does the cooldown start? 57 | /// 58 | public enum CooldownType 59 | { 60 | /// 61 | /// Cooldown begins from the moment we Use this cooldown, not waiting for delay 62 | /// 63 | fromStart, 64 | /// 65 | /// Cooldown begins after the cast timer finished, right at cast point 66 | /// 67 | fromCastPoint 68 | } 69 | 70 | 71 | /// 72 | /// The time from start till actual cast, think of it as delay in which you play cast animation and you can cancel 73 | /// 74 | public float castTime{ get; private set; } 75 | 76 | /// 77 | /// Initialization of timer should happen AFTER first use 78 | /// 79 | bool firstUse; 80 | 81 | /// 82 | /// When we are on cooldown, we cant use action, when we are off the cooldown, means action is ready 83 | /// 84 | public bool OnCooldown { get; private set; } 85 | 86 | /// 87 | /// Are we currently casting this ability? 88 | /// 89 | public bool isCasting { get; private set; } 90 | /// 91 | /// Is the ability completely suspended? (muted/stunned/frozen cooldown/disabled) 92 | /// 93 | public bool LockCasting { get; set; } 94 | 95 | bool has_cast_time; 96 | 97 | public Ability(string _name, float _cooldown_time, float _cast_time, Action _onActivate, CooldownType _type) 98 | { 99 | if(_onActivate == null) 100 | { 101 | Debug.LogError("Tried to create ability without callback" + name); 102 | return; 103 | } 104 | if (_cooldown_time <= 0f) 105 | { 106 | Debug.LogError("Resulting cooldown for " + _name + " is less or equal to zero, which is incorrect."); 107 | Debug.Break(); 108 | } 109 | //we treat ability as immutable object, so we only accept the callback in constructor 110 | onCast = _onActivate; 111 | //use for error reports and other things 112 | name = _name; 113 | //do we have a cast time? 114 | has_cast_time = _cast_time > 0f ? true : false; 115 | //if yes, create cast timer 116 | if (has_cast_time && cast_timer == null) 117 | { 118 | cast_timer = Timer.Countdown(_cast_time, actual_cast).Pause(); 119 | } 120 | 121 | cooldown_time = _cooldown_time; 122 | //switch (_type) 123 | //{ 124 | // case CooldownType.fromStart: 125 | // cooldown_time = _cooldown_time + _cast_time; 126 | // break; 127 | // case CooldownType.fromCastPoint: 128 | // cooldown_time = _cooldown_time; 129 | // break; 130 | // default: 131 | // break; 132 | //} 133 | 134 | castTime = _cast_time; 135 | cooldowntype = _type; 136 | firstUse = true; 137 | } 138 | 139 | /// 140 | /// This will activate attached action 141 | /// 142 | public bool Use() 143 | { 144 | if (!OnCooldown && !LockCasting) 145 | { 146 | activate(); 147 | return true; 148 | } 149 | else 150 | return false; 151 | } 152 | 153 | /// 154 | /// this activates attached action 155 | /// 156 | void activate() 157 | { 158 | if (onStart != null) 159 | onStart(); 160 | //on first use we Activate, and create a cooldown timer 161 | if (firstUse) 162 | { 163 | if (has_cast_time && cooldowntype == CooldownType.fromStart) 164 | cooldown_timer = Timer.Countdown(cooldown_time + castTime, put_offcooldown); 165 | else 166 | cooldown_timer = Timer.Countdown(cooldown_time, put_offcooldown); 167 | 168 | cooldown_timer.OnUpdate += () => cooldown_left = cooldown_timer.TimeLeft; 169 | //Dont let the pool reclaim this timer 170 | cooldown_timer.DontDisposeOnComplete = true; 171 | firstUse = false; 172 | } 173 | 174 | if (has_cast_time) 175 | { 176 | isCasting = true; 177 | if (cooldowntype == CooldownType.fromStart) 178 | { 179 | //we already are on cooldown, from the start of animation 180 | PutOnCooldown(); 181 | } 182 | //when cast timer countdown finished it will cast 183 | cast_timer.Unpause(); 184 | return; 185 | } 186 | 187 | else 188 | { 189 | actual_cast(); 190 | PutOnCooldown(); 191 | } 192 | } 193 | 194 | /// 195 | /// If you are currently casting will go back to start of the ability 196 | /// 197 | public void CancelCast() 198 | { 199 | if (isCasting) 200 | { 201 | if (onCancel != null) 202 | onCancel(); 203 | //reset the cast timer 204 | if (has_cast_time) 205 | cast_timer.Reset().Pause(); 206 | } 207 | } 208 | 209 | void actual_cast() 210 | { 211 | onCast(); 212 | isCasting = false; 213 | //reset the cast timer 214 | if (has_cast_time) 215 | cast_timer.Reset().Pause(); 216 | } 217 | /// 218 | /// Skips cast and goes straight to cooldown, use when you need to "break" the spell with another thing (like stun) 219 | /// 220 | public void PutOnCooldown() 221 | { 222 | if(firstUse || OnCooldown) 223 | { 224 | Debug.Log(name + "Already on cooldown"); 225 | return; 226 | } 227 | OnCooldown = true; 228 | cooldown_timer.Unpause(); 229 | 230 | } 231 | 232 | void reset() 233 | { 234 | if (has_cast_time) 235 | cast_timer.Reset().Pause(); 236 | OnCooldown = isCasting = false; 237 | cooldown_timer.Reset().Pause(); 238 | } 239 | 240 | /// 241 | /// "deactivates" or rather, resets the cooldown 242 | /// 243 | void put_offcooldown() 244 | { 245 | //Event raised when cooldown stops 246 | if (onOffCooldown != null) 247 | onOffCooldown(); 248 | OnCooldown = false; 249 | cooldown_timer.Reset().Pause(); 250 | } 251 | 252 | 253 | void Destroy() 254 | { 255 | cast_timer.Destroy(); 256 | cooldown_timer.Destroy(); 257 | } 258 | 259 | } 260 | -------------------------------------------------------------------------------- /Assets/Timers/Special/Ability.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dbb0cfcfc1d5b0b488ff211cc96b4358 3 | timeCreated: 1473340861 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Timers/Timer.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System; 5 | /// 6 | /// Timer is both static pool manager and dynamic DI container for concrete behaviors 7 | /// 8 | public partial class Timer 9 | { 10 | /// 11 | /// Implementers create behavior 12 | /// 13 | public interface ITimerBehavior 14 | { 15 | void Initialize(); 16 | void Update(float deltaTime); 17 | } 18 | 19 | 20 | public bool Paused { get; private set; } 21 | //DI defines what kind of timer this is 22 | ITimerBehavior behavior; 23 | //This base is shared between all types of timers 24 | TimerBehaviorBase behaviorBase; 25 | //Which time delta we are using for this timer 26 | TimeDeltaType type = TimeDeltaType.TimeScaleDependent; 27 | public TimeDeltaType timeDeltaType { get { return type; } } 28 | public enum TimeDeltaType { TimeScaleDependent, TimeScaleIndependent } 29 | //Event signaling when some timer finished work and is ready to be released 30 | event Action OnStopped; 31 | public event Action OnUpdate; 32 | public bool WasDestroyed { get; private set; } 33 | public bool DontDisposeOnComplete { get; set; } 34 | 35 | public float TimePassedTotal { get; private set; } 36 | public float TimePassed { get; private set; } 37 | public float TimeLeft { get; private set; } 38 | /// 39 | /// Not all timer have one fixed interval, this is the first "value" the timer will use, Countdown will use it as countdown time, Repeater will use it as 40 | /// main interval between repeats and so on 41 | /// 42 | public float MainInterval 43 | { 44 | get { return behaviorBase.MainInterval; } 45 | set { behaviorBase.MainInterval = value; } 46 | } 47 | /// 48 | /// Not all timers return this, how many cycles have passed 49 | /// 50 | /// 51 | public float ElapsedCycles { get { return behaviorBase.ElapsedCycles; } } 52 | 53 | void Update(float REAL_DELTA, float TIMESCALE_DELTA) 54 | { 55 | //skip the ones that were completed, works with DontDisposeOnComplete flag 56 | if (behaviorBase.Completed) 57 | return; 58 | //first check for potential problems 59 | behaviorBase.CheckErrors(); 60 | 61 | if (type == TimeDeltaType.TimeScaleDependent) 62 | behavior.Update(TIMESCALE_DELTA); 63 | else 64 | behavior.Update(REAL_DELTA); 65 | 66 | TimePassedTotal = behaviorBase.TotalTimeActive; 67 | TimePassed = behaviorBase.TimePassed; 68 | TimeLeft = MainInterval - TimePassed; 69 | 70 | if (OnUpdate != null) 71 | OnUpdate(); 72 | //Notify pool if we completed work 73 | if (behaviorBase.Completed) 74 | { 75 | if (DontDisposeOnComplete) 76 | return; 77 | OnStopped(this); 78 | return; 79 | } 80 | } 81 | 82 | 83 | //again shortening common actions 84 | Timer registerBehavior(ITimerBehavior behav) 85 | { 86 | behavior = behav; 87 | behaviorBase = (TimerBehaviorBase)behavior; 88 | behaviorBase.timer = this; 89 | return this; 90 | } 91 | 92 | Timer SetBehavior() where T : TimerBehaviorBase, new() 93 | { 94 | Type t = typeof(T); 95 | ITimerBehavior behav = null; 96 | if (TimerManager.behaviors.ContainsKey(t)) 97 | { 98 | List list = TimerManager.behaviors[t]; 99 | if (list.Count > 0) 100 | { 101 | behav = list[0]; 102 | list.Remove(behav); 103 | } 104 | } 105 | if (behav == null) 106 | behav = (ITimerBehavior)new T(); 107 | 108 | registerBehavior(behav); 109 | return this; 110 | } 111 | 112 | public void Destroy() 113 | { 114 | TimerManager.ReleaseTimer(this); 115 | } 116 | 117 | 118 | /// 119 | /// Do we use Time.deltaTime OR Time.unscaledTimeDelta 120 | /// unscaled means not affected by Time scale, by default all timers ARE affected by timescale 121 | /// 122 | /// 123 | /// 124 | public Timer SetIgnoreTimeScale(bool ignoreTimeScale) 125 | { 126 | type = ignoreTimeScale ? TimeDeltaType.TimeScaleIndependent : TimeDeltaType.TimeScaleDependent; 127 | return this; 128 | } 129 | 130 | 131 | public Timer SetCallbacks(Action c1) 132 | { 133 | behaviorBase.SetCallbacks(c1, null, null, null); 134 | return this; 135 | } 136 | 137 | public Timer SetCallbacks(Action c1, Action c2) 138 | { 139 | behaviorBase.SetCallbacks(c1, c2, null, null); 140 | return this; 141 | } 142 | 143 | public Timer SetCallbacks(Action c1, Action c2, Action c3) 144 | { 145 | behaviorBase.SetCallbacks(c1, c2, c3, null); 146 | return this; 147 | } 148 | 149 | public Timer SetCallbacks(Action c1, Action c2, Action c3, Action c4) 150 | { 151 | behaviorBase.SetCallbacks(c1, c2, c3, c4); 152 | return this; 153 | } 154 | 155 | public Timer Reset() 156 | { 157 | behaviorBase.ResetTime(); 158 | return this; 159 | } 160 | 161 | public Timer Pause() 162 | { 163 | Paused = true; 164 | return this; 165 | } 166 | 167 | public Timer Unpause() 168 | { 169 | Paused = false; 170 | return this; 171 | } 172 | 173 | /// 174 | /// We use this class to create timer types. We use its variables in concrete implementations, as per implementation. 175 | /// 176 | /// 177 | public class TimerBehaviorBase 178 | { 179 | 180 | public bool Completed { get; protected set; } 181 | public Timer timer; 182 | 183 | //How long the timer is UP (with all the pauses, resets, basically how long it lives since taken from pool) 184 | public float TotalTimeActive { get; protected set; } 185 | //Implementers can use these variables as they need 186 | public float TimePassed { get; protected set; } 187 | //Internally used floats 188 | protected float f1, f2, f3, f4; 189 | //callbacks 190 | protected Action c1, c2, c3, c4; 191 | //callbacks with parameters 192 | protected Action paramC1, paramC2; 193 | //parameters array 194 | protected object[] parameters; 195 | protected bool hasParameters; 196 | /// 197 | /// optional depends on implementation 198 | /// 199 | public int ElapsedCycles { get; protected set; } 200 | //use this to expose your "main" driving value of the timer 201 | public float MainInterval { get { return f1; } set { f1 = value; } } 202 | public TimerBehaviorBase ResetEntity() 203 | { 204 | ElapsedCycles = 0; 205 | TimePassed = 0f; 206 | TotalTimeActive = 0f; 207 | MainInterval = 0f; 208 | Completed = false; 209 | 210 | parameters = null; 211 | c1 = c2 = c3 = c4 = null; 212 | hasParameters = false; 213 | paramC1 = paramC2 = null; 214 | f1 = f2 = f3 = f4 = 0f; 215 | timer = null; 216 | 217 | 218 | return this; 219 | } 220 | public void CheckErrors() 221 | { 222 | if (!hasParameters && c1 == null && c2 == null && c3 == null && c4 == null) 223 | { 224 | Debug.LogError("Timer cant have zero callbacks, such timer is useless. Make sure to add a callback before the timer" + 225 | "starts execution"); 226 | Debug.Break(); 227 | } 228 | if (hasParameters && paramC1 == null && paramC2 == null) 229 | { 230 | Debug.LogError("PARAMETER Timer cant have zero parameter callbacks, such timer is useless. Make sure to add a callback before the timer" + 231 | "starts execution"); 232 | Debug.Break(); 233 | } 234 | } 235 | 236 | public TimerBehaviorBase SetCallbacks(Action one, Action two, Action three, Action four) 237 | { 238 | c1 = one; 239 | c2 = two; 240 | c3 = three; 241 | c4 = four; 242 | return this; 243 | } 244 | 245 | public TimerBehaviorBase SetCallbacksWithParameters(Action pc1, Action pc2, object[] p) 246 | { 247 | paramC1 = pc1; 248 | paramC2 = pc2; 249 | parameters = p; 250 | hasParameters = true; 251 | return this; 252 | } 253 | 254 | public TimerBehaviorBase SetFloats(float one, float two, float three, float four) 255 | { 256 | //Typically in most scenarios first float will be our main "driving" value for the timer. 257 | MainInterval = one; 258 | 259 | f1 = one; 260 | f2 = two; 261 | f3 = three; 262 | f4 = four; 263 | return this; 264 | } 265 | 266 | public TimerBehaviorBase ResetTime() 267 | { 268 | TimePassed = 0f; 269 | Completed = false; 270 | return this; 271 | } 272 | } 273 | 274 | /// 275 | /// This class handles updating and disposing of timers 276 | /// 277 | public static class TimerManager 278 | { 279 | /// 280 | /// Behavior objects pool 281 | /// 282 | public static Dictionary> behaviors = new Dictionary>(); 283 | public static List workingTimers = new List(); 284 | public static List freeTimers = new List(); 285 | public static List toRemove = new List(); 286 | 287 | public static void POLL_TIMER_DATA(TimerHelper.TimerHelperData data) 288 | { 289 | data.FreeTimers = freeTimers.Count; 290 | data.WorkingTimers = workingTimers.Count; 291 | data.AllTimers = data.FreeTimers + data.WorkingTimers; 292 | } 293 | 294 | public static void UpdateAllTimers() 295 | { 296 | int c = workingTimers.Count; 297 | //update all timers 298 | for (int i = 0; i < c; i++) 299 | { 300 | if (!workingTimers[i].WasDestroyed && !workingTimers[i].Paused) 301 | workingTimers[i].Update(Time.unscaledDeltaTime, Time.deltaTime); 302 | } 303 | 304 | c = toRemove.Count; 305 | if (c > 0) 306 | { 307 | for (int i = 0; i < c; i++) 308 | { 309 | workingTimers.Remove(toRemove[i]); 310 | } 311 | toRemove.Clear(); 312 | } 313 | } 314 | 315 | //attempt to get used timer from pool or make new 316 | public static Timer getTimer() 317 | { 318 | Timer t = null; 319 | if (freeTimers.Count == 0) 320 | { 321 | t = newTimer(); 322 | } 323 | else 324 | { 325 | t = freeTimers[0]; 326 | freeTimers.Remove(t); 327 | } 328 | //Just to make sure our Helper appears when we need it 329 | if (TimerHelper.instance == null) 330 | { } 331 | registerTimer(t); 332 | return t; 333 | } 334 | // avoiding boilerplate 335 | public static Timer newTimer() 336 | { 337 | Timer t = new Timer(); 338 | //easy way to get notified of which timer was stopped 339 | t.OnStopped += ReleaseTimer; 340 | return t; 341 | } 342 | 343 | public static void registerTimer(Timer timer) 344 | { 345 | timer.WasDestroyed = false; 346 | workingTimers.Add(timer); 347 | } 348 | //We do this at the end of timer lifecycle or when we destroy it 349 | public static void ReleaseTimer(Timer timer) 350 | { 351 | if (timer.WasDestroyed) 352 | return; 353 | freeTimers.Add(timer); 354 | 355 | //we use type as key to cache our behaviors 356 | Type btype = timer.behavior.GetType(); 357 | if (!behaviors.ContainsKey(btype)) 358 | behaviors.Add(btype, new List()); 359 | behaviors[btype].Add(timer.behavior); 360 | 361 | timer.Paused = false; 362 | timer.behavior = null; 363 | timer.behaviorBase.ResetEntity(); 364 | timer.WasDestroyed = true; 365 | toRemove.Add(timer); 366 | } 367 | } 368 | 369 | public static void KillAll() 370 | { 371 | int c = TimerManager.workingTimers.Count; 372 | for (int i = 0; i < c; i++) 373 | { 374 | TimerManager.workingTimers[i].Destroy(); 375 | } 376 | } 377 | 378 | } 379 | -------------------------------------------------------------------------------- /Assets/Timers/Timer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 174d0f3118fc88244bf64b012313c476 3 | timeCreated: 1473339839 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Timers/TimerHelper.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System; 5 | 6 | /// 7 | /// Acts a link between Timer class and Unity Update method. 8 | /// 9 | public class TimerHelper : MonoBehaviour 10 | { 11 | /// 12 | /// Viewing timers can be costly, do we want to pause polling? 13 | /// 14 | public bool UpdateViewer = true; 15 | public TimerHelperData viewer = new TimerHelperData(); 16 | 17 | private static TimerHelper _instance; 18 | public static TimerHelper instance 19 | { 20 | get 21 | { 22 | if (_instance == null) 23 | { 24 | _instance = FindObjectOfType(); 25 | if (_instance == null) 26 | { 27 | _instance = CreateNew(); 28 | } 29 | 30 | } 31 | return _instance; 32 | } 33 | } 34 | 35 | static TimerHelper CreateNew() 36 | { 37 | GameObject go = new GameObject("TimerHelper"); 38 | return go.AddComponent(); 39 | } 40 | 41 | void Update() 42 | { 43 | Timer.TimerManager.UpdateAllTimers(); 44 | if (UpdateViewer) 45 | Timer.TimerManager.POLL_TIMER_DATA(viewer); 46 | } 47 | 48 | [System.Serializable] 49 | public class TimerHelperData 50 | { 51 | public int FreeTimers; 52 | public int WorkingTimers; 53 | public int AllTimers; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Assets/Timers/TimerHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6e5ad7237561e434a81690b0e10a6374 3 | timeCreated: 1473339839 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Timers/Timer_Behaviors.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System; 4 | 5 | public partial class Timer 6 | { 7 | 8 | /// 9 | /// Create new Repeater type timer 10 | /// 11 | /// 12 | /// will happen each interval 13 | /// 14 | public static Timer Repeater(float interval, Action callback) 15 | { 16 | Timer timer = TimerManager.getTimer(); 17 | timer.SetBehavior(); 18 | timer.behaviorBase 19 | .SetFloats(interval, 0, 0, 0) 20 | .SetCallbacks(callback, null, null, null); 21 | timer.behavior.Initialize(); 22 | return timer; 23 | } 24 | 25 | 26 | /// 27 | /// Creates Repeater that passes parameters to a method on tick. 28 | /// 29 | /// 30 | /// 31 | /// 32 | /// 33 | public static Timer RepeaterParam(float interval, Action callback, object[] parameters) 34 | { 35 | Timer timer = TimerManager.getTimer(); 36 | timer.SetBehavior(); 37 | timer.behaviorBase 38 | .SetFloats(interval, 0, 0, 0) 39 | .SetCallbacksWithParameters(callback, null, parameters); 40 | timer.behavior.Initialize(); 41 | if (timer.behaviorBase.Completed) 42 | { 43 | Debug.Log(1); 44 | } 45 | return timer; 46 | } 47 | 48 | private class RepeaterBehavior : TimerBehaviorBase, ITimerBehavior 49 | { 50 | 51 | public void Initialize() 52 | { 53 | 54 | } 55 | 56 | public void Update(float deltaTime) 57 | { 58 | TimePassed += deltaTime; 59 | TotalTimeActive += deltaTime; 60 | 61 | if (TimePassed > MainInterval) 62 | { 63 | if (hasParameters) 64 | paramC1(parameters); 65 | else 66 | c1(); 67 | TimePassed = 0f + (TimePassed % MainInterval); 68 | } 69 | } 70 | } 71 | 72 | /// 73 | /// Create new Repeater type timer 74 | /// 75 | /// 76 | /// will happen each interval 77 | /// 78 | public static Timer Countdown(float exitTime, Action callback) 79 | { 80 | Timer timer = TimerManager.getTimer(); 81 | timer.SetBehavior(); 82 | timer.behaviorBase 83 | .SetFloats(exitTime, 0, 0, 0) 84 | .SetCallbacks(callback, null, null, null); 85 | timer.behavior.Initialize(); 86 | return timer; 87 | } 88 | 89 | private class CountdownBehavior : TimerBehaviorBase, ITimerBehavior 90 | { 91 | float exitTime; 92 | public void Initialize() 93 | { 94 | exitTime = f1; 95 | } 96 | 97 | public void Update(float deltaTime) 98 | { 99 | TimePassed += deltaTime; 100 | TotalTimeActive += deltaTime; 101 | 102 | if (TimePassed > exitTime) 103 | { 104 | Completed = true; 105 | c1(); 106 | } 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /Assets/Timers/Timer_Behaviors.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 160da7dc8a09ba94d974216686110863 3 | timeCreated: 1473339839 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | License: 2 | 3 | Project is released under MIT license Copyright (c) 2016 Alexander Antonov (pointcache) and contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /LICENSE.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0ec894ada1c26e14eaed3f9f3fe478e1 3 | timeCreated: 1461222543 4 | licenseType: Free 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointcache/Unity3d-Timers/05dec091957bc950f3b172caf1edcac9efb01f33/ProjectSettings/AudioManager.asset -------------------------------------------------------------------------------- /ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointcache/Unity3d-Timers/05dec091957bc950f3b172caf1edcac9efb01f33/ProjectSettings/ClusterInputManager.asset -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointcache/Unity3d-Timers/05dec091957bc950f3b172caf1edcac9efb01f33/ProjectSettings/DynamicsManager.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointcache/Unity3d-Timers/05dec091957bc950f3b172caf1edcac9efb01f33/ProjectSettings/EditorBuildSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointcache/Unity3d-Timers/05dec091957bc950f3b172caf1edcac9efb01f33/ProjectSettings/EditorSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointcache/Unity3d-Timers/05dec091957bc950f3b172caf1edcac9efb01f33/ProjectSettings/GraphicsSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointcache/Unity3d-Timers/05dec091957bc950f3b172caf1edcac9efb01f33/ProjectSettings/InputManager.asset -------------------------------------------------------------------------------- /ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointcache/Unity3d-Timers/05dec091957bc950f3b172caf1edcac9efb01f33/ProjectSettings/NavMeshAreas.asset -------------------------------------------------------------------------------- /ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointcache/Unity3d-Timers/05dec091957bc950f3b172caf1edcac9efb01f33/ProjectSettings/NetworkManager.asset -------------------------------------------------------------------------------- /ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointcache/Unity3d-Timers/05dec091957bc950f3b172caf1edcac9efb01f33/ProjectSettings/Physics2DSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointcache/Unity3d-Timers/05dec091957bc950f3b172caf1edcac9efb01f33/ProjectSettings/ProjectSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 5.4.0f3 2 | m_StandardAssetsVersion: 0 3 | -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointcache/Unity3d-Timers/05dec091957bc950f3b172caf1edcac9efb01f33/ProjectSettings/QualitySettings.asset -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointcache/Unity3d-Timers/05dec091957bc950f3b172caf1edcac9efb01f33/ProjectSettings/TagManager.asset -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointcache/Unity3d-Timers/05dec091957bc950f3b172caf1edcac9efb01f33/ProjectSettings/TimeManager.asset -------------------------------------------------------------------------------- /ProjectSettings/UnityAdsSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointcache/Unity3d-Timers/05dec091957bc950f3b172caf1edcac9efb01f33/ProjectSettings/UnityAdsSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pointcache/Unity3d-Timers/05dec091957bc950f3b172caf1edcac9efb01f33/ProjectSettings/UnityConnectSettings.asset -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![License MIT](https://img.shields.io/badge/license-MIT-green.svg) 2 | 3 | # Unity3d-Timers 4 | Timer class with various behaviors 5 | 6 | About: 7 | Have a system allowing to easily create and extend complex timer behaviors. 8 | 9 | Usage: 10 | 11 | ``` csharp 12 | //Start simple repeater 13 | Timer.Repeater(5f, () => Debug.Log("Repeater test")); 14 | //Start countdown and call Draw in 2.5 seconds 15 | Timer.Countdown(2.5f, Draw); 16 | ``` 17 | 18 | Concept: 19 | A manager class pools and constructs new timers, timer store up to 4 handlers, and arbitrarely raise events in 20 | concrete implementation. 21 | 22 | ``` csharp 23 | private class CountdownBehavior : TimerBehaviorBase, ITimerBehavior 24 | { 25 | float exitTime; 26 | public void Initialize() 27 | { 28 | exitTime = f1; 29 | } 30 | 31 | public void Update(float deltaTime) 32 | { 33 | TimePassed += deltaTime; 34 | TotalTimeActive += deltaTime; 35 | 36 | if (TimePassed > exitTime) 37 | { 38 | Completed = true; 39 | c1(); 40 | } 41 | } 42 | } 43 | 44 | ``` 45 | 46 | Countdown inherits TimerBehaviorBase and implements ITimerBehavior. 47 | On top of that only concrete behavior in implemented that uses data and callbacks provided in constructor: 48 | 49 | ``` csharp 50 | public static Timer Countdown(float exitTime, Action callback) 51 | { 52 | Timer timer = TimerManager.getTimer(); 53 | timer.SetBehavior(); 54 | timer.behaviorBase 55 | .SetFloats(exitTime, 0, 0, 0) 56 | .SetCallbacks(callback, null, null, null); 57 | timer.behavior.Initialize(); 58 | return timer; 59 | } 60 | 61 | ``` 62 | 63 | as you can see you can set 4 floats, and 4 callbacks and use them in your implementation of behavior as you like. 64 | Examples 65 | ![](http://i.imgur.com/3KabwIi.png) 66 | 67 | For concrete real example look at Ability class, 68 | it implements typical game ability, with cooldown. 69 | -------------------------------------------------------------------------------- /Test.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ea427eeaf13fc704da463ead77768806 3 | folderAsset: yes 4 | timeCreated: 1468112955 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Timer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 861072e7a49a1a04d8a437f2e7a40965 3 | timeCreated: 1468112955 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /TimerHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: adb0408336cd61949a850c022cdba804 3 | timeCreated: 1468112956 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Timer_Behaviors.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 73a0755d2e0c21c489ebc2f7b43a148a 3 | timeCreated: 1468112955 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | --------------------------------------------------------------------------------