Search Unity

  1. We are migrating the Unity Forums to Unity Discussions by the end of July. Read our announcement for more information and let us know if you have any questions.
    Dismiss Notice
  2. Dismiss Notice

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

Discussion in 'Assets and Asset Store' started by VIC20, Jul 12, 2016.

  1. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    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
     
    Last edited: Dec 17, 2021
  2. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    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)
     
  3. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    5,711
    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.
     
  4. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    Thank you, I will take a look at your issues.
     
  5. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    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

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

    Code (CSharp):
    1. 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?
     
  6. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    5,711
    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.
     
    Last edited: Mar 12, 2017
  7. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    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)
     
  8. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    5,711
    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!
     
  9. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    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. :)
     
  10. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    Sorry for the delay. I’ve just uploaded the update. Should be online within a few days.
     
    hopeful likes this.
  11. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    5,711
    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.
     
    VIC20 likes this.
  12. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    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?
     
    Last edited: Apr 7, 2017
  13. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    5,711
    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. ;)
     
    TeagansDad likes this.
  14. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    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.
     
  15. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    V 1.2.1 is available now.
     
  16. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    Someone asked me how to synchronize SunLight to the system time. This is as simple as possible:

    This example would set the current time:

    Code (CSharp):
    1. DateTime currentTime = DateTime.Now;
    2. 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



    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using System;
    5. using Hessburg;
    6.  
    7. public class SyncToSystemTime : MonoBehaviour
    8. {
    9.     public SunLight SunLight; // set in inspector
    10.     public bool syncActive; // set to true to sync
    11.  
    12.     void Update()
    13.     {
    14.         if(syncActive)
    15.         {
    16.             DateTime currentTime = DateTime.Now;
    17.             SunLight.SetTime(currentTime.Hour, currentTime.Minute, currentTime.Second);
    18.         }
    19.     }
    20. }
    21.  
     
    Last edited: Nov 27, 2017
    hopeful likes this.
  17. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    To complete the example: this would set it to date & time and correct timezone:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using System;
    5. using Hessburg;
    6.  
    7. public class syncToSystemTime : MonoBehaviour
    8. {
    9.     public SunLight SunLight; // set in inspector
    10.     public bool syncActive; // set to true to sync
    11.  
    12.     void Update()
    13.     {
    14.         if(syncActive)
    15.         {
    16.             DateTime currentTime = DateTime.Now;
    17.             SunLight.SetTime(currentTime.Hour, currentTime.Minute, currentTime.Second);
    18.             SunLight.dayOfYear=currentTime.DayOfYear;
    19.             SunLight.leapYear=DateTime.IsLeapYear(currentTime.Year);
    20.             TimeZone localZone = TimeZone.CurrentTimeZone;
    21.             TimeSpan currentOffset = localZone.GetUtcOffset(System.DateTime.Now);
    22.             SunLight.offsetUTC=(float)currentOffset.TotalHours;
    23.         }
    24.     }
    25. }

    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):

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using System;
    5. using Hessburg;
    6.  
    7. public class syncToSystemTime : MonoBehaviour
    8. {
    9.     public SunLight SunLight; // set in inspector
    10.     public bool syncActive; // set to true to sync
    11.  
    12.  
    13.     void Start ()
    14.     {
    15.         #if UNITY_ANDROID || UNITY_IOS
    16.             Input.location.Start(); // Starts Location Service on Device
    17.         #endif
    18.     }
    19.  
    20.  
    21.     void Update()
    22.     {
    23.         if(syncActive)
    24.         {
    25.             DateTime currentTime = DateTime.Now;
    26.             SunLight.SetTime(currentTime.Hour, currentTime.Minute, currentTime.Second);
    27.             SunLight.dayOfYear=currentTime.DayOfYear;
    28.             SunLight.leapYear=DateTime.IsLeapYear(currentTime.Year);
    29.             TimeZone localZone = TimeZone.CurrentTimeZone;
    30.             TimeSpan currentOffset = localZone.GetUtcOffset(System.DateTime.Now);
    31.             SunLight.offsetUTC=(float)currentOffset.TotalHours;
    32.      
    33.             #if UNITY_ANDROID || UNITY_IOS
    34.                 SunLight.latitude=Input.location.lastData.latitude;
    35.                 SunLight.longitude=Input.location.lastData.longitude;
    36.             #endif
    37.         }
    38.     }
    39. }
     
    hopeful likes this.
  18. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    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
     
    Last edited: Apr 26, 2020
    hopeful likes this.
  19. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    The Update is out now. You can contact me if you still need the older version with the additional Unity Script.
     
  20. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
  21. Jayme65

    Jayme65

    Joined:
    Dec 11, 2016
    Posts:
    94
    Hi,
    Does the asset returns the 'correct' sunrise and sunset hours according to longitude and latitude (I think so, but just want to be sure ;) )
    If the goal of this asset is to get the correct illumination based on location, time and day...why isn't it extended to year?
    Taking year in account would surely result in a very slight difference in the computed solution...but I would like to get this precision and to be able to simply say: sync on the user computer current date: year, day of year, hours and minutes! Possible? ;)
     
  22. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    Actually I never thought anyone would want to set the year because the differences are so tiny. I would have to change the calculation to offer the year. I could do that to give it some extra precision but this would require more calculations per frame for no real effect (I tried to reduce calculations where possible) – it is made for games not for space flight. Maybe I could add a different calculation with the year as an option. I will notice it on my list of ideas but I can’t promise anything.

    Short answer: if you think you absolutely need the year then don’t buy it :)
     
  23. PWendtInneo

    PWendtInneo

    Joined:
    Oct 14, 2016
    Posts:
    5
    Hi there, maybe you are able to help me. I want to use your Sunlight in an augmented reality app. The problem that I have is, that the world space alignment seems to set itself to the heading of the phone, when the app starts. So I need to get the real north direction, to display the real world shadows of the augmented objects in the app. When I used Apples ArKit there was an option to set the world alignment always in the direction of the north pole, but when I use Vuforia now, I don't have that handy advantage.
    I know, you can get the geographical North Pole heading with the compass.true heading, but I tried to fiddle that with the custom north direction into my scripts, when I didn't know about the ArKit heading option... with no success.
    And now I need to switch to Vuforia, to release the app on Android devices...
    Maybe you encountered a similar problem and you can help me out...
     
  24. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    Hello, none of my iOS devices supports ARKit so I never had a chance to test it and I never used Vuforia.
    I've made something similar (not AR but the device was exactly locked to real world too and showed a cubic panorama) for a 3D compass app. I’ve used the Gyroscope and the compass and smoothed them. This worked pretty good but it was 3 years ago and for iOS only. I don’t remember exactly what I did but it was possible with Unity 4 without any plugins. Sorry, that I can’t provide any better help.
     
  25. PWendtInneo

    PWendtInneo

    Joined:
    Oct 14, 2016
    Posts:
    5
    No Problem, I'm on it again and it seems I'm almost there. When I find the solution, I'll post it here :)
     
  26. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    Great, thank you.
     
  27. PWendtInneo

    PWendtInneo

    Joined:
    Oct 14, 2016
    Posts:
    5
    So I've solved it. It was not that hard.
    You have to use the device's Location Services to get the north direction of the build in compass.

    Code (CSharp):
    1. /* Don't forget to request the permission to use the location service on the device.
    2. Location.Start() takes a while so make sure you wait for it to finish.
    3. Unity Documentation has a good example how to use it!*/
    4. Input.location.Start();
    5. Input.compass.enabled = true;
    6.  
    7. /* Then get the compass' true heading and the camera's y-axis rotation and calculate the difference between the two.
    8. (Modulo to get always positive values you need for the Sunlight north direction value)*/
    9. float newValue = (cam.transform.eulerAngles.y - Input.compass.trueHeading + 360) % 360;
    10. // Finally Turn it around 180°!
    11. sunLight.northDirection = (newValue + 180) % 360;
    The Problem I had all day was, that the Compass calibration was pretty poor, so I got only false values for the north direction. If it doesn't work out, consider a manual calibration of the Sunlight north direction by pointing the device towards north and execute the following code:
    Code (CSharp):
    1. public void ManualResetNorthDirection()
    2.     {
    3.         float newValue = (cam.transform.eulerAngles.y + 360) % 360;
    4.         // Turn around 180°!
    5.         sunLight.northDirection = (newValue + 180) % 360;
    6.     }
    But this only works, if the in game camera turns with the device!

    Btw, with manual, you also could
    point the device towards south direction and leave the turning around 180° out... :) (I did it only for consistency reasons)
     
    Last edited: Apr 4, 2018
    VIC20 likes this.
  28. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    Oh, sorry, then I misunderstood you because I thought you already used Location Services and ran into problems with it. But glad to see you figured it out. Maybe I should add an example like yours to the manual. :)

    Next step, if you need to improve your result could be the additional usage of the gyroscope and some custom smoothing technic based on the mix of both. I did that with this app: https://hessburg.com/apps/compass/wota-uboat-compass.html
     
  29. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    A nice example of what you could do with SunLight:

    A happy customer built a shadow simulator of his neighborhood, using SunLight, so he knows when he can play badminton on his outside court without the sun shining in their eyes:

    http://www.toleap.se/badminton/
     
    novion4 likes this.
  30. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    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
     
    Last edited: Dec 17, 2021
  31. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    This is a simple workaround to use my asset "SunLight – Location based Time of Day“ with an URP sky (should work with HDRP too). I can't give support for HDRP and URP yet, but I hope this workaround will help those who want to use SunLight under URP / HDRP as well.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using Hessburg;
    6.  
    7. [ExecuteInEditMode]
    8. public class CopySunLightRotation : MonoBehaviour
    9. {
    10.     public SunLight SunLight; // set in inspector
    11.     private Transform SkyBoxLightTransform;
    12.     private Light SkyBoxLight;
    13.     private Light SunLightSkyboxLight;
    14.     private Light SunLightSceneLight;
    15.     private LensFlare SunLightLensFlare;
    16.     private Transform SunLightSkyboxLightTransform;
    17.     private GameObject SunLightSkyboxLightGameObject;
    18.     private GameObject SunLightSceneLightGameObject;
    19.     private GameObject SunLightLensFlareGameObject;
    20.    
    21.     void Start()
    22.     {
    23.         if (SunLight != null)
    24.         {
    25.             SunLightSkyboxLight = SunLight.GetSkyboxLight();
    26.             SunLightSceneLight = SunLight.GetSceneLight();
    27.             SunLightLensFlare = SunLight.GetLensFlare();
    28.             SunLightSkyboxLightTransform = SunLightSkyboxLight.transform;
    29.             SunLightSkyboxLightGameObject = SunLightSkyboxLight.gameObject;
    30.             SunLightSceneLightGameObject = SunLightSceneLight.gameObject;
    31.             SunLightLensFlareGameObject = SunLightLensFlare.gameObject;
    32.             SunLightSkyboxLightGameObject.SetActive(false);
    33.             SunLightSceneLightGameObject.SetActive(false);
    34.             SunLightLensFlareGameObject.SetActive(false);
    35.             SkyBoxLightTransform=this.transform;
    36.             SkyBoxLight=this.GetComponent<Light>();
    37.         }  
    38.     }
    39.  
    40.     // Update is called once per frame
    41.     void LateUpdate()
    42.     {
    43.         SkyBoxLightTransform.rotation=SunLightSkyboxLightTransform.rotation;
    44.         SkyBoxLight.color=SunLightSceneLight.color;
    45.     }
    46. }
    47.  
    1. download (or create) the script https://www.hessburg.com/downloads/SunLight/CopySunLightRotation.zip

    2. Attach the script to the directional light which you are using with the URP / HDRP sky

    3. Place the SunLight prefab into your scene.

    4. Set the reference to the SunLight prefab in the CopySunLightRotation.cs script that you have attached to your directional light

    The rotation and light color of the SunLight lights are now cloned to set the rotation and light color of your directed light.
    If the light color (which is based on the light system in the built-in renderer) does not meet your needs, you can try adjusting the intensity of your directed light. If this still does not meet your needs, adjust the light color manually and delete this line:

    SkyBoxLight.color=SunLightSceneLight.color;

    Of course, this means that you will then only use the rotation, but not the light color of SunLight

     
    Last edited: Feb 1, 2022
  32. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
  33. Noors84

    Noors84

    Joined:
    Jul 12, 2016
    Posts:
    81
    Hey, could you tell me what is the North direction assumed by your tool ? -z ?
     
  34. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    Yes, you are right. North is Unity’s negative Z direction (backward direction of the blue arrow).
     
    Noors84 likes this.
  35. fabbrius

    fabbrius

    Joined:
    May 22, 2020
    Posts:
    3
    Hi everyone, I purchased the asset today and started using it for an augmented reality project.
    The goal that prompted me to purchase was the ability to get shadows consistent with the actual lighting type of the environment where the augmented reality experience takes place.

    I followed the steps outlined, importing the prefab into the scene, setting the location, and followed the instructions in post #16 to synchronize the SunLight time with the device time (and thus real time). This is because I would like that anytime the user wants to use the app, they will always find a virtual lighting system consistent with natural light.
    The problem I'm facing, however, is that even after setting all the parameters, when I open the application the direction of the shadows of virtual objects in AR does not correspond to the direction of the real shadows.
    Basically what happens is that every time I open the app, depending on the direction in which I hold the device the shadows follow a different direction. Probably due to an alignment issue between the real and Unity coordinates.

    A similar problem was also by user PWendtInneo in post #23, if I understand correctly.
    Then he proposed a solution that unfortunately doesn't work for me, or maybe I couldn't implement it correctly.
    As a reference framework for augmented reality I'm using AR Foundation and the default deployment platform is Android (although a version for iOS is also planned).

    Does anyone have any ideas on how I can fix this? can anyone help me?

    Thanks
     
  36. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    Hello fabbrius, I can't tell what you're doing wrong. But I will try to create a simple example project and post it here. Unfortunately I can't start with it before Monday.
     
  37. fabbrius

    fabbrius

    Joined:
    May 22, 2020
    Posts:
    3
    Hello VIC20,
    thank you so much for your response.
    I gladly wait for your test example and will definitely test it.
    Thanks again!
     
  38. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    The script PWendtInneo shared works. Is it possible that you just forgot to attach the AR camera?

    The compass is driving me nuts. Actually even Apples own compass is showing me weird results. I tried it for many hours and just gave up. Maybe it is my phone and it works better for you. So here is what I tried. Like PWendtInneo did it takes the y angle of the camera to find out the start angle. Then it continues to calculate the start angle while averaging it to keep it smooth even when the compass runs mad – in theory, but my compass sometimes shows me east for west which of course is impossible to fix by smoothing.

    I hope this is at least a start for you to solve that problem. Sorry that I could not help you any better.

    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.UI;
    6. using System;
    7. using Hessburg;
    8.  
    9.  
    10. public class SetNorthForAR : MonoBehaviour
    11. {
    12. public float smooth = 0.2f;
    13. private float yVelocity = 0.0f;
    14. private SunLight SunLight;
    15. private Transform ARcamera;
    16. private bool trackingCompass = false;
    17. private float northDirection;
    18. private float averageAngle;
    19. private float angleDistance;
    20. private int i;
    21.  
    22. void Start()
    23. {
    24. ARcamera=GameObject.Find("AR Camera").transform;
    25. SunLight=GameObject.Find("SunLight").GetComponent<SunLight>();
    26. #if UNITY_ANDROID || UNITY_IOS
    27. Input.compass.enabled = true;
    28. Input.location.Start();
    29. StartCoroutine(CompassInitialization());
    30. #endif
    31. }
    32.  
    33. void Update()
    34. {
    35. #if UNITY_ANDROID || UNITY_IOS
    36. if (trackingCompass)
    37. {
    38. DateTime currentTime = DateTime.Now;
    39. SunLight.SetTime(currentTime.Hour, currentTime.Minute, currentTime.Second);
    40. SunLight.dayOfYear=currentTime.DayOfYear;
    41. SunLight.leapYear=DateTime.IsLeapYear(currentTime.Year);
    42. TimeZone localZone = TimeZone.CurrentTimeZone;
    43. TimeSpan currentOffset = localZone.GetUtcOffset(System.DateTime.Now);
    44. SunLight.offsetUTC=(float)currentOffset.TotalHours;
    45.  
    46. SunLight.latitude=Input.location.lastData.latitude;
    47. SunLight.longitude=Input.location.lastData.longitude;
    48.  
    49. northDirection = (((ARcamera.eulerAngles.y - Input.compass.trueHeading + 360.0f) % 360.0f) + 180.0f) % 360.0f;
    50. northDirection = AverageNorthDirection(northDirection);
    51. //SunLight.northDirection = Mathf.SmoothDampAngle(SunLight.northDirection, northDirection, ref yVelocity, smooth);
    52. SunLight.northDirection=northDirection;
    53. }
    54. #endif
    55. }
    56.  
    57. float AverageNorthDirection(float currentAngle)
    58. {
    59. if(averageAngle!=currentAngle)
    60. {
    61. angleDistance=Mathf.Abs(Mathf.DeltaAngle(averageAngle, currentAngle));
    62.  
    63. if((averageAngle>currentAngle && Mathf.Approximately(averageAngle-angleDistance, currentAngle)) || (averageAngle<currentAngle && Mathf.Approximately(currentAngle-angleDistance, averageAngle)))
    64. {
    65. averageAngle = (averageAngle*i+currentAngle) / (i+1);
    66. i++;
    67. }
    68. else
    69. {
    70. if(averageAngle>currentAngle)
    71. {
    72. averageAngle = ((averageAngle*i+averageAngle+angleDistance) / (i+1));
    73. i++;
    74. }
    75. else
    76. {
    77. averageAngle = (averageAngle*i+averageAngle-angleDistance) / (i+1);
    78. i++;
    79. if(averageAngle<0.0f)
    80. {
    81. averageAngle=averageAngle+360.0f;
    82. }
    83. }
    84. }
    85. if(i>300) i=100;
    86. }
    87. averageAngle=averageAngle % 360.0f;
    88. return averageAngle;
    89. }
    90.  
    91.  
    92. IEnumerator CompassInitialization()
    93. {
    94. yield return new WaitForSeconds(1f);
    95. #if UNITY_ANDROID || UNITY_IOS
    96. trackingCompass |= Input.compass.enabled;
    97. northDirection = (((ARcamera.eulerAngles.y - Input.compass.trueHeading + 360.0f) % 360.0f) + 180.0f) % 360.0f;
    98. SunLight.northDirection = northDirection;
    99. averageAngle=northDirection;
    100. #endif
    101. }
    102.  
    103.  
    104. }
    105.  
    106.  
    107.  
    108.  
     
    Last edited: May 5, 2022
  39. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    I have updated the script above a little and recalibrated the compass as described on this website.

    https://www.iphonetricks.org/how-to-fix-iphone-compass-not-working/

    When the compass is actually working correctly, the script works fine too. Of course, this only works as long as the compass cooperates. But this is a pure hardware problem that we can't do anything about, as long as the user uses magnetic sleeves and Apple (and Google?) doesn't allow us to manually trigger the calibration, we have to live with this problem and explain it to the user.
     
  40. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    I’ve created a new video to show how to install the fix to let it work with HDRP as explained in post #31 and post #32

     
  41. VIC20

    VIC20

    Joined:
    Jan 19, 2008
    Posts:
    2,690
    Next update will of course offer support for HDRP and URP out of the box without the need for the simple workaround which already makes it possible to use SunLight with HDRP and URP.

    The update should be released early 2024 (at least that is the plan). It will offer more artistic control of the sunlight color: light intensity, desaturation, tint color.

    Please note: SunLight will never participate in a sale again! It's already priced really low anyway.

     
    askenny likes this.