306 lines
11 KiB
C#
306 lines
11 KiB
C#
|
// Distant Lands 2024
|
||
|
// COZY: Stylized Weather 3
|
||
|
// All code included in this file is protected under the Unity Asset Store Eula
|
||
|
|
||
|
using UnityEngine;
|
||
|
using DistantLands.Cozy.Data;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Linq;
|
||
|
|
||
|
#if UNITY_EDITOR
|
||
|
using UnityEditor;
|
||
|
#endif
|
||
|
|
||
|
namespace DistantLands.Cozy
|
||
|
{
|
||
|
[ExecuteAlways]
|
||
|
public class CozyClimateModule : CozyBiomeModuleBase<CozyClimateModule>
|
||
|
{
|
||
|
|
||
|
[CozyProfile]
|
||
|
public ClimateProfile climateProfile;
|
||
|
public CozyWeather.ControlMethod controlMethod = CozyWeather.ControlMethod.profile;
|
||
|
|
||
|
|
||
|
[Tooltip("Adds an offset to the local temperature. Useful for adding biomes or climate change by location or elevation")]
|
||
|
public float localTemperatureFilter;
|
||
|
[Tooltip("Adds an offset to the local precipitation. Useful for adding biomes or climate change by location or elevation")]
|
||
|
public float localPrecipitationFilter;
|
||
|
internal float temperatureOffset;
|
||
|
internal float precipitationOffset;
|
||
|
public float currentTemperature;
|
||
|
public float currentPrecipitation;
|
||
|
|
||
|
[Range(0, 1)]
|
||
|
public float snowAmount;
|
||
|
[SerializeField]
|
||
|
private float m_SnowMeltSpeed = 0.35f;
|
||
|
[Range(0, 1)]
|
||
|
public float wetness;
|
||
|
[SerializeField]
|
||
|
private float m_DryingSpeed = 0.5f;
|
||
|
public float snowSpeed;
|
||
|
public float rainSpeed;
|
||
|
|
||
|
public override void InitializeModule()
|
||
|
{
|
||
|
isBiomeModule = GetComponent<CozyBiome>();
|
||
|
if (isBiomeModule)
|
||
|
return;
|
||
|
base.InitializeModule();
|
||
|
weatherSphere.climateModule = this;
|
||
|
AddBiome();
|
||
|
|
||
|
}
|
||
|
|
||
|
public override void CozyUpdateLoop()
|
||
|
{
|
||
|
ComputeBiomeWeights();
|
||
|
|
||
|
snowAmount += Time.deltaTime * snowSpeed;
|
||
|
|
||
|
if (snowSpeed <= 0)
|
||
|
if (currentTemperature > 32)
|
||
|
snowAmount -= Time.deltaTime * m_SnowMeltSpeed * 0.03f;
|
||
|
|
||
|
wetness += (Time.deltaTime * rainSpeed) + (-1 * m_DryingSpeed * 0.001f);
|
||
|
|
||
|
snowAmount = Mathf.Clamp01(snowAmount);
|
||
|
wetness = Mathf.Clamp01(wetness);
|
||
|
|
||
|
if (controlMethod == CozyWeather.ControlMethod.profile)
|
||
|
{
|
||
|
if (!climateProfile)
|
||
|
return;
|
||
|
|
||
|
currentTemperature = climateProfile.GetTemperature(weatherSphere) + localTemperatureFilter + temperatureOffset;
|
||
|
currentPrecipitation = Mathf.Clamp(climateProfile.GetHumidity(weatherSphere) + localPrecipitationFilter + precipitationOffset, 0, 100);
|
||
|
}
|
||
|
|
||
|
foreach (CozyClimateModule biome in biomes)
|
||
|
{
|
||
|
currentTemperature = Mathf.Lerp(currentTemperature, biome.currentTemperature, biome.weight);
|
||
|
currentPrecipitation = Mathf.Lerp(currentPrecipitation, biome.currentPrecipitation, biome.weight);
|
||
|
}
|
||
|
|
||
|
Shader.SetGlobalFloat("CZY_SnowAmount", snowAmount);
|
||
|
Shader.SetGlobalFloat("CZY_WetnessAmount", wetness);
|
||
|
}
|
||
|
|
||
|
public override void FrameReset()
|
||
|
{
|
||
|
|
||
|
temperatureOffset = 0;
|
||
|
precipitationOffset = 0;
|
||
|
|
||
|
snowSpeed = 0;
|
||
|
rainSpeed = 0;
|
||
|
|
||
|
}
|
||
|
|
||
|
public float GetTemperature()
|
||
|
{
|
||
|
if (controlMethod == CozyWeather.ControlMethod.native)
|
||
|
return currentTemperature;
|
||
|
else
|
||
|
return climateProfile.GetTemperature(weatherSphere) + localTemperatureFilter;
|
||
|
|
||
|
}
|
||
|
|
||
|
public float GetTemperature(float inTicks)
|
||
|
{
|
||
|
|
||
|
return climateProfile.GetTemperature(weatherSphere, inTicks) + localTemperatureFilter;
|
||
|
|
||
|
}
|
||
|
|
||
|
public float GetPrecipitation()
|
||
|
{
|
||
|
|
||
|
return climateProfile.GetHumidity(weatherSphere) + localPrecipitationFilter;
|
||
|
|
||
|
}
|
||
|
|
||
|
public float GetPrecipitation(float inTicks)
|
||
|
{
|
||
|
|
||
|
return climateProfile.GetHumidity(weatherSphere, inTicks) + localPrecipitationFilter;
|
||
|
}
|
||
|
|
||
|
public override void DeinitializeModule()
|
||
|
{
|
||
|
base.DeinitializeModule();
|
||
|
|
||
|
Shader.SetGlobalFloat("CZY_WindTime", 0);
|
||
|
Shader.SetGlobalVector("CZY_WindDirection", Vector3.zero);
|
||
|
|
||
|
}
|
||
|
|
||
|
public override void UpdateBiomeModule()
|
||
|
{
|
||
|
if (controlMethod == CozyWeather.ControlMethod.profile)
|
||
|
{
|
||
|
if (!climateProfile)
|
||
|
return;
|
||
|
|
||
|
currentTemperature = climateProfile.GetTemperature(weatherSphere) + localTemperatureFilter + temperatureOffset;
|
||
|
currentPrecipitation = Mathf.Clamp(climateProfile.GetHumidity(weatherSphere) + localPrecipitationFilter + precipitationOffset, 0, 100);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
#if UNITY_EDITOR
|
||
|
[CustomEditor(typeof(CozyClimateModule))]
|
||
|
[CanEditMultipleObjects]
|
||
|
public class E_ClimateModule : E_CozyModule, E_BiomeModule, IControlPanel
|
||
|
{
|
||
|
|
||
|
public static bool selection;
|
||
|
public static bool settings;
|
||
|
public static bool information;
|
||
|
SerializedProperty profile;
|
||
|
SerializedProperty controlMethod;
|
||
|
SerializedProperty currentTemperature;
|
||
|
SerializedProperty currentPrecipitation;
|
||
|
public CozyClimateModule climateModule;
|
||
|
|
||
|
public override GUIContent GetGUIContent()
|
||
|
{
|
||
|
|
||
|
//Place your module's GUI content here.
|
||
|
return new GUIContent(" Climate", (Texture)Resources.Load("Climate"), "Control temperature and humidity.");
|
||
|
|
||
|
}
|
||
|
|
||
|
void OnEnable()
|
||
|
{
|
||
|
profile = serializedObject.FindProperty("climateProfile");
|
||
|
controlMethod = serializedObject.FindProperty("controlMethod");
|
||
|
currentTemperature = serializedObject.FindProperty("currentTemperature");
|
||
|
currentPrecipitation = serializedObject.FindProperty("currentPrecipitation");
|
||
|
climateModule = (CozyClimateModule)target;
|
||
|
}
|
||
|
|
||
|
public override void GetReportsInformation()
|
||
|
{
|
||
|
|
||
|
EditorGUILayout.LabelField(GetGUIContent(), EditorStyles.toolbar);
|
||
|
EditorGUILayout.HelpBox("Currently the global ecosystem is running at " + Mathf.Round(climateModule.currentTemperature) + "°F or " + Mathf.Round((climateModule.currentTemperature - 32) * 5f / 9f) + "°C with a precipitation chance of " + Mathf.Round(climateModule.currentPrecipitation) + "%.\n" +
|
||
|
"Temperatures will " + (climateModule.currentTemperature > climateModule.GetTemperature(1) ? "drop" : "rise") + " tomorrow, bringing the temperature to " + Mathf.Round(climateModule.GetTemperature(1)) + "°F", MessageType.None);
|
||
|
EditorGUILayout.HelpBox($"Snow Amount: {climateModule.snowAmount}\nWetness: {climateModule.wetness}", MessageType.None);
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
public override void OpenDocumentationURL()
|
||
|
{
|
||
|
Application.OpenURL("https://distant-lands.gitbook.io/cozy-stylized-weather-documentation/how-it-works/modules/climate-module");
|
||
|
}
|
||
|
|
||
|
public override void DisplayInCozyWindow()
|
||
|
{
|
||
|
EditorGUI.indentLevel = 0;
|
||
|
serializedObject.Update();
|
||
|
selection = EditorGUILayout.BeginFoldoutHeaderGroup(selection, new GUIContent(" Selection"), EditorUtilities.FoldoutStyle);
|
||
|
EditorGUILayout.EndFoldoutHeaderGroup();
|
||
|
|
||
|
if (selection)
|
||
|
{
|
||
|
|
||
|
EditorGUI.indentLevel++;
|
||
|
EditorGUILayout.PropertyField(controlMethod);
|
||
|
if (controlMethod.intValue == 1)
|
||
|
EditorGUILayout.PropertyField(profile);
|
||
|
EditorGUI.indentLevel--;
|
||
|
|
||
|
}
|
||
|
|
||
|
if (controlMethod.intValue == 1)
|
||
|
{
|
||
|
settings = EditorGUILayout.BeginFoldoutHeaderGroup(settings, new GUIContent(" Global Settings"), EditorUtilities.FoldoutStyle);
|
||
|
EditorGUILayout.EndFoldoutHeaderGroup();
|
||
|
|
||
|
if (settings)
|
||
|
{
|
||
|
EditorGUI.indentLevel++;
|
||
|
if (profile.objectReferenceValue)
|
||
|
CreateEditor(profile.objectReferenceValue).OnInspectorGUI();
|
||
|
else
|
||
|
EditorGUILayout.HelpBox("Assign a profile to begin editing the climate!", MessageType.Error);
|
||
|
|
||
|
|
||
|
EditorGUILayout.PropertyField(serializedObject.FindProperty("m_SnowMeltSpeed"));
|
||
|
EditorGUILayout.PropertyField(serializedObject.FindProperty("m_DryingSpeed"));
|
||
|
|
||
|
EditorGUI.indentLevel--;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
information = EditorGUILayout.BeginFoldoutHeaderGroup(information, new GUIContent(" Current Information"), EditorUtilities.FoldoutStyle);
|
||
|
EditorGUILayout.EndFoldoutHeaderGroup();
|
||
|
|
||
|
if (information)
|
||
|
{
|
||
|
|
||
|
EditorGUI.indentLevel++;
|
||
|
EditorGUILayout.PropertyField(currentTemperature);
|
||
|
EditorGUILayout.PropertyField(currentPrecipitation);
|
||
|
EditorGUILayout.Space();
|
||
|
EditorGUILayout.PropertyField(serializedObject.FindProperty("snowAmount"));
|
||
|
EditorGUILayout.PropertyField(serializedObject.FindProperty("wetness"));
|
||
|
EditorGUI.indentLevel--;
|
||
|
|
||
|
}
|
||
|
|
||
|
serializedObject.ApplyModifiedProperties();
|
||
|
|
||
|
}
|
||
|
public void GetControlPanel()
|
||
|
{
|
||
|
EditorGUILayout.PropertyField(currentTemperature);
|
||
|
EditorGUILayout.PropertyField(currentPrecipitation);
|
||
|
EditorGUILayout.Space();
|
||
|
EditorGUILayout.PropertyField(serializedObject.FindProperty("snowAmount"));
|
||
|
EditorGUILayout.PropertyField(serializedObject.FindProperty("wetness"));
|
||
|
}
|
||
|
|
||
|
public void DrawBiomeReports()
|
||
|
{
|
||
|
EditorGUILayout.PropertyField(currentTemperature);
|
||
|
EditorGUILayout.PropertyField(currentPrecipitation);
|
||
|
EditorGUILayout.Space();
|
||
|
EditorGUILayout.PropertyField(serializedObject.FindProperty("snowAmount"));
|
||
|
EditorGUILayout.PropertyField(serializedObject.FindProperty("wetness"));
|
||
|
}
|
||
|
|
||
|
public void DrawInlineBiomeUI()
|
||
|
{
|
||
|
if (!target) return;
|
||
|
serializedObject.Update();
|
||
|
EditorGUILayout.PropertyField(controlMethod);
|
||
|
if (controlMethod.intValue == 1)
|
||
|
{
|
||
|
EditorGUILayout.PropertyField(profile);
|
||
|
|
||
|
|
||
|
EditorGUI.indentLevel++;
|
||
|
if (profile.objectReferenceValue)
|
||
|
CreateEditor(profile.objectReferenceValue).OnInspectorGUI();
|
||
|
else
|
||
|
EditorGUILayout.HelpBox("Assign a profile to begin editing the climate!", MessageType.Error);
|
||
|
|
||
|
}
|
||
|
|
||
|
EditorGUILayout.Space();
|
||
|
EditorGUILayout.PropertyField(currentTemperature);
|
||
|
EditorGUILayout.PropertyField(currentPrecipitation);
|
||
|
|
||
|
EditorGUI.indentLevel--;
|
||
|
serializedObject.ApplyModifiedProperties();
|
||
|
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
}
|