Page 1 of 1

[HOWTO] How To: Save Enviro - Sky and Weather

Posted: Tue Jul 21, 2020 7:37 pm
by Tony Li
You can use the package below to save Henrik Haupt's Enviro - Sky and Weather with the Pixel Crushers Save System. The package contains the script shown below and a test scene.

PixelCrushers_EnviroSaver_2020-07-21.unitypackage

EnviroSaver.cs

Code: Select all

using System;
using PixelCrushers;

/// <summary>
/// Pixel Crushers Save System saver for Hendrik Haupt's Enviro.
/// </summary>
public class EnviroSaver : Saver
{
    [Serializable]
    public class Data
    {
        public float timeOfDay;
        public int days;
        public int years;
    }

    private Data m_data = new Data();

    public override string RecordData()
    {
        m_data.timeOfDay = EnviroSkyMgr.instance.GetTimeOfDay();
        m_data.days = EnviroSkyMgr.instance.Time.Days;
        m_data.years = EnviroSkyMgr.instance.Time.Years;
        return SaveSystem.Serialize(m_data);
    }

    public override void ApplyData(string s)
    {
        if (string.IsNullOrEmpty(s)) return;
        m_data = SaveSystem.Deserialize<Data>(s, m_data);
        if (m_data == null)
        {
            m_data = new Data();
        }
        else
        {
            EnviroSkyMgr.instance.SetTimeOfDay(m_data.timeOfDay);
            EnviroSkyMgr.instance.Time.Days = m_data.days;
            EnviroSkyMgr.instance.Time.Years = m_data.years;
        }
    }

}

Re: How To: Save Enviro - Sky and Weather

Posted: Wed Jul 22, 2020 4:58 pm
by alsoknownas-stefan
Cool, I was looking for a weather/day/night system that could hook into Dialogue System. :D

Does this require any work on the Enviro side?

Re: How To: Save Enviro - Sky and Weather

Posted: Wed Jul 22, 2020 5:36 pm
by Tony Li
Only untick the Enviro manager's Don't Destroy On Load checkbox. No other Enviro changes needed.

If you're using the Dialogue System, it also includes Unistorm integration in case you'd prefer to use Unistorm instead of Enviro.

Re: How To: Save Enviro - Sky and Weather

Posted: Wed Oct 28, 2020 3:21 pm
by alsoknownas-stefan
Hi Tony,

It has been a while, hope you are doing fine.

I am having trouble integrating Enviro. I got your example to work, time becomes what it was on the moment of saving when loading (scene transitions also work fine). I am trying to do the same for the weather. I am having no luck. It seems that the weather is being overwritten with the startWeatherPreset when loading the game/when Enviro Sky Manager enters the scene. My small lizard brain came up with a few ideas (using ChangeWeatherInstant(); changing startWeatherPreset and currentActiveWeatherPreset on load), but alas on load it still jumps to the starting weather...
Do you have any ideas? Code:



using System;
using PixelCrushers;

/// <summary>
/// Pixel Crushers Save System saver for Hendrik Haupt's Enviro.
/// </summary>
public class EnviroSaver : Saver
{
[Serializable]
public class Data
{
public float timeOfDay;
public int days;
public int years;
public EnviroWeatherPreset weather;
}

private Data m_data = new Data();

public override string RecordData()
{
m_data.timeOfDay = EnviroSkyMgr.instance.GetTimeOfDay();
m_data.days = EnviroSkyMgr.instance.Time.Days;
m_data.years = EnviroSkyMgr.instance.Time.Years;
m_data.weather = EnviroSkyMgr.instance.Weather.currentActiveWeatherPreset;
return SaveSystem.Serialize(m_data);
}

public override void ApplyData(string s)
{
if (string.IsNullOrEmpty(s)) return;
m_data = SaveSystem.Deserialize<Data>(s, m_data);
if (m_data == null)
{
m_data = new Data();
}
else
{
EnviroSkyMgr.instance.SetTimeOfDay(m_data.timeOfDay);
EnviroSkyMgr.instance.Time.Days = m_data.days;
EnviroSkyMgr.instance.Time.Years = m_data.years;
EnviroSkyLite.instance.Weather.startWeatherPreset = m_data.weather;
EnviroSky.instance.Weather.startWeatherPreset = m_data.weather;
EnviroSkyMgr.instance.Weather.currentActiveWeatherPreset = m_data.weather;
EnviroSkyMgr.instance.ChangeWeatherInstant(m_data.weather);

}
}

}

Re: How To: Save Enviro - Sky and Weather

Posted: Wed Oct 28, 2020 4:04 pm
by Tony Li
Hi,

I haven't had a chance to test it, but maybe Enviro takes a frame or two to initialize the weather. If that's the case, you can try setting the Save System component's 'Frames To Wait Before Apply Data' to a higher value such as 2 or 3. Or you can make ApplyData() kick off a coroutine that waits a few frames before calling ChangeWeatherInstant().

Alternatively, you can implement ApplyDataImmediate() to change the presets before Enviro sets up the scene's weather. ApplyDataImmediate() will be called as soon as the scene has finished loading.

Re: How To: Save Enviro - Sky and Weather

Posted: Thu Oct 29, 2020 2:51 am
by alsoknownas-stefan
Hi Tony,

You never cease to amaze me. It works. :D

I set the Save System component's 'Frames To Wait Before Apply Data' to 3. I made a small change to my EnviroSaver script and now it works perfectly, using save and load functions and during scene transitions. Thank you again!

Final script of the custom saver for Enviro:

using System;
using PixelCrushers;

/// <summary>
/// Pixel Crushers Save System saver for Hendrik Haupt's Enviro.
/// </summary>
public class EnviroSaver : Saver
{
[Serializable]
public class Data
{
public float timeOfDay;
public int days;
public int years;
public EnviroWeatherPreset weather;
}

private Data m_data = new Data();

public override string RecordData()
{
m_data.timeOfDay = EnviroSkyMgr.instance.GetTimeOfDay();
m_data.days = EnviroSkyMgr.instance.Time.Days;
m_data.years = EnviroSkyMgr.instance.Time.Years;
m_data.weather = EnviroSkyMgr.instance.Weather.currentActiveWeatherPreset;
return SaveSystem.Serialize(m_data);
}

public override void ApplyData(string s)
{
if (string.IsNullOrEmpty(s)) return;
m_data = SaveSystem.Deserialize<Data>(s, m_data);
if (m_data == null)
{
m_data = new Data();
}
else
{
EnviroSkyMgr.instance.SetTimeOfDay(m_data.timeOfDay);
EnviroSkyMgr.instance.Time.Days = m_data.days;
EnviroSkyMgr.instance.Time.Years = m_data.years;
EnviroSkyMgr.instance.ChangeWeatherInstant(m_data.weather);

}
}

}

Re: How To: Save Enviro - Sky and Weather

Posted: Thu Oct 29, 2020 9:41 am
by Tony Li
Thank you for sharing!

BTW, you can retain code formatting in your posts by wrapping it in code tags. Select the code text and click the </> button.

Re: [HOWTO] How To: Save Enviro - Sky and Weather

Posted: Tue Mar 23, 2021 9:47 am
by MeishinTale
Hiho, thanks for this implementation !

Added temperature, snow and wetness in case weather was in transition during the save.
Changed Weather saving variable to a string since saving the entire WeatherPreset is heavier for no gain.
Also added a coroutine cf previous,

EnviroSaver.cs

Code: Select all

using System.Collections;
using UnityEngine;
using System;
using PixelCrushers;

public class EnviroSaver : Saver
{
    public bool LoadWetness = true, LoadSnow = true;
    public bool LoadSeasons = true, LoadWeather = true, LoadTemperature = true;

    [Serializable]
    public class Data
    {
        public float timeOfDay;
        public int days;
        public int years;
        public int season;
        public string weather;
        public float wetAmount;
        public float snowAmount;
        public float temp;
    }

    private Data m_data = new Data();

    public override string RecordData()
    {
        m_data.timeOfDay = EnviroSkyMgr.instance.GetTimeOfDay();
        m_data.days = EnviroSkyMgr.instance.Time.Days;
        m_data.years = EnviroSkyMgr.instance.Time.Years;

        m_data.weather = EnviroSky.instance.Weather.currentActiveWeatherPreset?.Name;
        m_data.season = (int)EnviroSky.instance.Seasons.currentSeasons;
        m_data.snowAmount = EnviroSky.instance.Weather.curSnowStrength;
        m_data.wetAmount = EnviroSky.instance.Weather.curWetness;
        m_data.temp = EnviroSky.instance.Weather.currentTemperature;

        return SaveSystem.Serialize(m_data);
    }

    public override void ApplyData(string s)
    {
        if (string.IsNullOrEmpty(s)) return;
        m_data = SaveSystem.Deserialize<Data>(s, m_data);
        if (m_data == null)
            m_data = new Data();
        else
            StartCoroutine(WaitAndLoad());
    }

    private IEnumerator WaitAndLoad()
    {
        // Wait for next frame
        yield return null;

        load();
    }

    private void load()
    {
        EnviroSkyMgr.instance.SetTimeOfDay(m_data.timeOfDay);
        EnviroSkyMgr.instance.Time.Days = m_data.days;
        EnviroSkyMgr.instance.Time.Years = m_data.years;
        // Weather
        if (LoadWeather) loadWeather();
        
        if (LoadSeasons) EnviroSkyMgr.instance.Seasons.currentSeasons = (EnviroSeasons.Seasons)m_data.season;
        
        if (LoadSnow) EnviroSkyMgr.instance.Weather.curSnowStrength = m_data.snowAmount;
        
        if (LoadWetness) EnviroSkyMgr.instance.Weather.curWetness = m_data.wetAmount;
        
        if (LoadTemperature) EnviroSkyMgr.instance.Weather.currentTemperature = m_data.temp;

    }

    private void loadWeather()
    {
        int index = EnviroSkyMgr.instance.Weather.weatherPresets.IndexWhere(x => x.Name == m_data.weather);
        if (index > -1)
            EnviroSkyMgr.instance.ChangeWeatherInstant(index);
        else
            Debug.LogError(string.Format("Weather {0} from saved is not in enviro presets' list", m_data.weather));
    }
}


Re: [HOWTO] How To: Save Enviro - Sky and Weather

Posted: Tue Mar 23, 2021 10:22 am
by Tony Li
Thanks for sharing!

Re: [HOWTO] How To: Save Enviro - Sky and Weather

Posted: Wed Apr 07, 2021 11:46 pm
by CruttMutt
Thank you everyone here! You are all amazing :o <3