// --------------------------------------------------------------------------------------------------------------------
//
// Copyright (c) VRMADA, All rights reserved.
//
// --------------------------------------------------------------------------------------------------------------------
using UltimateXR.Core.Components;
using UltimateXR.Extensions.System.Collections;
using UnityEngine;
namespace UltimateXR.Animation.ParticleSystems
{
///
/// Component that allows to toggle particle emission enabled state back and forth at random times.
///
public class UxrToggleEmitParticles : UxrComponent
{
#region Inspector Properties/Serialized Fields
[SerializeField] private ParticleSystem _particleSystem;
[SerializeField] private GameObject[] _toggleAdditionalGameObjects;
[SerializeField] private float _enabledDurationMin;
[SerializeField] private float _enabledDurationMax;
[SerializeField] private float _disabledDurationMin;
[SerializeField] private float _disabledDurationMax;
[SerializeField] private bool _useUnscaledTime;
#endregion
#region Public Types & Data
///
/// The particle system to toggle.
///
public ParticleSystem TargetParticleSystem
{
get => _particleSystem;
set => _particleSystem = value;
}
///
/// Additional objects whose active state is toggled too.
///
public GameObject[] ToggleAdditionalGameObjects
{
get => _toggleAdditionalGameObjects;
set => _toggleAdditionalGameObjects = value;
}
///
/// The minimum amount of seconds the emission will be enabled when toggled on.
///
public float EnabledSecondsMin
{
get => _enabledDurationMin;
set => _enabledDurationMin = value;
}
///
/// The maximum amount of seconds the emission will be enabled when toggled on.
///
public float EnabledSecondsMax
{
get => _enabledDurationMax;
set => _enabledDurationMax = value;
}
///
/// The minimum amount of seconds the emission will be disabled when toggled off.
///
public float DisabledSecondsMin
{
get => _disabledDurationMin;
set => _disabledDurationMin = value;
}
///
/// The minimum amount of seconds the emission will be disabled when toggled off.
///
public float DisabledSecondsMax
{
get => _disabledDurationMax;
set => _disabledDurationMax = value;
}
///
/// Whether to use or for timing.
///
public bool UseUnscaledTime
{
get => _useUnscaledTime;
set => _useUnscaledTime = value;
}
#endregion
#region Unity
///
/// Called each time the component is enabled. Sets up the next toggle time.
///
protected override void OnEnable()
{
base.OnEnable();
_startTime = _useUnscaledTime ? Time.unscaledTime : Time.time;
_nextToggleTime = GetNextRelativeToggleTime();
}
///
/// Called on each update. Checks if it is time to toggle the emission state.
///
private void Update()
{
float time = CurrentTime - _startTime;
if (time > _nextToggleTime)
{
// Toggle GameObjects
_toggleAdditionalGameObjects.ForEach(go => go.SetActive(!go.activeSelf));
// Toggle particle emission
if (_particleSystem != null)
{
ParticleSystem.EmissionModule emissionModule = _particleSystem.emission;
emissionModule.enabled = !emissionModule.enabled;
}
// Setup next toggle time
_startTime = CurrentTime;
_nextToggleTime = GetNextRelativeToggleTime();
}
}
#endregion
#region Private Methods
///
/// Gets the next time the components will be toggled
///
/// Next toggle time in seconds relative to the current time
private float GetNextRelativeToggleTime()
{
if (_particleSystem != null && _particleSystem.emission.enabled)
{
return Random.Range(_enabledDurationMin, _enabledDurationMax);
}
if (_particleSystem != null && !_particleSystem.emission.enabled)
{
return Random.Range(_disabledDurationMin, _disabledDurationMax);
}
return 0.0f;
}
#endregion
#region Private Types & Data
private float CurrentTime => _useUnscaledTime ? Time.unscaledTime : Time.time;
private float _startTime;
private float _nextToggleTime;
#endregion
}
}