Statistics
| Branch: | Tag: | Revision:

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
}