Unity: How to transfer time script to 24 hours and not decimals - c#

so I've found a script online for Unity that is a Day and Night cycle however it works in decimals, 0.1 to 1, however I want it to be 1 to 24.
The code I am using is below, I have tried fiddling around with the decimal values however I can't get it correct.
using UnityEngine;
using System.Collections;
public class DayNightCycle : MonoBehaviour {
public Light sun;
public float secondsInFullDay = 120f;
[Range(0,24)]
public float currentTimeOfDay = 0;
[HideInInspector]
public float timeMultiplier = 1f;
float sunInitialIntensity;
void Start() {
sunInitialIntensity = sun.intensity;
}
void Update() {
UpdateSun();
currentTimeOfDay += (Time.deltaTime / secondsInFullDay) * timeMultiplier;
if (currentTimeOfDay >= 24) {
currentTimeOfDay = 0;
}
}
void UpdateSun() {
sun.transform.localRotation = Quaternion.Euler((currentTimeOfDay * 360f) - 90, 170, 0);
float intensityMultiplier = 1;
if (currentTimeOfDay <= 0.23f || currentTimeOfDay >= 0.75f) {
intensityMultiplier = 0;
}
else if (currentTimeOfDay <= 0.25f) {
intensityMultiplier = Mathf.Clamp01((currentTimeOfDay - 0.23f) * (1 / 0.02f));
}
else if (currentTimeOfDay >= 0.73f) {
intensityMultiplier = Mathf.Clamp01(1 - ((currentTimeOfDay - 0.73f) * (1 / 0.02f)));
}
sun.intensity = sunInitialIntensity * intensityMultiplier;
}
}
The result I want is for the day and night cycle to work from 1 to 24 and not 0 to 1, so that there's 24 hours in the game, and that it's easier to modify when using a sleep script I've made.

To convert a value between 0 and 1 (interval [0, 1]) you just have to multiply by the size of your new interval then add the first value of your interval.
So if you have a variable value and want an interval: [MIN, MAX] the calculation is the following:
var newValue = (value * (MAX - MIN)) + MIN;
In you case you want the interval [1, 24] so it is:
var newValue = (value * 23) + 1;
Simple maths, hope it helps.

Related

C# Time Management (with Unity 2D)

I ran into a little issue whilst using C#/Unity in combination with a litte countdown timer. The countdown is working fine an as expected, as long as the number of total timeToDisplay is not too big (e.g. more than a day)
r/Unity2D - Asking for Help: Countdown strangely stops when there is too much remaining time
As you can see, the user has the possibility to add time to that countdown, which (again) works fine, until it's too much.
Using TextMeshPro and TextMeshPro-Buttons.
Image of Countdown + Buttons to add Seconds/Minutes/Hours/Days
However... here's the code:
using UnityEngine;
using TMPro;
public class Controller : MonoBehaviour
{
public float timeValue = 78000;
public TMP_Text timerText;
// I also tried FixedUpdate, but error still occured
void Update()
{
if (timeValue > 0)
{
timeValue -= Time.deltaTime;
}
else
{
timeValue = 0;
}
DisplayTime(timeValue);
}
void DisplayTime(float timeToDisplay)
{
float days = Mathf.FloorToInt(timeToDisplay / 86400);
timeToDisplay = timeToDisplay % 86400;
float hours = Mathf.FloorToInt(timeToDisplay / 3600);
timeToDisplay = timeToDisplay % 3600;
float minutes = Mathf.FloorToInt(timeToDisplay / 60);
timeToDisplay = timeToDisplay % 60;
float seconds = Mathf.FloorToInt(timeToDisplay);
if (seconds < 0)
{
seconds = 0;
}
timerText.text = string.Format("{0:00} days {1:00} hours {2:00} minutes {3:00} seconds", days, hours, minutes, seconds);
}
public void AddDay()
{
/* 86400 seconds/day */
timeValue += 86400;
}
public void AddHour()
{
/* 3600 seconds/hour */
timeValue += 3600;
}
public void AddMinute()
{
timeValue += 60;
}
public void AddSecond()
{
timeValue += 1;
}
}
Does anybody know what I'm missing here?
problem on here: timeValue -= Time.deltaTime , float have a little deviation
public float timeValue = 78000;
float beginTime = 0;
void Start()
{
beginTime = Time.time;
}
// I also tried FixedUpdate, but error still occured
void Update()
{
float usedTime = Time.time - beginTime;
if( timeValue - usedTime > 0 )
{
DisplayTime(timeValue - usedTime);
}
else
{
DisplayTime(0);
}
}

Unity - Trying to Calculate In-Game Time

So I wrote a day-night cycle script the other day and I have the sun/moon cycle working (its a really rough script, not perfect yet) but one of the other things I wanted to do was to be able to calculate the current time inside the game working off of that day/night cycle.
I have a ticker that is working so far but it is not scaling correctly to the percentage of the day.
Can anyone help me out with this because I think this is beyond my skillset with maths right now.
Basically I just want to solve the current time of day as relative to the % we are moving through the day/night cycle.
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
public class DayNightCycle : MonoBehaviour
{
public static DayNightCycle instance;
public Light sun, moon;
public float secondsInFullDay = 3600f;
[Range(0, 1)]
public float currentTimeOfDay = 0f;
[HideInInspector]
public float timeMultiplier = 1f;
float sunInitialIntensity;
public Camera mainCam;
public Material skyboxDay, skyBoxNight;
public float gameTime;
public float fSeconds;
public int totalSeconds, iSeconds, minutes, hours, days;
public int currentSecond, currentMinute, currentHour, currentDay;
public float previousTime;
private void Awake()
{
instance = this;
}
// Start is called before the first frame update
void Start()
{
sunInitialIntensity = sun.intensity;
}
// Update is called once per frame
void Update()
{
UpdateSun();
currentTimeOfDay += (Time.deltaTime / secondsInFullDay) * timeMultiplier;
if (currentTimeOfDay >= 1)
{
currentTimeOfDay = 0;
}
gameTime += Time.deltaTime;
// seconds / total seconds = percentage
// percentage * seconds = total seconds
// seconds = total seconds * percentage
totalSeconds = (int)gameTime;
fSeconds = (secondsInFullDay * currentTimeOfDay);
currentSecond = (int)fSeconds;
if (currentSecond >= 60)
IncrementMinutes();
if (currentMinute >= 60)
IncrementHours();
if (currentHour >= 24)
IncrementDays();
previousTime = (int)gameTime;
}
void UpdateSun()
{
sun.transform.localRotation = Quaternion.Euler((currentTimeOfDay * 360f) - 90, 170, 0);
moon.transform.localRotation = Quaternion.Euler((currentTimeOfDay * 360f) - 90, 170, 0);
float intensityMultiplier = 1f;
float moonIntensityMult = 0.025f;
if (currentTimeOfDay <= 0.23f || currentTimeOfDay >= 0.75f)
{
RenderSettings.skybox = skyBoxNight;
intensityMultiplier = 0f;
moonIntensityMult = 0.025f;
}
else if (currentTimeOfDay <= 0.25f)
{
RenderSettings.skybox = skyBoxNight;
intensityMultiplier = Mathf.Clamp01((currentTimeOfDay - 0.23f) * (1 / 0.02f));
moonIntensityMult = 0f;
}
else if (currentTimeOfDay >= 0.73f)
{
RenderSettings.skybox = skyboxDay;
intensityMultiplier = Mathf.Clamp01(1 - ((currentTimeOfDay - 0.73f) * (1 / 0.02f)));
moonIntensityMult = 0f;
}
sun.intensity = sunInitialIntensity * intensityMultiplier;
moon.intensity = moonIntensityMult;
}
public float GetTimeOfDayInSeconds
{
get { return currentTimeOfDay; }
set { return; }
}
void IncrementMinutes()
{
currentMinute++;
currentSecond = 0;
}
void IncrementHours()
{
currentHour++;
currentSecond = 0;
currentMinute = 0;
}
void IncrementDays()
{
currentDay++;
currentSecond = 0;
currentMinute = 0;
currentHour = 0;
}
}
I think keeping track of second, minute hour and increment each separtedly is not the right approach. You need to now the scale or proprotion factor between your game time and the real time, and handle the one time variable at once.
Find this trial function to obtain the sacaled time I think you need.
using System;
using UnityEngine;
public class DayNightCycle : MonoBehaviour {
// This is public to check with manual input if the obtained time is the one we expect.
// In the real method, this should not exist and should be calculated with the elapsed time of the game,
// commented belowin the getGameTime(int secodsDayDurationInGame) method
public double elapsedRealTime;
float startingGameTime;
DateTime startingGameDate;
private void Start() {
startingGameTime = Time.time;
startingGameDate = DateTime.Now; // choose the starting date you like
}
private float secondsOfARealDay = 24 * 60 * 60;
DateTime getGameTime(int secodsDayDurationInGame) {
float scaledElapsedSecondInGame = secondsOfARealDay / secodsDayDurationInGame; // second equivalent in your game
//float elapsedRealTime = Time.time - startingGameTime; // uncomment to calculate with elapsed real time.
DateTime gateDateTime = startingGameDate.AddSeconds(elapsedRealTime * scaledElapsedSecondInGame);
return gateDateTime;
}
void OnMouseDown() { // this makes the cube clickable
Debug.LogError(getGameTime(3600).ToString());
}
}
You can try it making a cube clickable to print the output when you update the elapsed time in the public variable.
It is for 3600 second day in your game, but if you whant another game day duration you can just make that variabel puclic and try.
Important to have a collider, if not, cube wont be clickable. However It is added by default when you add the primitive right click in the scene -> 3D Object -> Cube.
You can check for example that if you add 3600 to the elapsed time public variable, and you click the cube you obtain tomorrows date in the console.
When you check the function works according to your needs you can uncomment the line //float elapsedRealTime = Time.time - startingGameTime; to use the real time elapsed or the one you wish for the date calculation.
Okay so I got it to where it is correctly synched now with the day/night cycle I just need to clean this code up quite a bit. Note: The way I'm increasing days will start to fail if you use an exceptionally long in game day I think. The boolean might work but it might also give you a new day before the end of the current day. I was testing this on a 3600 second long day.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
public class DayNightCycle : MonoBehaviour
{
public static DayNightCycle instance;
public Light sun, moon;
public float secondsInFullDay = 3600f;
[Range(0, 1)]
public float currentTimeOfDay = 0f;
[HideInInspector]
public float timeMultiplier = 1f;
float sunInitialIntensity;
public Material skyboxDay, skyBoxNight;
public double elapsedRealTime;
public float secondsPerDayMultiplier;
[SerializeField]
private float speedOfGameSecond, speedOfGameMinute, speedOfGameHour, speedOfGameDay;
[SerializeField]
private float currentGameSecond, currentGameMinute, currentGameHour, currentGameDay;
private bool stopIncrementingDay;
private void Awake()
{
instance = this;
}
// Start is called before the first frame update
void Start()
{
speedOfGameSecond = secondsInFullDay / 24 / 60 / 60;
speedOfGameMinute = secondsInFullDay / 24 / 60;
speedOfGameHour = secondsInFullDay / 24;
speedOfGameDay = secondsInFullDay;
sunInitialIntensity = sun.intensity;
}
// Update is called once per frame
void Update()
{
UpdateSun();
currentTimeOfDay += (Time.deltaTime / secondsInFullDay) * timeMultiplier;
if (currentTimeOfDay >= 1)
{
currentTimeOfDay = 0;
}
secondsPerDayMultiplier = currentTimeOfDay * secondsInFullDay;
// seconds / total seconds = percentage
// percentage * seconds = total seconds
// seconds = total seconds * percentage
currentGameSecond = secondsPerDayMultiplier / speedOfGameSecond;
currentGameMinute = secondsPerDayMultiplier / speedOfGameMinute;
currentGameHour = secondsPerDayMultiplier / speedOfGameHour;
if(!stopIncrementingDay && currentGameHour >= 23.999)
{
IncrementDay();
stopIncrementingDay = true;
} else if(currentGameHour <= 23.999)
{
stopIncrementingDay = false;
}
elapsedRealTime += Time.deltaTime;
previousTime = Time.deltaTime;
}
void UpdateSun()
{
sun.transform.localRotation = Quaternion.Euler((currentTimeOfDay * 360f) - 90, 170, 0);
moon.transform.localRotation = Quaternion.Euler((currentTimeOfDay * 360f) - 90, 170, 0);
float intensityMultiplier = 1f;
float moonIntensityMult = 0.025f;
if (currentTimeOfDay <= 0.23f || currentTimeOfDay >= 0.85f)
{
RenderSettings.skybox = skyBoxNight;
intensityMultiplier = 0f;
moonIntensityMult = 0.025f;
}
else if (currentTimeOfDay <= 0.25f)
{
RenderSettings.skybox = skyBoxNight;
intensityMultiplier = Mathf.Clamp01((currentTimeOfDay - 0.23f) * (1 / 0.02f));
moonIntensityMult = 0f;
}
else if (currentTimeOfDay >= 0.83f)
{
RenderSettings.skybox = skyboxDay;
intensityMultiplier = Mathf.Clamp01(1 - ((currentTimeOfDay - 0.83f) * (1 / 0.02f)));
moonIntensityMult = 0f;
}
sun.intensity = sunInitialIntensity * intensityMultiplier;
moon.intensity = moonIntensityMult;
}
public float GetTimeOfDayPercent
{
get { return currentTimeOfDay; }
set { return; }
}
public float GetSecondsPerDay()
{
return secondsInFullDay;
}
private void IncrementDay()
{
currentGameSecond = 0;
currentGameMinute = 0;
currentGameHour = 0;
currentGameDay++;
}
public void GetTimeOfDay()
{
// now to work on this
}
}

increase player speed based on score (endless skiing game)

i am am making an endless skiing game, similar to alto and ski safari, and need help in increasing the speed of my player based on the score of the tricks (backflips, etc) he has performed. Here's the code I've written so far:
(this script calculates the score of the player based on backflip)
public class tricksScore : MonoBehaviour
{
private float flips = 0;
private float deltaRotation = 0;
private float currentRotation = 0;
private float WindupRotation = 0;
public static Rigidbody2D rigbod;
float divideByNum = 0.25f;
public Text scores;
public int trickscore;
private int iflip;
// Start is called before the first frame update
void Start()
{
scores = GetComponent<Text>();
}
// Update is called once per frame
void Update()
{
deltaRotation = (currentRotation - rigbod.transform.eulerAngles.z);
currentRotation = rigbod.transform.eulerAngles.z;
if (deltaRotation >= 300)
deltaRotation -= 360;
if (deltaRotation <= -300)
deltaRotation += 360;
WindupRotation += (deltaRotation);
flips = WindupRotation / 340;
iflip = (int)flips;
iflip = iflip * -1;
trickscore = iflip * 10;
Debug.Log(trickscore);
scores.text = "score " + trickscore;
}
}
i import the variable trickscore to the script responsible for character movement:
[SerializeField] private tricksScore trickscript;
public int trickscore;
public int oldScore = 0;
public int incInScore;
trickscore = trickscript.trickscore;
incInScore = trickscript.trickscore - oldScore;
if (incInScore >= 10)
{
oldScore = trickscript.trickscore;
}
if (incInScore > 1 && incInScore <= 10)
{
speed = speed + 10.15f;
}
else if (incInScore > 10 && incInScore <= 20)
{
speed = speed + 0.25f;
}
else if (incInScore > 20 && incInScore <= 50)
{
speed = speed + 0.50f;
}
else if (incInScore > 50 && incInScore <= 100)
{
speed = speed + 0.75f;
}
else if (incInScore > 100 && incInScore <= 200)
{
speed = speed + 1f;
}
else if (incInScore > 200)
{
speed = speed + 2f;
}
the problem is that the speed of the player doesnt increase when i perform a backflip, also i think the variable that stores the score of the player (trickscore) also has broken because prior to writing the script, it used to display the players score in the console (debug.log) and in the text object ("scores") but neither happens anymore. i am a complete code noobie and this is the first game i am making , and this porblem has had the entire development stuck for a many days, so i will greatly appreciate any and all help. Thank you
my guess is that you have both scripts attached to your gameobject, the ideal would be separate the calculations and have 1 script handling it, get used to that and you will save yourself a lot of bugs (way better than pass scripts around and have a lot of confusion), an example in one file (that also should work if your player "currentSpeed" is used):
using UnityEngine;
using UnityEngine.UI;
public class tricksScore : MonoBehaviour
{
private float flips = 0;
private float deltaRotation = 0;
private float currentRotation = 0;
private float WindupRotation = 0;
public static Rigidbody2D rigbod;
float divideByNum = 0.25f;
public Text scores;
public int trickscore;
private int iflip;
public int oldScore = 0;
public int incInScore;
public float currentSpeed;
// Start is called before the first frame update
void Start()
{
scores = GetComponent<Text>();
}
// Update is called once per frame
void Update()
{
deltaRotation = (currentRotation - rigbod.transform.eulerAngles.z);
currentRotation = rigbod.transform.eulerAngles.z;
if (deltaRotation >= 300)
deltaRotation -= 360;
if (deltaRotation <= -300)
deltaRotation += 360;
WindupRotation += (deltaRotation);
flips = WindupRotation / 340;
iflip = (int)flips;
iflip = iflip * -1;
trickscore = iflip * 10;
currentSpeed += Calculations.CalculateSpeed(trickscore,oldScore);
}
}
//this should be in a separate file
public class Calculations
{
public static float CalculateSpeed(float currentScore, float oldScore)
{
var incInScore = currentScore - oldScore;
if (incInScore > 1 && incInScore <= 10)
{
return 10.15f;
}
else if (incInScore > 10 && incInScore <= 20)
{
return 0.25f;
}
else if (incInScore > 20 && incInScore <= 50)
{
return 0.50f;
}
else if (incInScore > 50 && incInScore <= 100)
{
return 0.75f;
}
else if (incInScore > 100 && incInScore <= 200)
{
return 1f;
}
else
{
return 2f;
}
}
}

Separation Steering Algorithm

Ok so this site has helped me alot before i had an account, but now the net is not helping me so i'll post it myself :)
I am looking (i am yet another one) to do something like this:
tinykeep.com/dungen/
Now the first step(Generating the rooms , goes well), but this is the first time ever I encounter Flocking behaviour algorithms, and my maths really arent that terrific.
So i tried and came up with a non working algorithm, what i did is started from next standard separation algorithm: gamedevelopment.tutsplus.com/tutorials/the-three-simple-rules-of-flocking-behaviors-alignment-cohesion-and-separation--gamedev-3444 (sorry for this text but it wouldn't let me post more than 2 links without 10 rep), And changed it to my liking. Like i said before it's really not doing anything, if i find how i'll post some debug results.
Here's my code:
class Room {
Vector3 position;
Vector3 size;
int area;
public Room(Vector3 position, Vector3 size, int area) : this(position, size){
this.area = area;
}
public Room(Vector3 position, Vector3 size){
this.position = position;
this.size = size;
if(area != null)
this.area = (int)(size.x * size.z);
}
public Vector3 GetPosition(){
return position;
}
public Vector3 GetSize(){
return size;
}
public void SetPosition(Vector3 position){
this.position = position;
}
public Boolean TooCloseTo(Room room){
return position.x + size.x / 2 > room.GetPosition().x - room.GetSize().x / 2 || position.z + size.z / 2 > room.GetPosition().z - room.GetSize().z / 2 ||
position.x - size.x / 2 < room.GetPosition().x + room.GetSize().x / 2 || position.z - size.z / 2 < room.GetPosition().z + room.GetSize().z / 2;
}
public override string ToString ()
{
return string.Format ("[Room]\nPosition:{0}\nSize:{1}\nArea:{2}", position, size, area);
}
}
These are part of the Mapgenerator class, the rest of this class works fine and seems unimportant to me, but if you feel the need to see it, let me know and i'll post it.
void SeparateRooms(){
foreach (Room room in rooms) {
//Debug.Log (room);
Vector3 oldPos = room.GetPosition ();
Vector3 separation = computeSeparation (room);
//Debug.Log (separation);
Vector3 newPos = new Vector3 (oldPos.x += separation.x, oldPos.y, oldPos.z += separation.z);
room.SetPosition (newPos);
//Debug.Log (room);
}
}
Vector3 computeSeparation(Room agent) {
int neighbours = 0;
Vector3 v = new Vector3 ();
foreach (Room room in rooms) {
if (room != agent) {
if (agent.TooCloseTo (room)) {
v.x += Difference(room, agent, "x");
v.z += Difference(room, agent, "z");
neighbours++;
}
}
}
if (neighbours == 0)
return v;
v.x /= neighbours;
v.z /= neighbours;
v.x *= -1;
v.z *= -1;
v.Normalize ();
return v;
}
float Difference(Room room, Room agent, string type){
switch (type) {
case "x":
float xBottom = (room.GetPosition ().x + room.GetSize ().x / 2) - (agent.GetPosition ().x - agent.GetSize ().x / 2);
float xTop = (agent.GetPosition ().x + agent.GetSize ().x / 2) - (room.GetPosition ().x - room.GetSize ().x / 2);
return xBottom > 0 ? xBottom : xTop;
break;
case "z":
float xRight= (room.GetPosition ().z + room.GetSize ().z / 2) - (agent.GetPosition ().z - agent.GetSize ().z / 2);
float xLeft= (agent.GetPosition ().z + agent.GetSize ().z / 2) - (room.GetPosition ().z - room.GetSize ().z / 2);
return xRight > 0 ? xRight : xLeft;
default:
return 0;
break;
}
}
I was expecting the difference to be numbers like 4.0 and 8.0 and so on, instead i get 0.9 and 0.3 and so on, i'll copy an output:
Debug log
I hope that is readable.
Explanation: Each three lines are the info about the room:
1. the original room
2. the (what's supposed to be the) overlap between the room and the next
3. the new position of the room
EDIT: Ok thanks to the comments i'm getting pretty normal results for overlap now, but the rooms are still overlapping after i run the algorithm, i think this might have to do something with only iterating once over every room... Any comments on that?
I really hope some of you might be able to point me in the right direction, or tell me what is wrong in my reasoning.
Thank you!
EDIT: Filling up rooms:
public void Generate(int level) {
int levelModifier = (int)(Math.Round ((double)Mathf.Log (level, 2.5f),1) * 10);
int mean = 25;
int SD = 5;
for (int i = 0; i < 30 + levelModifier; i++) {
Vector3 position = getPInCircle (20);
int area = (int)SimpleRNG.GetNormal (mean, SD);
if (area < mean - SD)
continue;
Vector3 size = calculateSize (area);
Room room = new Room (position, size);
rooms.Add (room);
}
SeparateRooms ();
}
Vector3 calculateSize(int area) {
float k = UnityEngine.Random.Range (2.0f, area / 2.0f);
float l = area / k;
int shortSide;
int longSide;
if (Mathf.Round (k) > Mathf.Round (l)) {
shortSide = Mathf.RoundToInt (k);
longSide = Mathf.RoundToInt (l);
} else {
shortSide = Mathf.RoundToInt (l);
longSide = Mathf.RoundToInt (k);
}
//Debug.Log (shortSide);
//Debug.Log (longSide);
Vector3 size;
if (SimpleRNG.GetUniform () < 0.5) {
size = new Vector3 (Actualise(shortSide), 0, Actualise(longSide));
} else {
size = new Vector3 (Actualise(longSide), 0, Actualise(shortSide));
}
return size;
}
The SimpleRNG is John D. Cook's Namespace, open for download at www.codeproject.com/Articles/25172/Simple-Random-Number-Generation

Time.time make my Color Lerp not 'lerp'

I'm making a day/night cycle and have the lerp on Time.time, because if I use Time.deltaTime it turns night.day around so its day at 12am. However I digress.
The problem I'm running into now too is that with any Time setting it will make the lerp instant and not - well.. 'lerp'. Any idea on fixing this? I'm a C# newbie
I got it working with this as the time script:
using UnityEngine;
using System.Collections;
public class timeFlow : MonoBehaviour
{
public float Hours = 00;
public float Minutes = 00;
void Update()
{
if(Hours <= 23){
if(Minutes >= 60)
{
Minutes = 0;
if(Minutes <= 59)
{
Hours++;
}
else
{
Minutes = 0;
Hours = 0;
guiText.text = Hours.ToString("f0") + ":0" + Minutes.ToString("f0");
}
}
else
{
Minutes += UnityEngine.Time.deltaTime * 100;
}
if(Mathf.Round(Minutes) <= 9)
{
guiText.text = Hours.ToString("f0") + ":0" + Minutes.ToString("f0");
}
else
{
guiText.text = Hours.ToString("f0") + ":" + Minutes.ToString("f0");
}
}
else {
Hours = 0;
}
}
}
And this is the lerp script:
using UnityEngine;
using System.Collections;
public class cycleFlow : MonoBehaviour {
public Color32 night = new Color32(30, 30, 30, 255);
public Color32 day = new Color32(255, 255, 255, 255);
public GameObject Timer;
private timeFlow TimeFlow;
void Awake () {
TimeFlow = Timer.GetComponent<timeFlow> ();
}
void Update () {
DayNightCycle ();
}
void DayNightCycle()
{
foreach (SpriteRenderer child in transform.GetComponentsInChildren<SpriteRenderer>()) {
if (TimeFlow.Hours == 18){
child.color = Color.Lerp(day, night, Time.time);
}
if (TimeFlow.Hours == 6) {
child.color = Color.Lerp(night, day, Time.time);
}
}
}
}
You can write something like this, Lerp takes actual (from) value, final (to) value and fraction value. (here Time.deltaTime) Now when your timer will reach hour 18, your Color will change to color of night in few Update function calls (you can control change time by multiplying Time.deltaTime) :)
foreach ( SpriteRenderer child in transform.GetComponentsInChildren<SpriteRenderer>() ) {
if ( TimeFlow.Hours == 18 ) {
child.color = Color.Lerp(child.color, night, Time.deltaTime);
// here two times faster
// child.color = Color.Lerp(child.color, night, Time.deltaTime * 2.0f);
}
if ( TimeFlow.Hours == 6 ) {
child.color = Color.Lerp(child.color, day, Time.deltaTime);
// here half slower :)
// child.color = Color.Lerp(child.color, night, Time.deltaTime * 0.5f);
}
}
I had a hard time understanding lerp when used together with a time.
Maybe this example helps someone:
// lerp values between 0 and 10 in a duration of 3 seconds:
private float minValue = 0.0f;
private float maxValue = 10.0f;
private float totalDuration = 3.0f;
private float timePassed = 0.0f;
private float currentValue;
void Update()
{
timePassed += Time.deltaTime;
// Lerp expects a value between 0 and 1 as the third parameter,
// so we need to divide by the duration:
currentValue = Mathf.Lerp(minValue, maxValue, timePassed/totalDuration);
}
Note: you need to add some logic for:
handling when to start/stop lerping
when to reset timePassed

Categories