[released] SunLight – Location based Time of Day | For games or architectural applications

Are you

– tired of trying to change settings to simulate the color of real sunlight each time you alter the angle of your main directional light?

– searching for a quick and robust way to set a directional light to the correct angle for a given time and location?

– looking for useful and lightweight tool to make most out of Unity’s global illumination skybox?

– in need of a perfectly compatible solution to simulate a Day/Night Cycle?

– searching for an inexpensive tool for real world shadow simulation ?

SunLight – Location based Time of Day calculates the light color and orientation of a directional light source based on geographical location and time of day to create a realistic sun light source. Simple to use; just drag it into your scene and let SunLight handle the directional light.

Works with Unity’s built-in procedural skybox, making it rock solid and 100% compatible.

SunLight creates two directional lights, one to illuminate the scene and another one is used to trigger Unity’s Skybox only (layer mask set to nothing). This is necessary to avoid unwanted directional illumination from below the horizon in twilight conditions.

Two variants to fit to your prefered workflow: written in Unity Script (JS) and C#
Script reference: http://www.hessburg.com/AssetStore/SunLight_Manual_Reference.pdf

Usage:

Drag the prefab (C# and JS based prefabs available) into the scene and set location and time in inspector.

– Chose a location from 10 presets or manually set latitude and longitude.
– Choose whether to let SunLight handle the progress of time or control it in your script.
– If you wish you can manually override the azimuth (horizontal rotation) of the sun via inspector or in your own script.

Super easy artistic workflow: SunLight always updates the directional light based on your changes in inspector even when not in play mode. (Of course only when the prefab is actually in the scene and activated)

Just $9.99

You can use SunLight as a quick meaningful tool for architectural or urban planning purposes in Unity, when accuracy does not have to meet scientific standards by using it for shadow simulations.
The simplest way:
Simply use a map texture from any provider as a texture for a plane and scale and align it correctly:

Or use the slightly more expensive option:
Use one of the several assets offered in the store to create the terrain, textures and sometimes even rough buildings correctly using data from map providers – for example:

Real World Terrain

World Composer

CitiGen3D

Real Terrain Maker Light

Real Terrain Maker

GIS Terrain Loader

GIS data downloader

Asset Store Link

Update 1.1 adds a custom north direction to SunLight to always match to the horizontal rotation of your scene.

You can set it in Inspector or in your scripts.
SunLight.northDirection : float (Range 0.0-360)

I just got this and am using it for the first time - running the demo - and I notice that when the sun dips into the horizon (or rises) it seems to jump a little to the side. Maybe a hand-off of some sort occurs at the horizon and something is a tiny bit out of alignment? This is observed when the location is set to New York or Sydney or Reykjavik, but not at Singapore or Rio, so probably the distortion gets greater the further the observer is from the equator.

Also, every setting made in the inspector for Sun Light script gets changed once play is pressed, and the Time Progress Factor is permanently set to 3000 (but the time doesn’t automatically progress).

I’m using the C# example with Unity 5.5.0f3. There are no errors in the console.

Thank you, I will take a look at your issues.

I found two things which will cause the behavior you described:

#1 SL_SkyboxLight isn’t automatically set as the Sun in Window/Lighting under Scene/Environment Lighting. If not set Unity tries to use the brightest lights in the scene as the sun, but sometimes it does unexpected things. (Also see “please note“ on Page 1 of the SunLight manual). Set it manually to fix it.

I’ve just learned that Unity finally added RenderSettings.sun to the scripting API of Unity 5.5 (yay!). So I can release an update which will always set the correct light for the sun automatically. Please set it manually until the update is out (or when using versions of Unity prior to 5.5)

#2 I found an issue with refraction. Actually refraction isn’t really important, especially for games, because the differences are tiny and it has an effect during a very short time of the day only (during sunrise and sunset). You can quickly change the script to fix that until I release an update.

In SunlightCalculation.cs (same for UnityScript) change the line

altitude = (altitude+refraction) / Mathf.Deg2Rad; // Height of the center of the sun (in degrees) - 0 = horizon - 90 = full zenit

to

altitude = altitude / Mathf.Deg2Rad; // Height of the center of the sun (in degrees) - 0 = horizon - 90 = full zenit

This is something I can’t reproduce – have you checked the button Progress Time?

How I approached the demo was to take everything at face value - changing nothing - and I pressed play. I saw what was going on in the scene, and then decided to adjust values in the inspector while it was running to see how it would play out. I noticed that while I could change the location and hour, and everything else, time would not progress whether Progress Time was checked or not, and the value for Time Progress Factor always reads 3000 at runtime and cannot be changed.

I can’t think of anything that would account for that.

Also, when I change the inspector out of play mode, and then enter play, every setting is overwritten.

I have been running this in a nearly empty project, so I’ll try it now in a completely fresh empty project and see how that goes.

UPDATE: Okay, some more weird behavior. I decided to make some changes (selected New York) and saved the scene. Then I cleared out the old scene and brought in the new one (with NY) from the project file. Now, when I press play, time progresses! But … the location of New York is overwritten and so are all my other settings, like a progress factor of 1.

So while in edit mode I changed the location to Panama, and the hour to 6, progress factor of 1, day 100, I saved it and pressed play and I get the same thing … that is, every setting is overwritten by data I did not save, but now time progresses (at a factor of 3000, presumably).

It seems like the Sun Light script is getting data from elsewhere, and that data is overwriting my settings in the inspector on play. I have no explanation, though, for why I had to save the scene in order to get time to progress.

The demo scene is just an example of how you can use SunLight with your own scripts. That’s why you see unexpected behavior when you try to set variables in the inspector – the demo script is frequently overriding them.

Please drag the prefab into your scene to use it. (like it is mentioned in the manual)

Ah, that solves it. I guess the idea with the demo is that it ignores user changes; I didn’t expect that. But yes, dragging the prefab into the scene works perfectly. It also clears up the rising / setting issue I was reporting before.

Sorry for taking your time on what turned out to be user error!

Actually, as written above, there is really this tiny error which occurs for one frame and I would not have found it without you. But I will fix that with the update. :slight_smile:

Sorry for the delay. I’ve just uploaded the update. Should be online within a few days.

1 Like

BTW, the progress time issue (where it simply wouldn’t progress) seemed to come from a conflict with something else, and I didn’t spend the time to figure how or why. I couldn’t see any obvious culprit.

The SunLight plugin works fine in an empty project, and that’s how I should have tested it.

1 Like

The update just hit the Asset Store.

@hopeful – good to hear that it works. Hard to guess what could be the reason for the conflict you experienced, maybe some other asset was affecting your projects time settings?

Yeah, I have no idea how or why it was affected - so strange! - and while I was going to try to root it out, real life intervened and I just didn’t have the time.

I should have tested in a separate project, but it was one of those situations where “I only have like 2 or 3 models in here, so surely that can’t affect the plugin …”

Famous last words. :wink:

1 Like

Uploaded 1.2.1 to the Asset Store – this minor update should be available within a few days.

New in version 1.2.1:
Optimization to avoid unnecessary calculations when input parameters haven’t changed.

V 1.2.1 is available now.

Someone asked me how to synchronize SunLight to the system time. This is as simple as possible:

This example would set the current time:

DateTime currentTime = DateTime.Now;
SunLight.SetTime(currentTime.Hour, currentTime.Minute, currentTime.Second);

Once set, SunLight could handle the progress of time, but if you need a solution that is in sync to the real world even after a pause of the game then you could handle progress of time in your own script.

I’ve prepared an example for beginners:

https://hessburg.com/AssetStore/SyncToSystemTime.zip

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using Hessburg;

public class SyncToSystemTime : MonoBehaviour
{
    public SunLight SunLight; // set in inspector
    public bool syncActive; // set to true to sync
  
    void Update()
    {
        if(syncActive)
        {
            DateTime currentTime = DateTime.Now;
            SunLight.SetTime(currentTime.Hour, currentTime.Minute, currentTime.Second);
        }
    }
}
1 Like

To complete the example: this would set it to date & time and correct timezone:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using Hessburg;

public class syncToSystemTime : MonoBehaviour
{
    public SunLight SunLight; // set in inspector
    public bool syncActive; // set to true to sync
  
    void Update()
    {
        if(syncActive)
        {
            DateTime currentTime = DateTime.Now;
            SunLight.SetTime(currentTime.Hour, currentTime.Minute, currentTime.Second);
            SunLight.dayOfYear=currentTime.DayOfYear;
            SunLight.leapYear=DateTime.IsLeapYear(currentTime.Year);
            TimeZone localZone = TimeZone.CurrentTimeZone;
            TimeSpan currentOffset = localZone.GetUtcOffset(System.DateTime.Now);
            SunLight.offsetUTC=(float)currentOffset.TotalHours;
        }
    }
}

You would still have to feed in the latitude and longitude of the place.
On mobile you could do this by using location services – this should work (untested):

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using Hessburg;

public class syncToSystemTime : MonoBehaviour
{
    public SunLight SunLight; // set in inspector
    public bool syncActive; // set to true to sync
  

    void Start ()
    {
        #if UNITY_ANDROID || UNITY_IOS
            Input.location.Start(); // Starts Location Service on Device
        #endif
    }


    void Update()
    {
        if(syncActive)
        {
            DateTime currentTime = DateTime.Now;
            SunLight.SetTime(currentTime.Hour, currentTime.Minute, currentTime.Second);
            SunLight.dayOfYear=currentTime.DayOfYear;
            SunLight.leapYear=DateTime.IsLeapYear(currentTime.Year);
            TimeZone localZone = TimeZone.CurrentTimeZone;
            TimeSpan currentOffset = localZone.GetUtcOffset(System.DateTime.Now);
            SunLight.offsetUTC=(float)currentOffset.TotalHours;
      
            #if UNITY_ANDROID || UNITY_IOS
                SunLight.latitude=Input.location.lastData.latitude;
                SunLight.longitude=Input.location.lastData.longitude;
            #endif
        }
    }
}
1 Like

UPDATE:
I’ve submitted Version 1.3 of SunLight – Location based Time of Day to the Asset Store. It should become available within a few days.

What’s new: Removed any JS/UnityScript content. All scripts are C# only now. (Since Unity 2017.2 UnityScript is officially deprecated – I wish I could have kept it, but Assets containing Unity Script will be removed from the store soon, so I was forced to drop one language.)

Next step on the roadmap: Support for PlayMaker

1 Like

The Update is out now. You can contact me if you still need the older version with the additional Unity Script.

Link was broken due to typo, sorry for that – fixed it. https://hessburg.com/AssetStore/SyncToSystemTime.zip

PS: Sunlight is on Mega Sale.