123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- //### Particles Static Bezier Flow Controller
- //This is a component that controlls behaviour of particle system mounted to the same game object it is.
- //
- //It controlls only particles path, it does not controll any other aspect ot their behaviour or loock.
- //
- //License information: [ASSET STORE TERMS OF SERVICE AND EULA](https://unity3d.com/legal/as_terms)
- //
- //Developed by [MathArtCode](https://www.assetstore.unity3d.com/en/#!/search/page=1/sortby=popularity/query=publisher:8738) team, 2015
- using System;
- using System.Collections.Generic;
- using Assets.Scripts.BezierCurvedParticlesFlow.Utilities;
- using UnityEngine;
- #if !UNITY_3_5
- namespace Assets.Scripts.BezierCurvedParticlesFlow {
- #endif
- [AddComponentMenu( "Effects/MathArtCode/Particles Static Bezier Flow" )]
- [ExecuteInEditMode]
- [RequireComponent(typeof (ParticleSystem))]
- public sealed class ParticlesStaticBezierFlowController : MonoBehaviour {
- [SerializeField]
- private BezierLogic _bezierLogicLogic;
- private ParticleSystem.Particle[] _particles;
- [SerializeField]
- private Vector3[] _positions;
- [SerializeField]
- private int _samplesCount;
- private ParticleSystem _system;
- [SerializeField]
- private bool _usePositions;
- [SerializeField]
- private bool _useVelocities;
- [SerializeField]
- private Vector3[] _velocities;
- #if UNITY_3_5
- [SerializeField]
- private int _maxParticles;
- //Unity3.5 ParticleSystem.MaxParticles
- public int MaxParticles {
- get { return _maxParticles; }
- set {
- _maxParticles = value;
- _particles = new ParticleSystem.Particle[_maxParticles];
- }
- }
- #endif
- //Stores baked positions relative to host game object.
- private Vector3[] Positions {
- get {
- if (_positions == null) {
- Rasterize();
- }
- return _positions;
- }
- }
- //Stores baked velocities relative to host game object.
- private Vector3[] Velocities {
- get {
- if (_velocities == null) {
- Rasterize();
- }
- return _velocities;
- }
- }
- //Defines if pixel perfect positions as they are defined in bezier curve shall be used (which makes all particles follow one curve).
- public bool UsePositions {
- get { return _usePositions; }
- set { _usePositions = value; }
- }
- //Defines if each particle shall set its velocity relative to its life time (allowing you to use particle emmiter shape as flow form).
- public bool UseVelocities {
- get { return _useVelocities; }
- set { _useVelocities = value; }
- }
- //Hosts main curve related logic
- public BezierLogic BezierLogic {
- get { return _bezierLogicLogic ?? (_bezierLogicLogic = new BezierLogic()); }
- }
- //Defines how much samples shall be used in the resulting curve (sets size of arrays of positions and velocities updated on `Rasterize()` call).
- public int SamplesCount {
- get { return _samplesCount; }
- set { _samplesCount = value; }
- }
- //Allows to get a position which shall be taken by particle relative to its life time.
- private Vector3 GetPoint(float t) {
- t = Mathf.Clamp01(t)*(_samplesCount - 1);
- var i = (int) t;
- if (i >= Positions.Length) {
- i = Positions.Length-1;
- }
- return
- Positions[i];
- }
- //Allows to get a velocity which shall be taken by particle relative to its life time.
- private Vector3 GetVelocity(float t) {
- t = Mathf.Clamp01(t)*(_samplesCount - 1);
- var i = (int) t;
- if (i >= Velocities.Length) {
- i = Velocities.Length-1;
- }
- return
- Velocities[i];
- }
- //Updates baked values
- private void SetBakedData(Vector3[] positions, Vector3[] velocities) {
- _positions = positions;
- _velocities = velocities;
- }
- //Recalculates and updates baked values
- public void Rasterize() {
- var positions = new List<Vector3>();
- var velocities = new List<Vector3>();
- for (var i = 1; i < _samplesCount; i++) {
- var t = i/(float) _samplesCount;
- positions.Add(BezierLogic.GetPoint(t));
- velocities.Add(BezierLogic.GetVelocity(t));
- }
- SetBakedData(positions.ToArray(), velocities.ToArray());
- }
- //Resets component to its default values
- // ReSharper disable once UnusedMember.Local
- private void Reset() {
- #if UNITY_3_5
- _maxParticles = 50;
- #endif
- _samplesCount = 50;
- BezierLogic.Reset();
- Rasterize();
- _usePositions = true;
- _usePositions = true;
- }
- //Updates `ParticleSystem` particles setting positions and velocities if needed
- // ReSharper disable once UnusedMember.Local
- private void LateUpdate() {
- InitializeIfNeeded();
- var numParticlesAlive = _system.GetParticles(_particles);
- for (var i = 0; i < numParticlesAlive; i++) {
- var p = _particles[i];
- var t = (p.startLifetime - p.remainingLifetime)/p.startLifetime;
- if (_useVelocities) {
- _particles[i].velocity = GetVelocity(t);
- }
- if (_usePositions) {
- _particles[i].position = GetPoint(t);
- }
- }
- _system.SetParticles(_particles, numParticlesAlive);
- }
- //Gets GameObject particle system
- private void InitializeIfNeeded() {
- if (_system == null) {
- _system = GetComponent<ParticleSystem>();
- }
- if ( _particles == null ) {
- #if !UNITY_3_5
- _particles = new ParticleSystem.Particle[_system.maxParticles];
- #else
- _particles = new ParticleSystem.Particle[_maxParticles];
- #endif
- _system.GetParticles( _particles );
- }
- }
- }
- #if !UNITY_3_5
- }
- #endif
|