root / Assets / Time of Day / Assets / Scripts / TOD_Time.cs @ 125:2f0ae0194ff2
History | View | Annotate | Download (6.7 kB)
1 | using UnityEngine; |
---|---|
2 | using System; |
3 | |
4 | /// Time iteration class. |
5 | /// |
6 | /// Component of the sky dome parent game object. |
7 | |
8 | public class TOD_Time : MonoBehaviour |
9 | { |
10 | /// Length of one day in minutes. |
11 | [Tooltip("Length of one day in minutes.")] |
12 | [TOD_Min(0f)] public float DayLengthInMinutes = 30; |
13 | |
14 | /// Progress time at runtime. |
15 | [Tooltip("Progress time at runtime.")] |
16 | public bool ProgressTime = true; |
17 | |
18 | /// Set the date to the current device date on start. |
19 | [Tooltip("Set the date to the current device date on start.")] |
20 | public bool UseDeviceDate = false; |
21 | |
22 | /// Set the time to the current device time on start. |
23 | [Tooltip("Set the time to the current device time on start.")] |
24 | public bool UseDeviceTime = false; |
25 | |
26 | /// Set the time to the current device time on start. |
27 | [Tooltip("Set the time to the current time in Boston on start.")] |
28 | public bool UseBostonTime = false; |
29 | |
30 | /// Apply the time curve when progressing time. |
31 | [Tooltip("Apply the time curve when progressing time.")] |
32 | public bool UseTimeCurve = false; |
33 | |
34 | /// Time progression curve. |
35 | [Tooltip("Time progression curve.")] |
36 | public AnimationCurve TimeCurve = AnimationCurve.Linear(0, 0, 24, 24); |
37 | |
38 | /// Fired whenever the minute value is incremented. |
39 | public event Action OnMinute; |
40 | |
41 | /// Fired whenever the hour value is incremented. |
42 | public event Action OnHour; |
43 | |
44 | /// Fired whenever the day value is incremented. |
45 | public event Action OnDay; |
46 | |
47 | /// Fired whenever the month value is incremented. |
48 | public event Action OnMonth; |
49 | |
50 | /// Fired whenever the year value is incremented. |
51 | public event Action OnYear; |
52 | |
53 | /// Fired whenever the sun rises. |
54 | public event Action OnSunrise; |
55 | |
56 | /// Fired whenever the sun sets. |
57 | public event Action OnSunset; |
58 | |
59 | private TOD_Sky sky; |
60 | private AnimationCurve timeCurve; |
61 | private AnimationCurve timeCurveInverse; |
62 | |
63 | /// Apply changes made to TimeCurve. |
64 | public void RefreshTimeCurve() |
65 | { |
66 | TimeCurve.preWrapMode = WrapMode.Clamp; |
67 | TimeCurve.postWrapMode = WrapMode.Clamp; |
68 | |
69 | ApproximateCurve(TimeCurve, out timeCurve, out timeCurveInverse); |
70 | |
71 | timeCurve.preWrapMode = WrapMode.Loop; |
72 | timeCurve.postWrapMode = WrapMode.Loop; |
73 | |
74 | timeCurveInverse.preWrapMode = WrapMode.Loop; |
75 | timeCurveInverse.postWrapMode = WrapMode.Loop; |
76 | } |
77 | |
78 | /// Apply the time curve to a time span. |
79 | /// \param deltaTime The time span to adjust. |
80 | /// \return The adjusted time span. |
81 | public float ApplyTimeCurve(float deltaTime) |
82 | { |
83 | float time = timeCurveInverse.Evaluate(sky.Cycle.Hour) + deltaTime; |
84 | deltaTime = timeCurve.Evaluate(time) - sky.Cycle.Hour; |
85 | |
86 | if (time >= 24) |
87 | { |
88 | deltaTime += ((int)time / 24) * 24; |
89 | } |
90 | else if (time < 0) |
91 | { |
92 | deltaTime += ((int)time / 24 - 1) * 24; |
93 | } |
94 | |
95 | return deltaTime; |
96 | } |
97 | |
98 | /// Add hours and fractions of hours to the current time. |
99 | /// \param hours The hours to add. |
100 | /// \param adjust Whether or not to apply the time curve. |
101 | public void AddHours(float hours, bool adjust = true) |
102 | { |
103 | if (UseTimeCurve && adjust) hours = ApplyTimeCurve(hours); |
104 | |
105 | var dateTimeOld = sky.Cycle.DateTime; |
106 | var dateTimeNew = dateTimeOld.AddHours(hours); |
107 | |
108 | sky.Cycle.DateTime = dateTimeNew; |
109 | |
110 | if (dateTimeNew.Year > dateTimeOld.Year) |
111 | { |
112 | if (OnYear != null) OnYear(); |
113 | if (OnMonth != null) OnMonth(); |
114 | if (OnDay != null) OnDay(); |
115 | if (OnHour != null) OnHour(); |
116 | if (OnMinute != null) OnMinute(); |
117 | } |
118 | else if (dateTimeNew.Month > dateTimeOld.Month) |
119 | { |
120 | if (OnMonth != null) OnMonth(); |
121 | if (OnDay != null) OnDay(); |
122 | if (OnHour != null) OnHour(); |
123 | if (OnMinute != null) OnMinute(); |
124 | } |
125 | else if (dateTimeNew.Day > dateTimeOld.Day) |
126 | { |
127 | if (OnDay != null) OnDay(); |
128 | if (OnHour != null) OnHour(); |
129 | if (OnMinute != null) OnMinute(); |
130 | } |
131 | else if (dateTimeNew.Hour > dateTimeOld.Hour) |
132 | { |
133 | if (OnHour != null) OnHour(); |
134 | if (OnMinute != null) OnMinute(); |
135 | } |
136 | else if (dateTimeNew.Minute > dateTimeOld.Minute) |
137 | { |
138 | if (OnMinute != null) OnMinute(); |
139 | } |
140 | |
141 | double oldHour = dateTimeOld.TimeOfDay.TotalHours; |
142 | double newHour = dateTimeNew.TimeOfDay.TotalHours; |
143 | |
144 | if (oldHour < sky.SunriseTime && newHour >= sky.SunriseTime) |
145 | { |
146 | if (OnSunrise != null) OnSunrise(); |
147 | } |
148 | |
149 | if (oldHour < sky.SunsetTime && newHour >= sky.SunsetTime) |
150 | { |
151 | if (OnSunset != null) OnSunset(); |
152 | } |
153 | } |
154 | |
155 | /// Add seconds and fractions of seconds to the current time. |
156 | /// \param seconds The seconds to add. |
157 | /// \param adjust Whether or not to apply the time curve. |
158 | public void AddSeconds(float seconds, bool adjust = true) |
159 | { |
160 | AddHours(seconds / 3600f); |
161 | } |
162 | |
163 | private void CalculateLinearTangents(Keyframe[] keys) |
164 | { |
165 | for (int i = 0; i < keys.Length; i++) |
166 | { |
167 | var key = keys[i]; |
168 | |
169 | if (i > 0) |
170 | { |
171 | var prev = keys[i-1]; |
172 | key.inTangent = (key.value - prev.value) / (key.time - prev.time); |
173 | } |
174 | |
175 | if (i < keys.Length-1) |
176 | { |
177 | var next = keys[i+1]; |
178 | key.outTangent = (next.value - key.value) / (next.time - key.time); |
179 | } |
180 | |
181 | keys[i] = key; |
182 | } |
183 | } |
184 | |
185 | private void ApproximateCurve(AnimationCurve source, out AnimationCurve approxCurve, out AnimationCurve approxInverse) |
186 | { |
187 | const float minstep = 0.01f; |
188 | |
189 | var approxCurveKeys = new Keyframe[25]; |
190 | var approxInverseKeys = new Keyframe[25]; |
191 | |
192 | float time = -minstep; |
193 | for (int i = 0; i < 25; i++) |
194 | { |
195 | time = Mathf.Max(time + minstep, source.Evaluate(i)); |
196 | |
197 | approxCurveKeys[i] = new Keyframe(i, time); |
198 | approxInverseKeys[i] = new Keyframe(time, i); |
199 | } |
200 | |
201 | CalculateLinearTangents(approxCurveKeys); |
202 | CalculateLinearTangents(approxInverseKeys); |
203 | |
204 | approxCurve = new AnimationCurve(approxCurveKeys); |
205 | approxInverse = new AnimationCurve(approxInverseKeys); |
206 | } |
207 | |
208 | protected void Awake() |
209 | { |
210 | sky = GetComponent<TOD_Sky>(); |
211 | |
212 | if (UseDeviceDate) |
213 | { |
214 | sky.Cycle.Year = DateTime.Now.Year; |
215 | sky.Cycle.Month = DateTime.Now.Month; |
216 | sky.Cycle.Day = DateTime.Now.Day; |
217 | } |
218 | |
219 | // ------> added to TOD plugin |
220 | if (UseBostonTime) |
221 | { |
222 | sky.Cycle.Hour = bostonTime(); |
223 | } |
224 | // <------ added to TOD plugin |
225 | |
226 | if (UseDeviceTime) |
227 | { |
228 | sky.Cycle.Hour = (float)DateTime.Now.TimeOfDay.TotalHours; |
229 | } |
230 | |
231 | |
232 | RefreshTimeCurve(); |
233 | } |
234 | |
235 | // ------> added to TOD plugin |
236 | public float bostonTime() |
237 | { |
238 | float bostonTime;// = 12f; |
239 | int month = (int)DateTime.Now.Month; |
240 | if(month>=3 && month <=11){ |
241 | bostonTime = (float)DateTime.UtcNow.TimeOfDay.TotalHours - 4f; |
242 | Debug.Log ("The time in Boston is now " + bostonTime + " hours (daylight savings)."); |
243 | } |
244 | else{ |
245 | bostonTime = (float)DateTime.UtcNow.TimeOfDay.TotalHours - 5f; |
246 | Debug.Log ("The time in Boston is now " + bostonTime + " hours."); |
247 | } |
248 | return bostonTime; |
249 | } |
250 | |
251 | public float getTime() |
252 | { |
253 | return sky.Cycle.Hour; |
254 | } |
255 | // <------ added to TOD plugin |
256 | |
257 | |
258 | protected void FixedUpdate() |
259 | { |
260 | if (ProgressTime && DayLengthInMinutes > 0) |
261 | { |
262 | const float oneDayInMinutes = 60 * 24; |
263 | |
264 | float timeFactor = oneDayInMinutes / DayLengthInMinutes; |
265 | |
266 | AddSeconds(Time.deltaTime * timeFactor); |
267 | } |
268 | } |
269 | } |