added animation package and made small changes

This commit is contained in:
Lorenzo
2022-12-06 17:46:58 +01:00
parent 564ec183d7
commit 3f3323449f
3440 changed files with 12815908 additions and 344 deletions

View File

@@ -0,0 +1,157 @@
// =================================
// Namespaces.
// =================================
using UnityEngine;
// =================================
// Define namespace.
// =================================
namespace MirzaBeig
{
namespace Scripting
{
namespace Effects
{
// =================================
// Classes.
// =================================
public class AttractionParticleAffector : ParticleAffector
{
// =================================
// Nested classes and structures.
// =================================
// ...
// =================================
// Variables.
// =================================
// ...
[Header("Affector Controls")]
public float arrivalRadius = 1.0f;
public float arrivedRadius = 0.5f;
float arrivalRadiusSqr;
float arrivedRadiusSqr;
// =================================
// Functions.
// =================================
// ...
protected override void Awake()
{
base.Awake();
}
// ...
protected override void Start()
{
base.Start();
}
// ...
protected override void Update()
{
base.Update();
}
// ...
protected override void LateUpdate()
{
float uniformTransformScale = transform.lossyScale.x;
arrivalRadiusSqr = (arrivalRadius * arrivalRadius) * uniformTransformScale;
arrivedRadiusSqr = (arrivedRadius * arrivedRadius) * uniformTransformScale;
// ...
base.LateUpdate();
}
// ...
protected override Vector3 GetForce()
{
Vector3 force;
if (parameters.distanceToAffectorCenterSqr < arrivedRadiusSqr)
{
force.x = 0.0f;
force.y = 0.0f;
force.z = 0.0f;
}
else if (parameters.distanceToAffectorCenterSqr < arrivalRadiusSqr)
{
float inverseArrivalScaleNormalized = 1.0f - (parameters.distanceToAffectorCenterSqr / arrivalRadiusSqr);
force = Vector3.Normalize(parameters.scaledDirectionToAffectorCenter) * inverseArrivalScaleNormalized;
}
else
{
force = Vector3.Normalize(parameters.scaledDirectionToAffectorCenter);
}
return force;
}
// ...
protected override void OnDrawGizmosSelected()
{
if (enabled)
{
base.OnDrawGizmosSelected();
// ...
float uniformTransformScale = transform.lossyScale.x;
float arrivalRadius = this.arrivalRadius * uniformTransformScale;
float arrivedRadius = this.arrivedRadius * uniformTransformScale;
Vector3 center = transform.position + offset;
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(center, arrivalRadius);
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(center, arrivedRadius);
//Gizmos.color = Color.white;
//Gizmos.DrawLine(currentParticleSystem.transform.position, center);
}
}
// =================================
// End functions.
// =================================
}
// =================================
// End namespace.
// =================================
}
}
}
// =================================
// --END-- //
// =================================

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 3bf6d970cd2b79547a98f2dbf434935f
timeCreated: 1470567812
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: d566a25d31a988844a80d2747af4986e
timeCreated: 1458196122
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,553 @@
// =================================
// Namespaces.
// =================================
using UnityEngine;
using System.Collections.Generic;
// =================================
// Define namespace.
// =================================
namespace MirzaBeig
{
namespace Scripting
{
namespace Effects
{
// =================================
// Classes.
// =================================
public abstract class ParticleAffector : MonoBehaviour
{
// =================================
// Nested classes and structures.
// =================================
// ...
protected struct GetForceParameters
{
public float distanceToAffectorCenterSqr;
public Vector3 scaledDirectionToAffectorCenter;
public Vector3 particlePosition;
}
// =================================
// Variables.
// =================================
// ...
[Header("Common Controls")]
public float radius = Mathf.Infinity;
public float force = 5.0f;
public Vector3 offset = Vector3.zero;
public float scaledRadius
{
get
{
return radius * transform.lossyScale.x;
}
}
float _radius;
float radiusSqr;
float forceDeltaTime;
Vector3 transformPosition;
float[] particleSystemExternalForcesMultipliers;
public AnimationCurve scaleForceByDistance = new AnimationCurve(
new Keyframe(0.0f, 1.0f),
new Keyframe(1.0f, 1.0f)
);
// If (attached to a particle system): forces will be LOCAL.
// Else if (attached to a particle system): forces will be SELECTIVE.
// Else: forces will be GLOBAL.
new ParticleSystem particleSystem;
public List<ParticleSystem> _particleSystems;
int particleSystemsCount;
// All required particle systems that will actually be used.
List<ParticleSystem> particleSystems = new List<ParticleSystem>();
// Particles in each system.
// Second dimension initialized to max particle count
// and not modified unless max particle count for that system changes.
// Prevents allocations each frame.
ParticleSystem.Particle[][] particleSystemParticles;
ParticleSystem.MainModule[] particleSystemMainModules;
Renderer[] particleSystemRenderers;
// ^I could also just put the system and the module in a struct and make a 2D array
// instead of having a seperate array for the modules.
// Current iteration of the particle systems when looping through all of them.
// Useful to derived classes (like for the vortex particle affector).
protected ParticleSystem currentParticleSystem;
// Parameters used by derived force classes.
protected GetForceParameters parameters;
// Update even when entire particle system is invisible?
// Default: FALSE -> if all particles are invisible/offscreen,
// update will not execute.
public bool alwaysUpdate = false;
// =================================
// Functions.
// =================================
// ...
protected virtual void Awake()
{
}
// ...
protected virtual void Start()
{
particleSystem = GetComponent<ParticleSystem>();
}
// Called once per particle system, before entering second loop for its particles.
// Used for setting up based on particle system-specific data.
protected virtual void PerParticleSystemSetup()
{
}
// Direction is NOT normalized.
protected virtual Vector3 GetForce()
{
return Vector3.zero;
}
// ...
protected virtual void Update()
{
}
// Add/remove from public list of particles being managed.
// Remember that adding specific systems will override all
// other contexts (global and pure local).
// Duplicates are not checked (intentionally).
public void AddParticleSystem(ParticleSystem particleSystem)
{
_particleSystems.Add(particleSystem);
}
public void RemoveParticleSystem(ParticleSystem particleSystem)
{
_particleSystems.Remove(particleSystem);
}
// ...
protected virtual void LateUpdate()
{
_radius = scaledRadius;
radiusSqr = _radius * _radius;
forceDeltaTime = force * Time.deltaTime;
transformPosition = transform.position + offset;
// SELECTIVE.
// If manually assigned a set of systems, use those no matter what.
if (_particleSystems.Count != 0)
{
// If editor array size changed, clear and add again.
if (particleSystems.Count != _particleSystems.Count)
{
particleSystems.Clear();
particleSystems.AddRange(_particleSystems);
}
// Else if array size is the same, then re-assign from
// the editor array. I do this in case the elements are different
// even though the size is the same.
else
{
for (int i = 0; i < _particleSystems.Count; i++)
{
particleSystems[i] = _particleSystems[i];
}
}
}
// LOCAL.
// Else if attached to particle system, use only that.
// Obviously, this will only happen if there are no systems specified in the array.
else if (particleSystem)
{
// If just one element, assign as local PS component.
if (particleSystems.Count == 1)
{
particleSystems[0] = particleSystem;
}
// Else, clear entire array and add only the one.
else
{
particleSystems.Clear();
particleSystems.Add(particleSystem);
}
}
// GLOBAL.
// Else, take all the ones from the entire scene.
// This is the most expensive since it searches the entire scene
// and also requires an allocation for every frame due to not knowing
// if the particle systems are all the same from the last frame unless
// I had a list to compare to from last frame. In that case, I'm not sure
// if the performance would be better or worse. Do a test later?
else
{
particleSystems.Clear();
particleSystems.AddRange(FindObjectsOfType<ParticleSystem>());
}
parameters = new GetForceParameters();
particleSystemsCount = particleSystems.Count;
// If first frame (array is null) or length is less than the number of systems, initialize size of array.
// I never shrink the array. Not sure if that's potentially super bad? I could always throw in a public
// bool as an option to allow shrinking since there's a performance benefit for each, but depends on the
// implementation case.
if (particleSystemParticles == null || particleSystemParticles.Length < particleSystemsCount)
{
particleSystemParticles = new ParticleSystem.Particle[particleSystemsCount][];
particleSystemMainModules = new ParticleSystem.MainModule[particleSystemsCount];
particleSystemRenderers = new Renderer[particleSystemsCount];
particleSystemExternalForcesMultipliers = new float[particleSystemsCount];
for (int i = 0; i < particleSystemsCount; i++)
{
particleSystemMainModules[i] = particleSystems[i].main;
particleSystemRenderers[i] = particleSystems[i].GetComponent<Renderer>();
particleSystemExternalForcesMultipliers[i] = particleSystems[i].externalForces.multiplier;
}
}
for (int i = 0; i < particleSystemsCount; i++)
{
if (!particleSystemRenderers[i].isVisible && !alwaysUpdate)
{
continue;
}
int maxParticles = particleSystemMainModules[i].maxParticles;
if (particleSystemParticles[i] == null || particleSystemParticles[i].Length < maxParticles)
{
particleSystemParticles[i] = new ParticleSystem.Particle[maxParticles];
}
currentParticleSystem = particleSystems[i];
PerParticleSystemSetup();
int particleCount = currentParticleSystem.GetParticles(particleSystemParticles[i]);
ParticleSystemSimulationSpace simulationSpace = particleSystemMainModules[i].simulationSpace;
ParticleSystemScalingMode scalingMode = particleSystemMainModules[i].scalingMode;
// I could also store the transforms in an array similar to what I do with modules.
// Or, put all of those together into a struct and make an array out of that since
// they'll always be assigned/updated at the same time.
Transform currentParticleSystemTransform = currentParticleSystem.transform;
Transform customSimulationSpaceTransform = particleSystemMainModules[i].customSimulationSpace;
// If in world space, there's no need to do any of the extra calculations... simplify the loop!
if (simulationSpace == ParticleSystemSimulationSpace.World)
{
for (int j = 0; j < particleCount; j++)
{
parameters.particlePosition = particleSystemParticles[i][j].position;
parameters.scaledDirectionToAffectorCenter.x = transformPosition.x - parameters.particlePosition.x;
parameters.scaledDirectionToAffectorCenter.y = transformPosition.y - parameters.particlePosition.y;
parameters.scaledDirectionToAffectorCenter.z = transformPosition.z - parameters.particlePosition.z;
parameters.distanceToAffectorCenterSqr = parameters.scaledDirectionToAffectorCenter.sqrMagnitude;
if (parameters.distanceToAffectorCenterSqr < radiusSqr)
{
float distanceToCenterNormalized = parameters.distanceToAffectorCenterSqr / radiusSqr;
float distanceScale = scaleForceByDistance.Evaluate(distanceToCenterNormalized);
Vector3 force = GetForce();
float forceScale = (forceDeltaTime * distanceScale) * particleSystemExternalForcesMultipliers[i];
force.x *= forceScale;
force.y *= forceScale;
force.z *= forceScale;
Vector3 particleVelocity = particleSystemParticles[i][j].velocity;
particleVelocity.x += force.x;
particleVelocity.y += force.y;
particleVelocity.z += force.z;
particleSystemParticles[i][j].velocity = particleVelocity;
}
}
}
else
{
Vector3 particleSystemPosition = Vector3.zero;
Quaternion particleSystemRotation = Quaternion.identity;
Vector3 particleSystemLocalScale = Vector3.one;
Transform simulationSpaceTransform = currentParticleSystemTransform;
switch (simulationSpace)
{
case ParticleSystemSimulationSpace.Local:
{
particleSystemPosition = simulationSpaceTransform.position;
particleSystemRotation = simulationSpaceTransform.rotation;
particleSystemLocalScale = simulationSpaceTransform.localScale;
break;
}
case ParticleSystemSimulationSpace.Custom:
{
simulationSpaceTransform = customSimulationSpaceTransform;
particleSystemPosition = simulationSpaceTransform.position;
particleSystemRotation = simulationSpaceTransform.rotation;
particleSystemLocalScale = simulationSpaceTransform.localScale;
break;
}
default:
{
throw new System.NotSupportedException(
string.Format("Unsupported scaling mode '{0}'.", simulationSpace));
}
}
for (int j = 0; j < particleCount; j++)
{
parameters.particlePosition = particleSystemParticles[i][j].position;
switch (simulationSpace)
{
case ParticleSystemSimulationSpace.Local:
case ParticleSystemSimulationSpace.Custom:
{
switch (scalingMode)
{
case ParticleSystemScalingMode.Hierarchy:
{
parameters.particlePosition = simulationSpaceTransform.TransformPoint(particleSystemParticles[i][j].position);
break;
}
case ParticleSystemScalingMode.Local:
{
// Order is important.
parameters.particlePosition = Vector3.Scale(parameters.particlePosition, particleSystemLocalScale);
parameters.particlePosition = particleSystemRotation * parameters.particlePosition;
parameters.particlePosition = parameters.particlePosition + particleSystemPosition;
break;
}
case ParticleSystemScalingMode.Shape:
{
parameters.particlePosition = particleSystemRotation * parameters.particlePosition;
parameters.particlePosition = parameters.particlePosition + particleSystemPosition;
break;
}
default:
{
throw new System.NotSupportedException(
string.Format("Unsupported scaling mode '{0}'.", scalingMode));
}
}
break;
}
}
parameters.scaledDirectionToAffectorCenter.x = transformPosition.x - parameters.particlePosition.x;
parameters.scaledDirectionToAffectorCenter.y = transformPosition.y - parameters.particlePosition.y;
parameters.scaledDirectionToAffectorCenter.z = transformPosition.z - parameters.particlePosition.z;
parameters.distanceToAffectorCenterSqr = parameters.scaledDirectionToAffectorCenter.sqrMagnitude;
//particleSystemParticles[i][j].velocity += forceDeltaTime * Vector3.Normalize(parameters.scaledDirectionToAffectorCenter);
if (parameters.distanceToAffectorCenterSqr < radiusSqr)
{
// 0.0f -> 0.99...f;
float distanceToCenterNormalized = parameters.distanceToAffectorCenterSqr / radiusSqr;
// Evaluating a curve within a loop which is very likely to exceed a few thousand
// iterations produces a noticeable FPS drop (around minus 2 - 5). Might be a worthwhile
// optimization to check outside all loops if the curve is constant (all keyframes same value),
// and then run a different block of code if true that uses that value as a stored float without
// having to call Evaluate(t).
float distanceScale = scaleForceByDistance.Evaluate(distanceToCenterNormalized);
// Expanded vector operations for optimization. I think this is already done by
// the compiler, but it's nice to have for the editor anyway.
Vector3 force = GetForce();
float forceScale = (forceDeltaTime * distanceScale) * particleSystemExternalForcesMultipliers[i];
force.x *= forceScale;
force.y *= forceScale;
force.z *= forceScale;
switch (simulationSpace)
{
case ParticleSystemSimulationSpace.Local:
case ParticleSystemSimulationSpace.Custom:
{
switch (scalingMode)
{
case ParticleSystemScalingMode.Hierarchy:
{
force = simulationSpaceTransform.InverseTransformVector(force);
break;
}
case ParticleSystemScalingMode.Local:
{
// Order is important.
// Notice how rotation and scale orders are reversed.
force = Quaternion.Inverse(particleSystemRotation) * force;
force = Vector3.Scale(force, new Vector3(
1.0f / particleSystemLocalScale.x,
1.0f / particleSystemLocalScale.y,
1.0f / particleSystemLocalScale.z));
break;
}
case ParticleSystemScalingMode.Shape:
{
force = Quaternion.Inverse(particleSystemRotation) * force;
break;
}
// This would technically never execute since it's checked earlier (above).
default:
{
throw new System.NotSupportedException(
string.Format("Unsupported scaling mode '{0}'.", scalingMode));
}
}
break;
}
}
Vector3 particleVelocity = particleSystemParticles[i][j].velocity;
particleVelocity.x += force.x;
particleVelocity.y += force.y;
particleVelocity.z += force.z;
particleSystemParticles[i][j].velocity = particleVelocity;
}
}
}
currentParticleSystem.SetParticles(particleSystemParticles[i], particleCount);
}
}
// ...
void OnApplicationQuit()
{
}
// ...
protected virtual void OnDrawGizmosSelected()
{
Gizmos.color = Color.green;
Gizmos.DrawWireSphere(transform.position + offset, scaledRadius);
}
// =================================
// End functions.
// =================================
}
// =================================
// End namespace.
// =================================
}
}
}
// =================================
// --END-- //
// =================================

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 9fbb01249b8f1d8419cf21b6846cb507
timeCreated: 1470567813
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,263 @@
// =================================
// Namespaces.
// =================================
using UnityEngine;
// =================================
// Define namespace.
// =================================
namespace MirzaBeig
{
namespace Scripting
{
namespace Effects
{
// =================================
// Classes.
// =================================
public class TurbulenceParticleAffector : ParticleAffector
{
// =================================
// Nested classes and structures.
// =================================
// ...
public enum NoiseType
{
PseudoPerlin,
Perlin,
Simplex,
OctavePerlin,
OctaveSimplex
}
// =================================
// Variables.
// =================================
// ...
[Header("Affector Controls")]
public float speed = 1.0f;
[Range(0.0f, 8.0f)]
public float frequency = 1.0f;
public NoiseType noiseType = NoiseType.Perlin;
// ...
[Header("Octave Variant-Only Controls")]
[Range(1, 8)]
public int octaves = 1;
[Range(0.0f, 4.0f)]
public float lacunarity = 2.0f;
[Range(0.0f, 1.0f)]
public float persistence = 0.5f;
float time;
// Noise start offsets.
float randomX;
float randomY;
float randomZ;
// Final offset.
float offsetX;
float offsetY;
float offsetZ;
// =================================
// Functions.
// =================================
// ...
protected override void Awake()
{
base.Awake();
}
// ...
protected override void Start()
{
base.Start();
// ...
randomX = Random.Range(-32.0f, 32.0f);
randomY = Random.Range(-32.0f, 32.0f);
randomZ = Random.Range(-32.0f, 32.0f);
}
// ...
protected override void Update()
{
time = Time.time;
// ...
base.Update();
}
// ...
protected override void LateUpdate()
{
offsetX = (time * speed) + randomX;
offsetY = (time * speed) + randomY;
offsetZ = (time * speed) + randomZ;
// ...
base.LateUpdate();
}
// ...
protected override Vector3 GetForce()
{
// I could also pre-multiply the frequency, but
// all the octave variants also use frequency
// within themselves, so it would cause redundant
// multiplication.
float xX = parameters.particlePosition.x + offsetX;
float yX = parameters.particlePosition.y + offsetX;
float zX = parameters.particlePosition.z + offsetX;
float xY = parameters.particlePosition.x + offsetY;
float yY = parameters.particlePosition.y + offsetY;
float zY = parameters.particlePosition.z + offsetY;
float xZ = parameters.particlePosition.x + offsetZ;
float yZ = parameters.particlePosition.y + offsetZ;
float zZ = parameters.particlePosition.z + offsetZ;
Vector3 force;
switch (noiseType)
{
case NoiseType.PseudoPerlin:
{
// This isn't really right, but... it gives believable-enough results.
// It's also much faster than real perlin noise.
// It works well where you don't have to animate a large field where
// the repeating pattern would otherwise be easily seen.
// Examples of good uses: smoke trail particle turbulence.
// Example of bad uses: particle box simulating waves or something...
float noiseX = Mathf.PerlinNoise(xX * frequency, yY * frequency);
float noiseY = Mathf.PerlinNoise(xX * frequency, zY * frequency);
float noiseZ = Mathf.PerlinNoise(xX * frequency, xY * frequency);
noiseX = Mathf.Lerp(-1.0f, 1.0f, noiseX);
noiseY = Mathf.Lerp(-1.0f, 1.0f, noiseY);
noiseZ = Mathf.Lerp(-1.0f, 1.0f, noiseZ);
Vector3 forceX = (Vector3.right * noiseX);
Vector3 forceY = (Vector3.up * noiseY);
Vector3 forceZ = (Vector3.forward * noiseZ);
force = forceX + forceY + forceZ;
break;
}
// ...
default:
case NoiseType.Perlin:
{
force.x = Noise.perlin(xX * frequency, yX * frequency, zX * frequency);
force.y = Noise.perlin(xY * frequency, yY * frequency, zY * frequency);
force.z = Noise.perlin(xZ * frequency, yZ * frequency, zZ * frequency);
return force;
}
// ...
case NoiseType.Simplex:
{
force.x = Noise.simplex(xX * frequency, yX * frequency, zX * frequency);
force.y = Noise.simplex(xY * frequency, yY * frequency, zY * frequency);
force.z = Noise.simplex(xZ * frequency, yZ * frequency, zZ * frequency);
break;
}
// ...
case NoiseType.OctavePerlin:
{
force.x = Noise.octavePerlin(xX, yX, zX, frequency, octaves, lacunarity, persistence);
force.y = Noise.octavePerlin(xY, yY, zY, frequency, octaves, lacunarity, persistence);
force.z = Noise.octavePerlin(xZ, yZ, zZ, frequency, octaves, lacunarity, persistence);
break;
}
case NoiseType.OctaveSimplex:
{
force.x = Noise.octaveSimplex(xX, yX, zX, frequency, octaves, lacunarity, persistence);
force.y = Noise.octaveSimplex(xY, yY, zY, frequency, octaves, lacunarity, persistence);
force.z = Noise.octaveSimplex(xZ, yZ, zZ, frequency, octaves, lacunarity, persistence);
break;
}
}
return force;
}
// ...
protected override void OnDrawGizmosSelected()
{
if (enabled)
{
base.OnDrawGizmosSelected();
}
}
// =================================
// End functions.
// =================================
}
// =================================
// End namespace.
// =================================
}
}
}
// =================================
// --END-- //
// =================================

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 80ca8d20214f40846b9e49b318255592
timeCreated: 1470567813
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,164 @@
// =================================
// Namespaces.
// =================================
using UnityEngine;
// =================================
// Define namespace.
// =================================
namespace MirzaBeig
{
namespace Scripting
{
namespace Effects
{
// =================================
// Classes.
// =================================
public class VortexParticleAffector : ParticleAffector
{
// =================================
// Nested classes and structures.
// =================================
// ...
// =================================
// Variables.
// =================================
// ...
Vector3 axisOfRotation;
[Header("Affector Controls")]
// Useful if particle affector and particle system
// are on the same game object, and you need a seperate
// rotation for the system, and the affector, but don't
// want to make the two different game objects.
public Vector3 axisOfRotationOffset = Vector3.zero;
// =================================
// Functions.
// =================================
// ...
protected override void Awake()
{
base.Awake();
}
// ...
protected override void Start()
{
base.Start();
}
// ...
protected override void Update()
{
base.Update();
}
// ...
protected override void LateUpdate()
{
base.LateUpdate();
}
// ...
void UpdateAxisOfRotation()
{
axisOfRotation = Quaternion.Euler(axisOfRotationOffset) * transform.up;
}
// ...
protected override void PerParticleSystemSetup()
{
UpdateAxisOfRotation();
}
// ...
protected override Vector3 GetForce()
{
// With no rotation, looking at the PS with the vortex down the Z axis, you may
// think it's spinning the wrong way because it's counter-clockwise. But it's actually correct...
// Because if you were to look up aligned with the up-axis of the vortex, you'd see it spinning
// clockwise. And if that up was inverted (you looked down at the vortex from above), then it would
// be spinning counter-clockwise since now the vector of rotation is point at you, not away from you.
// I can't believe I almost mixed that up by adding a negative (-) in front of the return.
return Vector3.Normalize(Vector3.Cross(axisOfRotation, parameters.scaledDirectionToAffectorCenter));
}
// ...
protected override void OnDrawGizmosSelected()
{
if (enabled)
{
base.OnDrawGizmosSelected();
// ...
Gizmos.color = Color.red;
// When not playing, I don't have a reference to the specific particle system,
// so just use the default method of showing the axis of rotation (which may be wrong).
// There's no easy way around this since I may have several particle systems being updated
// with a single vortex. It's just a visual guide anyways, so no big deal, I suppose.
Vector3 axisOfRotation;
if (Application.isPlaying && enabled)
{
UpdateAxisOfRotation();
axisOfRotation = this.axisOfRotation;
}
else
{
axisOfRotation = Quaternion.Euler(axisOfRotationOffset) * transform.up;
}
Gizmos.DrawLine(transform.position + offset, (transform.position + offset) + (axisOfRotation * scaledRadius));
}
}
// =================================
// End functions.
// =================================
}
// =================================
// End namespace.
// =================================
}
}
}
// =================================
// --END-- //
// =================================

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 39e8c956cffbc4b4ba68531bef53e1d4
timeCreated: 1470567812
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: