You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
249 lines
8.0 KiB
C#
249 lines
8.0 KiB
C#
using UnityEngine;
|
|
|
|
namespace Gaia
|
|
{
|
|
[RequireComponent(typeof(WindZone))]
|
|
public class WindManager : MonoBehaviour
|
|
{
|
|
#region Variables
|
|
|
|
#region Public Variables
|
|
|
|
public bool m_useWindAudio = true;
|
|
public float windGlobalMaxDist = 1000f;
|
|
public Vector4 windGlobals;
|
|
public Vector4 windGlobalsB;
|
|
public AudioClip m_windAudioClip;
|
|
public float m_windTransitionTime = 5f;
|
|
|
|
#endregion
|
|
#region Private Variables
|
|
|
|
[SerializeField]
|
|
private WindZone m_windZone;
|
|
private AudioSource m_windAudioSource;
|
|
private int m_shaderPropertyIDWindGlobals;
|
|
private int m_shaderPropertyIDWindGlobalsB;
|
|
private Vector3 m_windDirection;
|
|
private Vector4 m_targetWindGlobals;
|
|
private float m_windTime = 0;
|
|
|
|
private bool m_canProcessWind = false;
|
|
private float m_currentWindSpeed = 0f;
|
|
private float m_currentWindVolume = 0f;
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
#region Unity Function
|
|
|
|
private void Start()
|
|
{
|
|
Setup();
|
|
}
|
|
private void Update()
|
|
{
|
|
UpdateWind();
|
|
|
|
if (m_useWindAudio)
|
|
{
|
|
CheckWindVolume();
|
|
if (m_canProcessWind)
|
|
{
|
|
ProcessWindAudio();
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
#region Public Functions
|
|
|
|
/// <summary>
|
|
/// Applies the settings isntantly
|
|
/// </summary>
|
|
public void InstantWindApply()
|
|
{
|
|
Setup();
|
|
m_windDirection = m_windZone.transform.forward;
|
|
m_targetWindGlobals.x = m_windDirection.x;
|
|
m_targetWindGlobals.y = -Mathf.Max(m_windDirection.y, Vector2.Distance(new Vector2(m_windDirection.x, m_windDirection.z), Vector2.zero) * 0.5f); // force some data into y to give branches some bounce
|
|
m_targetWindGlobals.z = m_windDirection.z;
|
|
m_targetWindGlobals.w = Mathf.Clamp(m_windZone.windMain, 0.0f, 1.2f);
|
|
windGlobals = m_targetWindGlobals;
|
|
Shader.SetGlobalVector(m_shaderPropertyIDWindGlobals, windGlobals);
|
|
|
|
windGlobalsB.x = windGlobalMaxDist;
|
|
windGlobalsB.y = Mathf.Pow(windGlobals.w * 0.5f + 0.5f, 3.0f) * 0.1f;
|
|
Shader.SetGlobalVector(m_shaderPropertyIDWindGlobalsB, windGlobalsB);
|
|
}
|
|
/// <summary>
|
|
/// Processes and updates the wind
|
|
/// </summary>
|
|
public void UpdateWind()
|
|
{
|
|
m_windDirection = m_windZone.transform.forward;
|
|
m_targetWindGlobals.x = m_windDirection.x;
|
|
m_targetWindGlobals.y = -Mathf.Max(m_windDirection.y, Vector2.Distance(new Vector2(m_windDirection.x, m_windDirection.z), Vector2.zero) * 0.5f); // force some data into y to give branches some bounce
|
|
m_targetWindGlobals.z = m_windDirection.z;
|
|
m_targetWindGlobals.w = Mathf.Clamp(m_windZone.windMain, 0.0f, 1.2f);
|
|
|
|
windGlobals = Vector4.Lerp(windGlobals, m_targetWindGlobals, Time.deltaTime * 0.25f);
|
|
Shader.SetGlobalVector(m_shaderPropertyIDWindGlobals, windGlobals);
|
|
m_windTime += Time.deltaTime * Mathf.Pow(windGlobals.w * 0.5f + 0.5f, 3.0f) * 0.1f;
|
|
if (m_windTime > 100.0f)
|
|
{
|
|
m_windTime -= 100.0f;
|
|
}
|
|
|
|
windGlobalsB.x = windGlobalMaxDist;
|
|
windGlobalsB.y = m_windTime;
|
|
|
|
Shader.SetGlobalVector(m_shaderPropertyIDWindGlobalsB, windGlobalsB);
|
|
}
|
|
|
|
#endregion
|
|
#region Private Functions
|
|
|
|
/// <summary>
|
|
/// Sets up the wind manager
|
|
/// </summary>
|
|
private void Setup()
|
|
{
|
|
m_shaderPropertyIDWindGlobals = Shader.PropertyToID("_PW_WindGlobals");
|
|
m_shaderPropertyIDWindGlobalsB = Shader.PropertyToID("_PW_WindGlobalsB");
|
|
if (m_windZone == null)
|
|
{
|
|
m_windZone = GetWindZone();
|
|
}
|
|
|
|
if (m_windZone == null)
|
|
{
|
|
m_windDirection = m_windZone.transform.forward;
|
|
windGlobals.x = m_windDirection.x;
|
|
windGlobals.y = m_windDirection.y;
|
|
windGlobals.z = m_windDirection.z;
|
|
windGlobals.w = m_windZone.windMain;
|
|
m_currentWindSpeed = m_windZone.windMain;
|
|
m_currentWindVolume = Mathf.Clamp01(m_windZone.windMain);
|
|
}
|
|
|
|
if (Application.isPlaying)
|
|
{
|
|
m_windAudioSource = GetWindAudioSource();
|
|
if (m_windAudioSource != null)
|
|
{
|
|
m_windAudioSource.clip = m_windAudioClip;
|
|
m_windAudioSource.volume = m_currentWindVolume;
|
|
if (!m_windAudioSource.isPlaying)
|
|
{
|
|
m_windAudioSource.Play();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Checks if the volume needs to be processed
|
|
/// </summary>
|
|
private void CheckWindVolume()
|
|
{
|
|
if (m_windZone.windMain != m_currentWindSpeed)
|
|
{
|
|
if (m_windAudioSource != null)
|
|
{
|
|
m_currentWindVolume = m_windAudioSource.volume;
|
|
m_canProcessWind = true;
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Processes the volume for the wind to be updated
|
|
/// </summary>
|
|
private void ProcessWindAudio()
|
|
{
|
|
if (m_windAudioClip == null || m_windAudioSource == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
float clampedWindSpeed = Mathf.Clamp01(m_windZone.windMain);
|
|
m_windAudioSource.clip = m_windAudioClip;
|
|
if (!m_windAudioSource.isPlaying)
|
|
{
|
|
m_windAudioSource.Play();
|
|
}
|
|
m_windAudioSource.volume = Mathf.Lerp(m_currentWindVolume, clampedWindSpeed, Time.deltaTime / m_windTransitionTime);
|
|
if (m_currentWindVolume >= clampedWindSpeed)
|
|
{
|
|
if (m_windAudioSource.volume <= clampedWindSpeed - 0.05f)
|
|
{
|
|
m_windAudioSource.volume = clampedWindSpeed;
|
|
m_canProcessWind = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (m_windAudioSource.volume >= clampedWindSpeed - 0.05f)
|
|
{
|
|
m_windAudioSource.volume = clampedWindSpeed;
|
|
m_canProcessWind = false;
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// Gets the wind audio source from the object
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private AudioSource GetWindAudioSource()
|
|
{
|
|
if (m_windAudioSource != null)
|
|
{
|
|
return m_windAudioSource;
|
|
}
|
|
|
|
AudioSource audioSource = GetComponent<AudioSource>();
|
|
if (audioSource == null)
|
|
{
|
|
audioSource = gameObject.AddComponent<AudioSource>();
|
|
|
|
}
|
|
|
|
audioSource.loop = true;
|
|
audioSource.playOnAwake = true;
|
|
audioSource.maxDistance = 100000f;
|
|
|
|
return audioSource;
|
|
}
|
|
/// <summary>
|
|
/// Gets the wind zone
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private WindZone GetWindZone()
|
|
{
|
|
WindZone windZone = gameObject.GetComponent<WindZone>();
|
|
if (windZone == null)
|
|
{
|
|
windZone = gameObject.AddComponent<WindZone>();
|
|
}
|
|
|
|
return windZone;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Public Static Functions
|
|
|
|
/// <summary>
|
|
/// Removes the manager from the scene
|
|
/// </summary>
|
|
public static void RemoveWindManager()
|
|
{
|
|
WindManager manager = FindObjectOfType<WindManager>();
|
|
if (manager != null)
|
|
{
|
|
DestroyImmediate(manager);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |