Slowing down day/night cycle when sun is near horizens

Hello all,

I’m using a simple transform to rotate the position of the sun at a constant speed right now. What I would really like is for the night to go quickly and for dawn/dust to linger for a while.

I just have no idea how I would do this. Any thoughts?

@JustFun’s suggestion of using an animations is likely the easiest solution. But as a programmer, programming is my hammer and everything looks like a nail. So here is an approach using some code. I’m going to assume that you’ve implemented your cycle by having an empty game object at the center and by placing your sun as an outlying child. So you would rotate the empty game object to rotate the sun across the sky.

I sometimes have trouble getting my head wrapped around problems like these, so I standardize things. First I write my code so that movement or cycling is mapped into the values between 0.0 and 1.0. Usually what I’m remapping is time. So for the above rotation, I might write this coroutine:

function DayNight(time : float) {
	var timer : float;
	
	while (true) {
		timer += Time.deltaTime / time;
		timer = timer % 1.0;
		var a = Map(timer) * 360.0;
		transform.rotation = Quaternion.AngleAxis(a, Vector3.forward);
		yield;
	}
}

And then a linear Map() function is:

function Map(var f) {
    return f;
}

And you would call it in Start() for a 30 second day/night cycle:

 DayNight(30.0);

This is lot of code for something that can be done in a single line in Update(), but now I can easily map the input through some sort of curve or calculation. So to use a Cosine function to slow the rotation at near 0 and 180 degrees, I can rewrite map to:

function Map(f : float) : float{
	if (f <= 0.5) 
		var ff = (Mathf.Cos(f * Mathf.PI * 2.0 - Mathf.PI) + 1.0) / 4.0;
	else 
		ff = (Mathf.Cos((f - 0.5) * Mathf.PI * 2.0 - Mathf.PI) + 1.0) / 4.0 + 0.5;
    return ff;
}

And if I want more control, I can write a version of the Map function that takes an AnimationCurve.

var ac : AnimationCurve;

function Map(f : float) : float {
	return Mathf.Clamp01(ac.Evaluate(f));
}

And the curve might look like:

30697-ac1.png

And since an AnimationCurve is such a flexible solution, that brings us back full circle to the suggestion that an Animation might be the simplest solution, and this problem isn’t a nail at all.

Thanks guys for taking the time to reply. Very in depth!

I thought about animation but it’s something I’ve not really tackled beyond the basics so far so I kind of avoided it.

I think I’ll look into the animation solution.