Files
beyond/Assets/Scripts/Optimization/Activator.cs
2024-11-20 15:21:28 +01:00

274 lines
9.5 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.VFX;
namespace Beyond
{
public class Activator : MonoBehaviour
{
[SerializeField] private float activationPerFrame = 10000;
private List<Transform> toActivate;
private List<Renderer> renderers;
private List<Behaviour> lights;
private List<Behaviour> reflectionProbes;
private List<Behaviour> skinnedMeshRenderers;
private List<Behaviour> visualEffects;
private List<Behaviour> particleSystems;
private List<Behaviour> audioSources;
[SerializeField] private float waitTime = 0f;
private bool state = true;
[Space, Tooltip("When use useRenderers = false then gameobjects in enabled/disabled")]
[SerializeField] private bool useRenderers = true;
[SerializeField] private bool useLights = true;
[SerializeField] private bool useReflectionProbes = true;
[SerializeField] private bool useSkinnedMeshRenderers = true;
[SerializeField] private bool useVisualEffects = true;
[SerializeField] private bool useParticleSystems = true;
[SerializeField] private bool useAudioSources = false;
// Start is called before the first frame update
void Awake()
{
if (!useRenderers)
{
List<Transform> childs = new List<Transform>(gameObject.transform.childCount);
foreach (Transform child in gameObject.transform)
{
if (child.gameObject.activeInHierarchy)
{
childs.Add(child);
}
}
toActivate = childs;
}
else
{
//Renderers
List<Renderer> activeRenderers = new List<Renderer>();
var allRenderers = GetComponentsInChildren<Renderer>();
var length = allRenderers.Length;
for (int i = 0; i < length; i++)
{
if (allRenderers[i].enabled)
{
activeRenderers.Add(allRenderers[i]);
}
}
renderers = activeRenderers;
if (useLights) GetComponentsBehaviour<Light>(out lights);
if (useReflectionProbes) GetComponentsBehaviour<ReflectionProbe>(out reflectionProbes);
if (useSkinnedMeshRenderers) GetComponentsBehaviour<SkinnedMeshRenderer>(out skinnedMeshRenderers);
if (useVisualEffects) GetComponentsBehaviour<VisualEffect>(out visualEffects);
if (useAudioSources) GetComponentsBehaviour<AudioSource>(out audioSources);
if (useParticleSystems) GetComponentsBehaviour<ParticleSystemRenderer>(out particleSystems);
}
}
private void Activate()
{
StopAllCoroutines();
StartCoroutine(ActivatePerFrame());
if (useRenderers)
{
if (useLights) StartCoroutine(ActivatePerFrame(lights));
if (useReflectionProbes) StartCoroutine(ActivatePerFrame(reflectionProbes));
if (useSkinnedMeshRenderers) StartCoroutine(ActivatePerFrame(skinnedMeshRenderers));
if (useVisualEffects) StartCoroutine(ActivatePerFrame(visualEffects));
if (useAudioSources) StartCoroutine(ActivatePerFrame(audioSources));
if (useParticleSystems) StartCoroutine(ActivatePerFrame(particleSystems));
}
}
private void Deactivate()
{
StopAllCoroutines();
StartCoroutine(DeactivatePerFrame());
if (useRenderers)
{
if (useLights) StartCoroutine(DeactivatePerFrame(lights));
if (useReflectionProbes) StartCoroutine(DeactivatePerFrame(reflectionProbes));
if (useSkinnedMeshRenderers) StartCoroutine(DeactivatePerFrame(skinnedMeshRenderers));
if (useVisualEffects) StartCoroutine(DeactivatePerFrame(visualEffects));
if (useAudioSources) StartCoroutine(DeactivatePerFrame(audioSources));
if (useParticleSystems) StartCoroutine(DeactivatePerFrame(particleSystems));
}
}
private void GetComponentsBehaviour<T>(out List<Behaviour> results)
{
List<Behaviour> activeComponents = new List<Behaviour>();
var allComponents = GetComponentsInChildren<T>();
var length = allComponents.Length;
for (int i = 0; i < length; i++)
{
if (allComponents[i] is Behaviour && (allComponents[i] as Behaviour).enabled)
{
activeComponents.Add(allComponents[i] as Behaviour);
}
}
results = activeComponents;
}
public void SetActive(bool isActive)
{
if (isActive && !state)
{
//Debug.Log("Activate volume: " + name);
state = true;
Activate();
}
else if (!isActive && state)
{
//Debug.Log("Deactivate volume: " + name);
state = false;
Deactivate();
}
}
private IEnumerator ActivatePerFrame(List<Behaviour> components)
{
var delay = new WaitForSeconds(waitTime);
int activatedCount = 0;
int count = components != null ? components.Count : 0;
for (int i = 0; i < count; i++)
{
components[i].enabled = true;
activatedCount++;
if (activatedCount >= activationPerFrame)
{
activatedCount = 0;
yield return delay;
}
}
}
private IEnumerator DeactivatePerFrame(List<Behaviour> components)
{
var delay = new WaitForSeconds(waitTime);
int activatedCount = 0;
int count = components != null ? components.Count : 0;
for (int i = 0; i < count; i++)
{
components[i].enabled = false;
activatedCount++;
if (activatedCount >= activationPerFrame)
{
activatedCount = 0;
yield return delay;
}
}
}
private IEnumerator ActivatePerFrame()
{
var delay = new WaitForSeconds(waitTime);
int activatedCount = 0;
int count = !useRenderers ? (toActivate != null ? toActivate.Count : 0) : (renderers != null ? renderers.Count : 0);
for (int i = 0; i < count; i++)
{
if (!useRenderers)
{
try
{
toActivate[i].gameObject.SetActive(true);
}
catch (Exception e)
{
toActivate.RemoveAt(i);
count--;
Debug.LogError(e);
}
}
else
{
try
{
renderers[i].enabled = true;
}
catch (Exception e)
{
renderers.RemoveAt(i);
count--;
Debug.LogError(e);
}
}
activatedCount++;
if (activatedCount >= activationPerFrame)
{
activatedCount = 0;
yield return delay;
}
}
}
private IEnumerator DeactivatePerFrame()
{
var delay = new WaitForSeconds(waitTime);
int activatedCount = 0;
int count = !useRenderers ? (toActivate != null ? toActivate.Count : 0) : (renderers != null ? renderers.Count : 0);
for (int i = 0; i < count; i++)
{
if (!useRenderers)
{
try
{
toActivate[i].gameObject.SetActive(false);
}
catch (Exception e)
{
toActivate.RemoveAt(i);
count--;
Debug.LogError(e);
}
}
else
{
try
{
renderers[i].enabled = false;
}
catch (Exception e)
{
renderers.RemoveAt(i);
count--;
Debug.LogError(e);
}
}
activatedCount++;
if (activatedCount >= activationPerFrame)
{
activatedCount = 0;
yield return delay;
}
}
}
private void OnValidate()
{
if (useRenderers == false)
{
useLights = false;
useReflectionProbes = false;
useSkinnedMeshRenderers = false;
useVisualEffects = false;
useParticleSystems = false;
useAudioSources = false;
}
}
}
}