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? ![]()
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 ![]()
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…
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.
No Problem, I’m on it again and it seems I’m almost there. When I find the solution, I’ll post it here ![]()
Great, thank you.
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.
/* Don't forget to request the permission to use the location service on the device.
Location.Start() takes a while so make sure you wait for it to finish.
Unity Documentation has a good example how to use it!*/
Input.location.Start();
Input.compass.enabled = true;
/* Then get the compass' true heading and the camera's y-axis rotation and calculate the difference between the two.
(Modulo to get always positive values you need for the Sunlight north direction value)*/
float newValue = (cam.transform.eulerAngles.y - Input.compass.trueHeading + 360) % 360;
// Finally Turn it around 180°!
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:
public void ManualResetNorthDirection()
{
float newValue = (cam.transform.eulerAngles.y + 360) % 360;
// Turn around 180°!
sunLight.northDirection = (newValue + 180) % 360;
}
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)
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: WOTA: U-Boat Compass
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:
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:
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.
using System.Collections;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Hessburg;
[ExecuteInEditMode]
public class CopySunLightRotation : MonoBehaviour
{
public SunLight SunLight; // set in inspector
private Transform SkyBoxLightTransform;
private Light SkyBoxLight;
private Light SunLightSkyboxLight;
private Light SunLightSceneLight;
private LensFlare SunLightLensFlare;
private Transform SunLightSkyboxLightTransform;
private GameObject SunLightSkyboxLightGameObject;
private GameObject SunLightSceneLightGameObject;
private GameObject SunLightLensFlareGameObject;
void Start()
{
if (SunLight != null)
{
SunLightSkyboxLight = SunLight.GetSkyboxLight();
SunLightSceneLight = SunLight.GetSceneLight();
SunLightLensFlare = SunLight.GetLensFlare();
SunLightSkyboxLightTransform = SunLightSkyboxLight.transform;
SunLightSkyboxLightGameObject = SunLightSkyboxLight.gameObject;
SunLightSceneLightGameObject = SunLightSceneLight.gameObject;
SunLightLensFlareGameObject = SunLightLensFlare.gameObject;
SunLightSkyboxLightGameObject.SetActive(false);
SunLightSceneLightGameObject.SetActive(false);
SunLightLensFlareGameObject.SetActive(false);
SkyBoxLightTransform=this.transform;
SkyBoxLight=this.GetComponent<Light>();
}
}
// Update is called once per frame
void LateUpdate()
{
SkyBoxLightTransform.rotation=SunLightSkyboxLightTransform.rotation;
SkyBoxLight.color=SunLightSceneLight.color;
}
}
-
download (or create) the script https://www.hessburg.com/downloads/SunLight/CopySunLightRotation.zip
-
Attach the script to the directional light which you are using with the URP / HDRP sky
-
Place the SunLight prefab into your scene.
-
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
To use the fix above with HDRP you will need to replace the file SunLightEditorHelper.cs with this one:
https://www.hessburg.com/downloads/SunLight/SunLightEditorHelper.zip
The original file is located in „Assets/Hessburg - SunLight/SunLight/Scripts/CS"
Hey, could you tell me what is the North direction assumed by your tool ? -z ?
Yes, you are right. North is Unity’s negative Z direction (backward direction of the blue arrow).
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
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.
Hello VIC20,
thank you so much for your response.
I gladly wait for your test example and will definitely test it.
Thanks again!
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.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
using Hessburg;
public class SetNorthForAR : MonoBehaviour
{
public float smooth = 0.2f;
private float yVelocity = 0.0f;
private SunLight SunLight;
private Transform ARcamera;
private bool trackingCompass = false;
private float northDirection;
private float averageAngle;
private float angleDistance;
private int i;
void Start()
{
ARcamera=GameObject.Find("AR Camera").transform;
SunLight=GameObject.Find("SunLight").GetComponent<SunLight>();
#if UNITY_ANDROID || UNITY_IOS
Input.compass.enabled = true;
Input.location.Start();
StartCoroutine(CompassInitialization());
#endif
}
void Update()
{
#if UNITY_ANDROID || UNITY_IOS
if (trackingCompass)
{
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;
SunLight.latitude=Input.location.lastData.latitude;
SunLight.longitude=Input.location.lastData.longitude;
northDirection = (((ARcamera.eulerAngles.y - Input.compass.trueHeading + 360.0f) % 360.0f) + 180.0f) % 360.0f;
northDirection = AverageNorthDirection(northDirection);
//SunLight.northDirection = Mathf.SmoothDampAngle(SunLight.northDirection, northDirection, ref yVelocity, smooth);
SunLight.northDirection=northDirection;
}
#endif
}
float AverageNorthDirection(float currentAngle)
{
if(averageAngle!=currentAngle)
{
angleDistance=Mathf.Abs(Mathf.DeltaAngle(averageAngle, currentAngle));
if((averageAngle>currentAngle && Mathf.Approximately(averageAngle-angleDistance, currentAngle)) || (averageAngle<currentAngle && Mathf.Approximately(currentAngle-angleDistance, averageAngle)))
{
averageAngle = (averageAngle*i+currentAngle) / (i+1);
i++;
}
else
{
if(averageAngle>currentAngle)
{
averageAngle = ((averageAngle*i+averageAngle+angleDistance) / (i+1));
i++;
}
else
{
averageAngle = (averageAngle*i+averageAngle-angleDistance) / (i+1);
i++;
if(averageAngle<0.0f)
{
averageAngle=averageAngle+360.0f;
}
}
}
if(i>300) i=100;
}
averageAngle=averageAngle % 360.0f;
return averageAngle;
}
IEnumerator CompassInitialization()
{
yield return new WaitForSeconds(1f);
#if UNITY_ANDROID || UNITY_IOS
trackingCompass |= Input.compass.enabled;
northDirection = (((ARcamera.eulerAngles.y - Input.compass.trueHeading + 360.0f) % 360.0f) + 180.0f) % 360.0f;
SunLight.northDirection = northDirection;
averageAngle=northDirection;
#endif
}
}
I have updated the script above a little and recalibrated the compass as described on this website.
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.