Files
Fishing2/Assets/Plugins/Azure[Sky] Dynamic Skybox/Core/Scripts/AzureWeatherSystem.cs
2026-01-25 11:25:49 +08:00

599 lines
37 KiB
C#

using System;
using Unity.VisualScripting;
using System.Collections.Generic;
namespace UnityEngine.AzureSky
{
/// <summary>Class that handles the weather features.</summary>
[Serializable]
public sealed class AzureWeatherSystem
{
/// <summary>The list containing the weather property groups.</summary>
public List<AzureWeatherPropertyGroup> weatherPropertyGroupList { get => m_weatherPropertyGroupList; set => m_weatherPropertyGroupList = value; }
[SerializeField] private List<AzureWeatherPropertyGroup> m_weatherPropertyGroupList = new List<AzureWeatherPropertyGroup>();
/// <summary>The list containing the global weather presets.</summary>
public List<AzureGlobalWeather> globalWeatherList { get => m_globalWeatherList; set => m_globalWeatherList = value; }
[SerializeField] private List<AzureGlobalWeather> m_globalWeatherList = new List<AzureGlobalWeather>();
/// <summary>List of local weather zones arranged according to its priorities.</summary>
public List<AzureWeatherZone> weatherZoneList { get => m_weatherZoneList; set => m_weatherZoneList = value; }
[SerializeField] private List<AzureWeatherZone> m_weatherZoneList = new List<AzureWeatherZone>();
/// <summary>The list containing the settings for instantiation of the thunder prefabs.</summary>
public List<AzureThunderSettings> thunderSettingsList { get => m_thunderSettingsList; set => m_thunderSettingsList = value; }
[SerializeField] private List<AzureThunderSettings> m_thunderSettingsList = new List<AzureThunderSettings>();
/// <summary>The current weather preset.</summary>
public AzureWeatherPreset currentWeatherPreset { get => m_currentWeatherPreset; set => m_currentWeatherPreset = value; }
[SerializeField] private AzureWeatherPreset m_currentWeatherPreset = null;
/// <summary>Stores the target weather preset when runing a global weather transition.</summary>
public AzureWeatherPreset targetWeatherPreset => m_targetWeatherPreset;
private AzureWeatherPreset m_targetWeatherPreset = null;
/// <summary>The trigger used to detect if it is entering a local weather zone.</summary>
public Transform weatherZoneTrigger { get => m_weatherZoneTrigger; set => m_weatherZoneTrigger = value; }
[SerializeField] private Transform m_weatherZoneTrigger = null;
/// <summary>The time used to evaluate the curves and gradients.</summary>
public float evaluationTime { get => m_evaluationTime; set => m_evaluationTime = value; }
[SerializeField] private float m_evaluationTime = 6.5f;
[SerializeField] private float m_evaluationTimeGradient = 0.27f; // 6.5f / 24f
/// <summary>There is a global weather transition in progress?</summary>
public bool isWeatherChanging => m_isWeatherChanging;
private bool m_isWeatherChanging = false;
/// <summary>Stores the current global weather index in use.</summary>
public int globalWeatherIndex => m_globalWeatherIndex;
private int m_globalWeatherIndex = 0;
/// <summary>Stores the progress of a global weather transition.</summary>
public float weatherTransitionProgress => m_weatherTransitionProgress;
[SerializeField] private float m_weatherTransitionProgress = 0.0f;
/// <summary>Used internally to perform a global weather transition.</summary>
private float m_weatherTransitionStart = 0.0f;
/// <summary>Used internally to perform a global weather transition.</summary>
private float m_weatherTransitionLength = 0.0f;
/// <summary>Used internally to perform a local weather zone transition.</summary>
private Vector3 m_weatherZoneTriggerPosition = Vector3.zero;
/// <summary>Used internally to perform a local weather zone transition.</summary>
private Collider m_weatherZoneCollider = null;
/// <summary>Used internally to perform a local weather zone transition.</summary>
private float m_weatherZoneClosestDistanceSqr = 0.0f;
/// <summary>Used internally to perform a local weather zone transition.</summary>
private Vector3 m_weatherZoneClosestPoint = Vector3.zero;
/// <summary>Used internally to perform a local weather zone transition.</summary>
private float m_weatherZoneDistance = 0.0f;
/// <summary>Used internally to perform a local weather zone transition.</summary>
private float m_weatherZoneBlendDistanceSqr = 0.0f;
/// <summary>Used internally to perform a local weather zone transition.</summary>
private float m_weatherZoneInterpolationFactor = 0.0f;
/// <summary>Used internally to perform the transition ramp curve of each weather group.</summary>
private float m_weatherGroupRampTime = 0.0f;
/// <summary>Used internally to perform the direction and position weather transitions.</summary>
private Vector3 m_vector3Angle;
/// <summary>Called just before the first Update() of the AzureCoreSystem script.</summary>
public void Start()
{
InitializeCurrentWeatherPreset();
InitializePropertyTargets();
UpdateWeatherSystem();
OverrideTargetProperties();
}
/// <summary>Performs a complete update in the weather system. Handled by the Update() of the AzureCoreSystem script.</summary>
public void UpdateWeatherSystem()
{
AzureNotificationCenter.Invoke.OnBeforeWeatherSystemUpdateCallback(this);
m_evaluationTimeGradient = m_evaluationTime / 24f;
if (!m_isWeatherChanging)
{
EvaluateCurrentWeather();
}
else
{
// Performs the global weather transition
m_weatherTransitionProgress = Mathf.Clamp01((Time.time - m_weatherTransitionStart) / m_weatherTransitionLength);
EvaluateGlobalWeatherTransition(m_currentWeatherPreset, m_targetWeatherPreset, m_weatherTransitionProgress);
// Ends the global weather transition
if (Mathf.Abs(m_weatherTransitionProgress - 1.0f) <= 0.0f)
{
m_isWeatherChanging = false;
m_weatherTransitionProgress = 0.0f;
m_weatherTransitionStart = 0.0f;
m_currentWeatherPreset = m_targetWeatherPreset;
AzureNotificationCenter.Invoke.OnWeatherTransitionEndCallback(this);
}
}
// Computes weather zones influence
// Based on Unity's Post Processing v2
if (!m_weatherZoneTrigger)
{
AzureNotificationCenter.Invoke.OnAfterWeatherSystemUpdateCallback(this);
return;
}
m_weatherZoneTriggerPosition = m_weatherZoneTrigger.position;
// Traverse all weather zones in the weather zone list
foreach (AzureWeatherZone weatherZone in m_weatherZoneList)
{
// Skip if the list index is null
if (weatherZone == null)
continue;
// If weather zone has no collider, skip it as it's useless
m_weatherZoneCollider = weatherZone.colliderVolume;
if (!m_weatherZoneCollider)
continue;
// Skip if the collider or the game object is disabled
if (!m_weatherZoneCollider.enabled || !m_weatherZoneCollider.gameObject.activeInHierarchy)
continue;
// Find closest distance to weather zone, 0 means it's inside it
m_weatherZoneClosestDistanceSqr = float.PositiveInfinity;
m_weatherZoneClosestPoint = m_weatherZoneCollider.ClosestPoint(m_weatherZoneTriggerPosition); // 5.6-only API
m_weatherZoneDistance = ((m_weatherZoneClosestPoint - m_weatherZoneTriggerPosition) / 2f).sqrMagnitude;
if (m_weatherZoneDistance < m_weatherZoneClosestDistanceSqr)
m_weatherZoneClosestDistanceSqr = m_weatherZoneDistance;
m_weatherZoneCollider = null;
m_weatherZoneBlendDistanceSqr = weatherZone.blendDistance * weatherZone.blendDistance;
// Weather zone has no influence, ignore it
// Note: Weather zone doesn't do anything when `closestDistanceSqr = blendDistSqr` but
// we can't use a >= comparison as blendDistSqr could be set to 0 in which
// case weather zone would have total influence
if (m_weatherZoneClosestDistanceSqr > m_weatherZoneBlendDistanceSqr)
continue;
// Weather zone has influence
m_weatherZoneInterpolationFactor = 1f;
if (m_weatherZoneBlendDistanceSqr > 0f)
m_weatherZoneInterpolationFactor = 1f - (m_weatherZoneClosestDistanceSqr / m_weatherZoneBlendDistanceSqr);
// No need to clamp01 the interpolation factor as it'll always be in [0 <-> 1] range
EvaluateWeatherZonesInfluence(weatherZone.weatherPreset, m_weatherZoneInterpolationFactor);
}
AzureNotificationCenter.Invoke.OnAfterWeatherSystemUpdateCallback(this);
}
/// <summary>Gets the output values from the weather properties and uses them to override the targets.</summary>
public void OverrideTargetProperties()
{
AzureNotificationCenter.Invoke.OnBeforeOverrideUpdateCallback(this);
for (int i = 0; i < m_weatherPropertyGroupList.Count; i++)
{
if (m_weatherPropertyGroupList[i].isEnabled == false)
continue;
for (int j = 0; j < m_weatherPropertyGroupList[i].weatherPropertyList.Count; j++)
{
if (m_weatherPropertyGroupList[i].weatherPropertyList[j].overrideMode == AzureWeatherPropertyOverrideMode.Off)
continue;
switch (m_weatherPropertyGroupList[i].weatherPropertyList[j].propertyType)
{
case AzureWeatherPropertyType.Float:
case AzureWeatherPropertyType.Curve:
switch (m_weatherPropertyGroupList[i].weatherPropertyList[j].targetType)
{
case AzureWeatherPropertyTargetType.Property:
m_weatherPropertyGroupList[i].weatherPropertyList[j].propertyInfo?.SetValueOptimized(m_weatherPropertyGroupList[i].weatherPropertyList[j].targetComponent, m_weatherPropertyGroupList[i].weatherPropertyList[j].floatOutput);
break;
case AzureWeatherPropertyTargetType.Field:
m_weatherPropertyGroupList[i].weatherPropertyList[j].fieldInfo?.SetValueOptimized(m_weatherPropertyGroupList[i].weatherPropertyList[j].targetComponent, m_weatherPropertyGroupList[i].weatherPropertyList[j].floatOutput);
break;
case AzureWeatherPropertyTargetType.MaterialProperty:
m_weatherPropertyGroupList[i].weatherPropertyList[j].targetMaterial?.SetFloat(m_weatherPropertyGroupList[i].weatherPropertyList[j].targetPropertyName, m_weatherPropertyGroupList[i].weatherPropertyList[j].floatOutput);
break;
case AzureWeatherPropertyTargetType.GlobalShaderUniform:
Shader.SetGlobalFloat(m_weatherPropertyGroupList[i].weatherPropertyList[j].targetPropertyName, m_weatherPropertyGroupList[i].weatherPropertyList[j].floatOutput);
break;
case AzureWeatherPropertyTargetType.GlobalProperty:
m_weatherPropertyGroupList[i].weatherPropertyList[j].propertyInfo?.SetValue(m_weatherPropertyGroupList[i].weatherPropertyList[j].targetGlobalType, m_weatherPropertyGroupList[i].weatherPropertyList[j].floatOutput);
break;
case AzureWeatherPropertyTargetType.GlobalField:
m_weatherPropertyGroupList[i].weatherPropertyList[j].fieldInfo?.SetValue(m_weatherPropertyGroupList[i].weatherPropertyList[j].targetGlobalType, m_weatherPropertyGroupList[i].weatherPropertyList[j].floatOutput);
break;
}
break;
case AzureWeatherPropertyType.Color:
case AzureWeatherPropertyType.Gradient:
switch (m_weatherPropertyGroupList[i].weatherPropertyList[j].targetType)
{
case AzureWeatherPropertyTargetType.Property:
m_weatherPropertyGroupList[i].weatherPropertyList[j].propertyInfo?.SetValueOptimized(m_weatherPropertyGroupList[i].weatherPropertyList[j].targetComponent, m_weatherPropertyGroupList[i].weatherPropertyList[j].colorOutput);
break;
case AzureWeatherPropertyTargetType.Field:
m_weatherPropertyGroupList[i].weatherPropertyList[j].fieldInfo?.SetValueOptimized(m_weatherPropertyGroupList[i].weatherPropertyList[j].targetComponent, m_weatherPropertyGroupList[i].weatherPropertyList[j].colorOutput);
break;
case AzureWeatherPropertyTargetType.MaterialProperty:
m_weatherPropertyGroupList[i].weatherPropertyList[j].targetMaterial?.SetColor(m_weatherPropertyGroupList[i].weatherPropertyList[j].targetPropertyName, m_weatherPropertyGroupList[i].weatherPropertyList[j].colorOutput);
break;
case AzureWeatherPropertyTargetType.GlobalShaderUniform:
Shader.SetGlobalColor(m_weatherPropertyGroupList[i].weatherPropertyList[j].targetPropertyName, m_weatherPropertyGroupList[i].weatherPropertyList[j].colorOutput);
break;
case AzureWeatherPropertyTargetType.GlobalProperty:
m_weatherPropertyGroupList[i].weatherPropertyList[j].propertyInfo?.SetValue(m_weatherPropertyGroupList[i].weatherPropertyList[j].targetGlobalType, m_weatherPropertyGroupList[i].weatherPropertyList[j].colorOutput);
break;
case AzureWeatherPropertyTargetType.GlobalField:
m_weatherPropertyGroupList[i].weatherPropertyList[j].fieldInfo?.SetValue(m_weatherPropertyGroupList[i].weatherPropertyList[j].targetGlobalType, m_weatherPropertyGroupList[i].weatherPropertyList[j].colorOutput);
break;
}
break;
case AzureWeatherPropertyType.Direction:
case AzureWeatherPropertyType.Position:
switch (m_weatherPropertyGroupList[i].weatherPropertyList[j].targetType)
{
case AzureWeatherPropertyTargetType.Property:
m_weatherPropertyGroupList[i].weatherPropertyList[j].propertyInfo?.SetValueOptimized(m_weatherPropertyGroupList[i].weatherPropertyList[j].targetComponent, m_weatherPropertyGroupList[i].weatherPropertyList[j].vector3Output);
break;
case AzureWeatherPropertyTargetType.Field:
m_weatherPropertyGroupList[i].weatherPropertyList[j].fieldInfo?.SetValueOptimized(m_weatherPropertyGroupList[i].weatherPropertyList[j].targetComponent, m_weatherPropertyGroupList[i].weatherPropertyList[j].vector3Output);
break;
case AzureWeatherPropertyTargetType.MaterialProperty:
m_weatherPropertyGroupList[i].weatherPropertyList[j].targetMaterial?.SetVector(m_weatherPropertyGroupList[i].weatherPropertyList[j].targetPropertyName, m_weatherPropertyGroupList[i].weatherPropertyList[j].vector3Output);
break;
case AzureWeatherPropertyTargetType.GlobalShaderUniform:
Shader.SetGlobalVector(m_weatherPropertyGroupList[i].weatherPropertyList[j].targetPropertyName, m_weatherPropertyGroupList[i].weatherPropertyList[j].vector3Output);
break;
case AzureWeatherPropertyTargetType.GlobalProperty:
m_weatherPropertyGroupList[i].weatherPropertyList[j].propertyInfo?.SetValue(m_weatherPropertyGroupList[i].weatherPropertyList[j].targetGlobalType, m_weatherPropertyGroupList[i].weatherPropertyList[j].vector3Output);
break;
case AzureWeatherPropertyTargetType.GlobalField:
m_weatherPropertyGroupList[i].weatherPropertyList[j].fieldInfo?.SetValue(m_weatherPropertyGroupList[i].weatherPropertyList[j].targetGlobalType, m_weatherPropertyGroupList[i].weatherPropertyList[j].vector3Output);
break;
}
break;
}
}
}
AzureNotificationCenter.Invoke.OnAfterOverrideUpdateCallback(this);
}
#if UNITY_EDITOR
public void OnEditorUpdate()
{
m_evaluationTimeGradient = m_evaluationTime / 24f;
InitializeCurrentWeatherPreset();
EvaluateCurrentWeather();
}
#endif
/// <summary>Instantiates a thunder prefab in the scene using as position the especification from the thunder settings list. When the thunder sound is over, the instance is automatically deleted.</summary>
/// Note that in this case, you only need to pass the element index as parameter, the position will the one you set in the Inspector of the thunder settings list.
public void InstantiateThunderPrefab(int index)
{
if (m_thunderSettingsList.Count <= 0) return;
if (m_thunderSettingsList[index].transform == null) return;
Object.Instantiate(m_thunderSettingsList[index].transform, m_thunderSettingsList[index].position, Quaternion.identity);
}
/// <summary>Instantiates a thunder prefab in the scene using a Vector3 parameter as position. When the thunder sound is over, the instance is automatically deleted.</summary>
/// Note that in this case, you also need to pass the instantiation position as parameter, the position in the Inspector of the thunder settings list will be ignored.
public void InstantiateThunderPrefab(int index, Vector3 position)
{
if (m_thunderSettingsList.Count <= 0) return;
if (m_thunderSettingsList[index].transform == null) return;
Object.Instantiate(m_thunderSettingsList[index].transform, position, Quaternion.identity);
}
/// <summary>Starts a global weather transition using the preset from the global weather list. It changes the weather index to the selected one.</summary>
public void SetGlobalWeather(int index)
{
index = Mathf.Clamp(index, 0, m_globalWeatherList.Count);
if (m_globalWeatherList[index].weatherPreset == null) return;
if (m_globalWeatherIndex == index) return;
if (m_isWeatherChanging) return;
m_targetWeatherPreset = m_globalWeatherList[index].weatherPreset;
m_weatherTransitionLength = m_globalWeatherList[index].transitionTime;
m_weatherTransitionProgress = 0.0f;
m_weatherTransitionStart = Time.time;
m_globalWeatherIndex = index;
m_isWeatherChanging = true;
}
/// <summary>Starts a global weather transition using a custom preset and transition time, without changing the weather index.</summary>
public void SetGlobalWeather(AzureWeatherPreset preset, float transitionTime)
{
m_targetWeatherPreset = preset;
m_weatherTransitionLength = transitionTime;
m_weatherTransitionProgress = 0.0f;
m_weatherTransitionStart = Time.time;
m_isWeatherChanging = true;
}
/// <summary>Instantly changes the global weather without a transition, and without changing the weather index.</summary>
public void SetGlobalWeather(AzureWeatherPreset preset)
{
m_currentWeatherPreset = preset;
}
/// <summary>Enable all the weather groups.</summary>
public void WeatherGroupsEnableAll()
{
for (int i = 0; i < m_weatherPropertyGroupList.Count; i++)
{
m_weatherPropertyGroupList[i].isEnabled = true;
}
}
/// <summary>Disable all the weather groups.</summary>
public void WeatherGroupsDisableAll()
{
for (int i = 0; i < m_weatherPropertyGroupList.Count; i++)
{
m_weatherPropertyGroupList[i].isEnabled = false;
}
}
/// <summary>Enable a weather group at a given index.</summary>
public void WeatherGroupsEnableAt(int index)
{
m_weatherPropertyGroupList[index].isEnabled = true;
}
/// <summary>Disable a weather group at a given index.</summary>
public void WeatherGroupsDisableAt(int index)
{
m_weatherPropertyGroupList[index].isEnabled = false;
}
/// <summary>Set the active state of a weather group giving its index and state.</summary>
public void WeatherGroupsSetStateAt(int index, bool state)
{
m_weatherPropertyGroupList[index].isEnabled = state;
}
/// <summary>Returns the float output of a custom weather property.</summary>
public float GetFloatOutput(int groupIndex, int propertyIndex)
{
return m_weatherPropertyGroupList[groupIndex].weatherPropertyList[propertyIndex].floatOutput;
}
/// <summary>Returns the color output of a custom weather property.</summary>
public Color GetColorOutput(int groupIndex, int propertyIndex)
{
return m_weatherPropertyGroupList[groupIndex].weatherPropertyList[propertyIndex].colorOutput;
}
/// <summary>Returns the Vector3 output of a custom weather property.</summary>
public Vector3 GetVector3Output(int groupIndex, int propertyIndex)
{
return m_weatherPropertyGroupList[groupIndex].weatherPropertyList[propertyIndex].vector3Output;
}
/// <summary>PropertInfo and FieldInfo are not serializable, so the targets must always be reassigned when the scene starts.</summary>
public void InitializePropertyTargets()
{
for (int i = 0; i < m_weatherPropertyGroupList.Count; i++)
{
for (int j = 0; j < m_weatherPropertyGroupList[i].weatherPropertyList.Count; j++)
{
m_weatherPropertyGroupList[i].weatherPropertyList[j].propertyInfo = null;
m_weatherPropertyGroupList[i].weatherPropertyList[j].fieldInfo = null;
switch (m_weatherPropertyGroupList[i].weatherPropertyList[j].targetType)
{
case AzureWeatherPropertyTargetType.Property:
if (m_weatherPropertyGroupList[i].weatherPropertyList[j].targetObject == null) continue;
GameObject obj = m_weatherPropertyGroupList[i].weatherPropertyList[j].targetObject;
string componentName = m_weatherPropertyGroupList[i].weatherPropertyList[j].targetComponentName;
string propertyName = m_weatherPropertyGroupList[i].weatherPropertyList[j].targetPropertyName;
m_weatherPropertyGroupList[i].weatherPropertyList[j].targetComponent = obj.GetComponent(componentName);
m_weatherPropertyGroupList[i].weatherPropertyList[j].propertyInfo = m_weatherPropertyGroupList[i].weatherPropertyList[j].targetComponent?.GetType().GetProperty(propertyName);
break;
case AzureWeatherPropertyTargetType.Field:
if (m_weatherPropertyGroupList[i].weatherPropertyList[j].targetObject == null) continue;
obj = m_weatherPropertyGroupList[i].weatherPropertyList[j].targetObject;
componentName = m_weatherPropertyGroupList[i].weatherPropertyList[j].targetComponentName;
propertyName = m_weatherPropertyGroupList[i].weatherPropertyList[j].targetPropertyName;
m_weatherPropertyGroupList[i].weatherPropertyList[j].targetComponent = obj.GetComponent(componentName);
m_weatherPropertyGroupList[i].weatherPropertyList[j].fieldInfo = m_weatherPropertyGroupList[i].weatherPropertyList[j].targetComponent?.GetType().GetField(propertyName);
break;
case AzureWeatherPropertyTargetType.GlobalProperty:
componentName = m_weatherPropertyGroupList[i].weatherPropertyList[j].targetComponentName;
propertyName = m_weatherPropertyGroupList[i].weatherPropertyList[j].targetPropertyName;
m_weatherPropertyGroupList[i].weatherPropertyList[j].targetGlobalType = Type.GetType(componentName);
m_weatherPropertyGroupList[i].weatherPropertyList[j].propertyInfo = m_weatherPropertyGroupList[i].weatherPropertyList[j].targetGlobalType?.GetProperty(propertyName);
break;
case AzureWeatherPropertyTargetType.GlobalField:
componentName = m_weatherPropertyGroupList[i].weatherPropertyList[j].targetComponentName;
propertyName = m_weatherPropertyGroupList[i].weatherPropertyList[j].targetPropertyName;
m_weatherPropertyGroupList[i].weatherPropertyList[j].targetGlobalType = Type.GetType(componentName);
m_weatherPropertyGroupList[i].weatherPropertyList[j].fieldInfo = m_weatherPropertyGroupList[i].weatherPropertyList[j].targetGlobalType?.GetField(propertyName);
break;
}
}
}
}
/// <summary>Initialize the current weather preset using the first global weather as reference.</summary>
private void InitializeCurrentWeatherPreset()
{
if (m_globalWeatherList.Count <= 0) return;
if (m_globalWeatherList[0] == null) return;
m_currentWeatherPreset = m_globalWeatherList[0].weatherPreset;
}
/// <summary>Evaluate the weather system according to the current weather preset selected.</summary>
private void EvaluateCurrentWeather()
{
if (m_currentWeatherPreset == null) return;
for (int i = 0; i < m_weatherPropertyGroupList.Count; i++)
{
if (m_weatherPropertyGroupList[i].isEnabled == false)
continue;
for (int j = 0; j < m_weatherPropertyGroupList[i].weatherPropertyList.Count; j++)
{
switch (m_weatherPropertyGroupList[i].weatherPropertyList[j].propertyType)
{
case AzureWeatherPropertyType.Float:
m_weatherPropertyGroupList[i].weatherPropertyList[j].floatOutput = m_currentWeatherPreset.propertyGroupDataList[i].propertyDataList[j].floatData;
break;
case AzureWeatherPropertyType.Color:
m_weatherPropertyGroupList[i].weatherPropertyList[j].colorOutput = m_currentWeatherPreset.propertyGroupDataList[i].propertyDataList[j].colorData;
break;
case AzureWeatherPropertyType.Curve:
m_weatherPropertyGroupList[i].weatherPropertyList[j].floatOutput = m_currentWeatherPreset.propertyGroupDataList[i].propertyDataList[j].curveData.Evaluate(m_evaluationTime);
break;
case AzureWeatherPropertyType.Gradient:
m_weatherPropertyGroupList[i].weatherPropertyList[j].colorOutput = m_currentWeatherPreset.propertyGroupDataList[i].propertyDataList[j].gradientData.Evaluate(m_evaluationTimeGradient);
break;
case AzureWeatherPropertyType.Direction:
case AzureWeatherPropertyType.Position:
m_weatherPropertyGroupList[i].weatherPropertyList[j].vector3Output = m_currentWeatherPreset.propertyGroupDataList[i].propertyDataList[j].vector3Data;
break;
}
}
}
}
/// <summary>Performs a global weather transition.</summary>
private void EvaluateGlobalWeatherTransition(AzureWeatherPreset from, AzureWeatherPreset to, float t)
{
if (from == null || to == null) return;
for (int i = 0; i < m_weatherPropertyGroupList.Count; i++)
{
if (m_weatherPropertyGroupList[i].isEnabled == false)
continue;
m_weatherGroupRampTime = to.propertyGroupDataList[i].rampCurve.Evaluate(t);
for (int j = 0; j < m_weatherPropertyGroupList[i].weatherPropertyList.Count; j++)
{
switch (m_weatherPropertyGroupList[i].weatherPropertyList[j].propertyType)
{
case AzureWeatherPropertyType.Float:
m_weatherPropertyGroupList[i].weatherPropertyList[j].floatOutput = FloatInterpolation(from.propertyGroupDataList[i].propertyDataList[j].floatData, to.propertyGroupDataList[i].propertyDataList[j].floatData, m_weatherGroupRampTime);
break;
case AzureWeatherPropertyType.Color:
m_weatherPropertyGroupList[i].weatherPropertyList[j].colorOutput = ColorInterpolation(from.propertyGroupDataList[i].propertyDataList[j].colorData, to.propertyGroupDataList[i].propertyDataList[j].colorData, m_weatherGroupRampTime);
break;
case AzureWeatherPropertyType.Curve:
m_weatherPropertyGroupList[i].weatherPropertyList[j].floatOutput = FloatInterpolation(from.propertyGroupDataList[i].propertyDataList[j].curveData.Evaluate(m_evaluationTime), to.propertyGroupDataList[i].propertyDataList[j].curveData.Evaluate(m_evaluationTime), m_weatherGroupRampTime);
break;
case AzureWeatherPropertyType.Gradient:
m_weatherPropertyGroupList[i].weatherPropertyList[j].colorOutput = ColorInterpolation(from.propertyGroupDataList[i].propertyDataList[j].gradientData.Evaluate(m_evaluationTimeGradient), to.propertyGroupDataList[i].propertyDataList[j].gradientData.Evaluate(m_evaluationTimeGradient), m_weatherGroupRampTime);
break;
case AzureWeatherPropertyType.Direction:
m_vector3Angle.x = Mathf.LerpAngle(from.propertyGroupDataList[i].propertyDataList[j].vector3Data.x, to.propertyGroupDataList[i].propertyDataList[j].vector3Data.x, m_weatherGroupRampTime);
m_vector3Angle.y = Mathf.LerpAngle(from.propertyGroupDataList[i].propertyDataList[j].vector3Data.y, to.propertyGroupDataList[i].propertyDataList[j].vector3Data.y, m_weatherGroupRampTime);
m_vector3Angle.z = Mathf.LerpAngle(from.propertyGroupDataList[i].propertyDataList[j].vector3Data.z, to.propertyGroupDataList[i].propertyDataList[j].vector3Data.z, m_weatherGroupRampTime);
m_weatherPropertyGroupList[i].weatherPropertyList[j].vector3Output = m_vector3Angle;
break;
case AzureWeatherPropertyType.Position:
m_weatherPropertyGroupList[i].weatherPropertyList[j].vector3Output = Vector3.Lerp(from.propertyGroupDataList[i].propertyDataList[j].vector3Data, to.propertyGroupDataList[i].propertyDataList[j].vector3Data, m_weatherGroupRampTime);
break;
}
}
}
}
/// <summary>Evaluate the weather while inside any weather zone influence.</summary>
private void EvaluateWeatherZonesInfluence(AzureWeatherPreset target, float blendFactor)
{
if (target == null) return;
for (int i = 0; i < m_weatherPropertyGroupList.Count; i++)
{
if (m_weatherPropertyGroupList[i].isEnabled == false)
continue;
m_weatherGroupRampTime = target.propertyGroupDataList[i].rampCurve.Evaluate(blendFactor);
for (int j = 0; j < m_weatherPropertyGroupList[i].weatherPropertyList.Count; j++)
{
switch (m_weatherPropertyGroupList[i].weatherPropertyList[j].propertyType)
{
case AzureWeatherPropertyType.Float:
m_weatherPropertyGroupList[i].weatherPropertyList[j].floatOutput = FloatInterpolation(m_weatherPropertyGroupList[i].weatherPropertyList[j].floatOutput, target.propertyGroupDataList[i].propertyDataList[j].floatData, m_weatherGroupRampTime);
break;
case AzureWeatherPropertyType.Color:
m_weatherPropertyGroupList[i].weatherPropertyList[j].colorOutput = ColorInterpolation(m_weatherPropertyGroupList[i].weatherPropertyList[j].colorOutput, target.propertyGroupDataList[i].propertyDataList[j].colorData, m_weatherGroupRampTime);
break;
case AzureWeatherPropertyType.Curve:
m_weatherPropertyGroupList[i].weatherPropertyList[j].floatOutput = FloatInterpolation(m_weatherPropertyGroupList[i].weatherPropertyList[j].floatOutput, target.propertyGroupDataList[i].propertyDataList[j].curveData.Evaluate(m_evaluationTime), m_weatherGroupRampTime);
break;
case AzureWeatherPropertyType.Gradient:
m_weatherPropertyGroupList[i].weatherPropertyList[j].colorOutput = ColorInterpolation(m_weatherPropertyGroupList[i].weatherPropertyList[j].colorOutput, target.propertyGroupDataList[i].propertyDataList[j].gradientData.Evaluate(m_evaluationTimeGradient), m_weatherGroupRampTime);
break;
case AzureWeatherPropertyType.Direction:
m_vector3Angle.x = Mathf.LerpAngle(m_weatherPropertyGroupList[i].weatherPropertyList[j].vector3Output.x, target.propertyGroupDataList[i].propertyDataList[j].vector3Data.x, m_weatherGroupRampTime);
m_vector3Angle.y = Mathf.LerpAngle(m_weatherPropertyGroupList[i].weatherPropertyList[j].vector3Output.y, target.propertyGroupDataList[i].propertyDataList[j].vector3Data.y, m_weatherGroupRampTime);
m_vector3Angle.z = Mathf.LerpAngle(m_weatherPropertyGroupList[i].weatherPropertyList[j].vector3Output.z, target.propertyGroupDataList[i].propertyDataList[j].vector3Data.z, m_weatherGroupRampTime);
m_weatherPropertyGroupList[i].weatherPropertyList[j].vector3Output = m_vector3Angle;
break;
case AzureWeatherPropertyType.Position:
m_weatherPropertyGroupList[i].weatherPropertyList[j].vector3Output = Vector3.Lerp(m_weatherPropertyGroupList[i].weatherPropertyList[j].vector3Output, target.propertyGroupDataList[i].propertyDataList[j].vector3Data, m_weatherGroupRampTime);
break;
}
}
}
}
/// <summary>Interpolates between two values given an interpolation factor.</summary>
private float FloatInterpolation(float from, float to, float t)
{
return from + (to - from) * t;
}
/// <summary>Interpolates between two colors given an interpolation factor.</summary>
private Color ColorInterpolation(Color from, Color to, float t)
{
Color ret;
ret.r = from.r + (to.r - from.r) * t;
ret.g = from.g + (to.g - from.g) * t;
ret.b = from.b + (to.b - from.b) * t;
ret.a = from.a + (to.a - from.a) * t;
return ret;
}
}
}