Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using UnityEngine;
- namespace Assets.Scripts.Client
- {
- /// <summary>
- /// PointCloud is a class that gives programatic control of a ParticleEmitter
- /// so we can create a mathematic simulation.
- /// </summary>
- [ExecuteInEditMode]
- public class PointCloud : MonoBehaviour
- {
- public Action<ParticleEmitter> onParticleEmitterChangedDelegate;
- [SerializeField][HideInInspector]
- private GameObject m_ParticleEmitterInstance = null;
- [SerializeField][HideInInspector]
- private float[] m_CachedAngularVelocity = new float[0];
- [SerializeField][HideInInspector]
- private Color[] m_CachedColor = new Color[0];
- [SerializeField][HideInInspector]
- private float[] m_CachedEnergy = new float[0];
- [SerializeField][HideInInspector]
- private Vector3[] m_CachedPosition = new Vector3[0];
- [SerializeField][HideInInspector]
- private float[] m_CachedRotation = new float[0];
- [SerializeField][HideInInspector]
- private float[] m_CachedSize = new float[0];
- [SerializeField][HideInInspector]
- private float[] m_CachedStartEnergy = new float[0];
- [SerializeField][HideInInspector]
- private Vector3[] m_CachedVelocity = new Vector3[0];
- #region Properties
- private ParticleEmitter m_CachedParticleEmitter = null;
- /// <summary>
- /// Gets the particle emitter.
- ///
- /// We return the particle emitter that belongs to the instantiated
- /// particles GameObject.
- /// </summary>
- /// <value>The particle system.</value>
- public new ParticleEmitter particleEmitter
- {
- get
- {
- if (this.m_CachedParticleEmitter == null && this.m_ParticleEmitterInstance != null)
- this.m_CachedParticleEmitter =
- this.m_ParticleEmitterInstance.GetComponent<ParticleEmitter>() as ParticleEmitter;
- return this.m_CachedParticleEmitter;
- }
- }
- [SerializeField][HideInInspector]
- private GameObject m_ParticleEmitterPrefab = null;
- /// <summary>
- /// Sets the particle emitter prefab.
- /// </summary>
- /// <value>The particle emitter prefab.</value>
- public GameObject particleEmitterPrefab
- {
- get
- {
- return this.m_ParticleEmitterPrefab;
- }
- set
- {
- this.SetParticleEmitterPrefab(value);
- }
- }
- /// <summary>
- /// Gets or sets the particles.
- /// </summary>
- /// <value>The particles.</value>
- public Particle[] particles
- {
- get
- {
- return this.GetParticles();
- }
- set
- {
- this.SetParticles(value);
- }
- }
- #endregion
- #region Unity Methods
- /// <summary>
- /// Called when the object is instantiated
- /// </summary>
- protected virtual void Awake()
- {
- this._RebuildParticlesFromCache();
- }
- /// <summary>
- /// Called when the object is about to be destroyed
- /// </summary>
- protected virtual void OnDestroy()
- {
- this._Clear();
- }
- #endregion
- #region Methods
- /// <summary>
- /// Sets the particle emitter prefab.
- /// </summary>
- /// <param name="prefab">Prefab.</param>
- public void SetParticleEmitterPrefab(GameObject prefab)
- {
- if (prefab == this.m_ParticleEmitterPrefab)
- return;
- this.m_ParticleEmitterPrefab = prefab;
- if (this.m_ParticleEmitterPrefab != null)
- {
- ParticleEmitter prefabEmitter = this.m_ParticleEmitterPrefab.GetComponent<ParticleEmitter>();
- if (prefabEmitter == null)
- Debug.LogWarning("Particle Emitter Prefab has no ParticleEmitter component");
- }
- this._InstantiateParticlePrefab();
- }
- /// <summary>
- /// Gets the particles.
- /// </summary>
- /// <returns>The particles.</returns>
- public Particle[] GetParticles()
- {
- if (this.particleEmitter == null)
- return this._GetParticlesFromCache();
- return this.particleEmitter.particles.Clone() as Particle[];
- }
- /// <summary>
- /// Gets the particle world position.
- /// </summary>
- /// <returns>The particle world position.</returns>
- public Vector3 GetParticleWorldPosition(Particle particle)
- {
- Vector3 position = particle.position;
- // Particle doesn't really exist in space
- if (this.particleEmitter == null)
- {
- Debug.LogWarning("Unknown particle simulation space");
- return position;
- }
- // We need to translate the particle from local space
- if (!this.particleEmitter.useWorldSpace)
- return this.particleEmitter.transform.TransformPoint(position);
- return position;
- }
- /// <summary>
- /// Sets the particles.
- /// </summary>
- /// <param name="particles">Particles.</param>
- public void SetParticles(Particle[] particles)
- {
- if (this.particleEmitter != null)
- this.particleEmitter.particles = particles;
- this._SetParticlesToCache(particles);
- }
- /// <summary>
- /// Builds the particles.
- /// </summary>
- /// <returns>The particles.</returns>
- /// <param name="count">Count.</param>
- public static Particle[] BuildParticles(int count)
- {
- Particle[] particles = new Particle[count];
- // If the energy of the particles is zero or less, the particles
- // will be deleted as soon as they are assigned to the particle emitter
- for (int index=0; index < count; index++)
- particles[index].energy = 1.0f;
- return particles;
- }
- #endregion
- #region Private Methods
- /// <summary>
- /// Particles aren't serialized by unity so we need to separate them into
- /// their properties
- /// </summary>
- /// <param name="particles">Particles.</param>
- private void _SetParticlesToCache(Particle[] particles)
- {
- int count = particles.Length;
- this.m_CachedAngularVelocity = new float[count];
- this.m_CachedColor = new Color[count];
- this.m_CachedEnergy = new float[count];
- this.m_CachedPosition = new Vector3[count];
- this.m_CachedRotation = new float[count];
- this.m_CachedSize = new float[count];
- this.m_CachedStartEnergy = new float[count];
- this.m_CachedVelocity = new Vector3[count];
- for (int index=0; index < particles.Length; index++)
- {
- this.m_CachedAngularVelocity[index] = particles[index].angularVelocity;
- this.m_CachedColor[index] = particles[index].color;
- this.m_CachedEnergy[index] = particles[index].energy;
- this.m_CachedPosition[index] = particles[index].position;
- this.m_CachedRotation[index] = particles[index].rotation;
- this.m_CachedSize[index] = particles[index].size;
- this.m_CachedStartEnergy[index] = particles[index].startEnergy;
- this.m_CachedVelocity[index] = particles[index].velocity;
- }
- }
- /// <summary>
- /// Rebuilds the array of particles from the cache
- /// </summary>
- /// <returns>The particles from cache.</returns>
- private Particle[] _GetParticlesFromCache()
- {
- int count = this.m_CachedAngularVelocity.Length;
- Particle[] output = new Particle[count];
- for (int index=0; index < count; index++)
- {
- Particle particle = new Particle();
- particle.angularVelocity = this.m_CachedAngularVelocity[index];
- particle.color = this.m_CachedColor[index];
- particle.energy = this.m_CachedEnergy[index];
- particle.position = this.m_CachedPosition[index];
- particle.rotation = this.m_CachedRotation[index];
- particle.size = this.m_CachedSize[index];
- particle.startEnergy = this.m_CachedStartEnergy[index];
- particle.velocity = this.m_CachedVelocity[index];
- output[index] = particle;
- }
- return output;
- }
- /// <summary>
- /// Instantiates the particle prefab.
- /// </summary>
- private void _InstantiateParticlePrefab()
- {
- this._Clear();
- this.m_CachedParticleEmitter = null;
- if (this.m_ParticleEmitterPrefab != null)
- {
- this.m_ParticleEmitterInstance = Instantiate(this.m_ParticleEmitterPrefab) as GameObject;
- this.m_ParticleEmitterInstance.transform.parent = this.transform;
- this.m_ParticleEmitterInstance.transform.localPosition = Vector3.zero;
- this.m_ParticleEmitterInstance.transform.localEulerAngles = Vector3.zero;
- this.m_ParticleEmitterInstance.transform.localScale = Vector3.one;
- this.m_ParticleEmitterInstance.layer = this.gameObject.layer;
- this._RebuildParticlesFromCache();
- }
- if (this.onParticleEmitterChangedDelegate != null)
- this.onParticleEmitterChangedDelegate(this.particleEmitter);
- }
- /// <summary>
- /// Reapplies the cached particles
- /// </summary>
- private void _RebuildParticlesFromCache()
- {
- this.SetParticles(this._GetParticlesFromCache());
- }
- /// <summary>
- /// Tidy up generated GameObjects
- /// </summary>
- private void _Clear()
- {
- if (Application.isEditor)
- DestroyImmediate(this.m_ParticleEmitterInstance);
- else
- Destroy(this.m_ParticleEmitterInstance);
- }
- #endregion
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement