// -------------------------------------------------------------------------------------------------------------------- // // 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 } }