added animation package and made small changes
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 40587c37bffeec44581d661b302b88ce
|
||||
folderAsset: yes
|
||||
timeCreated: 1470101287
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ad67b6f6ac17a1c44bb26a6ecd06e9ea
|
||||
folderAsset: yes
|
||||
timeCreated: 1485465640
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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-- //
|
||||
// =================================
|
||||
@@ -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
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d566a25d31a988844a80d2747af4986e
|
||||
timeCreated: 1458196122
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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-- //
|
||||
// =================================
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9fbb01249b8f1d8419cf21b6846cb507
|
||||
timeCreated: 1470567813
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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-- //
|
||||
// =================================
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 80ca8d20214f40846b9e49b318255592
|
||||
timeCreated: 1470567813
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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-- //
|
||||
// =================================
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 39e8c956cffbc4b4ba68531bef53e1d4
|
||||
timeCreated: 1470567812
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 35f64f26eb6e5f04bb370e3f131891db
|
||||
folderAsset: yes
|
||||
timeCreated: 1488921461
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,400 @@
|
||||
|
||||
// =================================
|
||||
// Namespaces.
|
||||
// =================================
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
// =================================
|
||||
// Define namespace.
|
||||
// =================================
|
||||
|
||||
namespace MirzaBeig
|
||||
{
|
||||
|
||||
namespace Scripting
|
||||
{
|
||||
|
||||
namespace Effects
|
||||
{
|
||||
|
||||
// =================================
|
||||
// Classes.
|
||||
// =================================
|
||||
|
||||
[RequireComponent(typeof(ParticleSystem))]
|
||||
public class ParticleFlocking : MonoBehaviour
|
||||
{
|
||||
// =================================
|
||||
// Nested classes and structures.
|
||||
// =================================
|
||||
|
||||
// ...
|
||||
|
||||
public struct Voxel
|
||||
{
|
||||
public Bounds bounds;
|
||||
public int[] particles;
|
||||
|
||||
public int particleCount;
|
||||
}
|
||||
|
||||
// =================================
|
||||
// Variables.
|
||||
// =================================
|
||||
|
||||
// ...
|
||||
|
||||
[Header("N^2 Mode Settings")]
|
||||
|
||||
public float maxDistance = 0.5f;
|
||||
|
||||
[Header("Forces")]
|
||||
|
||||
public float cohesion = 0.5f;
|
||||
public float separation = 0.25f;
|
||||
|
||||
[Header("Voxel Mode Settings")]
|
||||
|
||||
public bool useVoxels = true;
|
||||
public bool voxelLocalCenterFromBounds = true;
|
||||
|
||||
public float voxelVolume = 8.0f;
|
||||
public int voxelsPerAxis = 5;
|
||||
|
||||
int previousVoxelsPerAxisValue;
|
||||
|
||||
Voxel[] voxels;
|
||||
new ParticleSystem particleSystem;
|
||||
|
||||
ParticleSystem.Particle[] particles;
|
||||
Vector3[] particlePositions;
|
||||
|
||||
ParticleSystem.MainModule particleSystemMainModule;
|
||||
|
||||
[Header("General Performance Settings")]
|
||||
|
||||
[Range(0.0f, 1.0f)]
|
||||
public float delay = 0.0f;
|
||||
|
||||
float timer;
|
||||
|
||||
public bool alwaysUpdate = false;
|
||||
bool visible;
|
||||
|
||||
// =================================
|
||||
// Functions.
|
||||
// =================================
|
||||
|
||||
// ...
|
||||
|
||||
void Start()
|
||||
{
|
||||
particleSystem = GetComponent<ParticleSystem>();
|
||||
particleSystemMainModule = particleSystem.main;
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
void OnBecameVisible()
|
||||
{
|
||||
visible = true;
|
||||
}
|
||||
void OnBecameInvisible()
|
||||
{
|
||||
visible = false;
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
void buildVoxelGrid()
|
||||
{
|
||||
int voxelCount =
|
||||
voxelsPerAxis * voxelsPerAxis * voxelsPerAxis;
|
||||
|
||||
voxels = new Voxel[voxelCount];
|
||||
|
||||
float voxelSize = voxelVolume / voxelsPerAxis;
|
||||
|
||||
float voxelSizeHalf = voxelSize / 2.0f;
|
||||
float voxelVolumeHalf = voxelVolume / 2.0f;
|
||||
|
||||
Vector3 positionBase = transform.position;
|
||||
|
||||
int i = 0;
|
||||
|
||||
for (int x = 0; x < voxelsPerAxis; x++)
|
||||
{
|
||||
float posX = (-voxelVolumeHalf + voxelSizeHalf) + (x * voxelSize);
|
||||
|
||||
for (int y = 0; y < voxelsPerAxis; y++)
|
||||
{
|
||||
float posY = (-voxelVolumeHalf + voxelSizeHalf) + (y * voxelSize);
|
||||
|
||||
for (int z = 0; z < voxelsPerAxis; z++)
|
||||
{
|
||||
float posZ = (-voxelVolumeHalf + voxelSizeHalf) + (z * voxelSize);
|
||||
|
||||
voxels[i].particleCount = 0;
|
||||
voxels[i].bounds = new Bounds(positionBase + new Vector3(posX, posY, posZ), Vector3.one * voxelSize);
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
void LateUpdate()
|
||||
{
|
||||
if (alwaysUpdate || visible)
|
||||
{
|
||||
if (useVoxels)
|
||||
{
|
||||
int voxelCount =
|
||||
voxelsPerAxis * voxelsPerAxis * voxelsPerAxis;
|
||||
|
||||
if (voxels == null || voxels.Length < voxelCount)
|
||||
{
|
||||
buildVoxelGrid();
|
||||
}
|
||||
}
|
||||
|
||||
int maxParticles = particleSystemMainModule.maxParticles;
|
||||
|
||||
if (particles == null || particles.Length < maxParticles)
|
||||
{
|
||||
particles = new ParticleSystem.Particle[maxParticles];
|
||||
particlePositions = new Vector3[maxParticles];
|
||||
|
||||
if (useVoxels)
|
||||
{
|
||||
for (int i = 0; i < voxels.Length; i++)
|
||||
{
|
||||
voxels[i].particles = new int[maxParticles];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
timer += Time.deltaTime;
|
||||
|
||||
if (timer >= delay)
|
||||
{
|
||||
float deltaTime = timer;
|
||||
timer = 0.0f;
|
||||
|
||||
particleSystem.GetParticles(particles);
|
||||
int particleCount = particleSystem.particleCount;
|
||||
|
||||
float cohesionDeltaTime = cohesion * deltaTime;
|
||||
float separationDeltaTime = separation * deltaTime;
|
||||
|
||||
for (int i = 0; i < particleCount; i++)
|
||||
{
|
||||
particlePositions[i] = particles[i].position;
|
||||
}
|
||||
|
||||
if (useVoxels)
|
||||
{
|
||||
int voxelCount = voxels.Length;
|
||||
float voxelSize = voxelVolume / voxelsPerAxis;
|
||||
|
||||
for (int i = 0; i < particleCount; i++)
|
||||
{
|
||||
for (int j = 0; j < voxelCount; j++)
|
||||
{
|
||||
if (voxels[j].bounds.Contains(particlePositions[i]))
|
||||
{
|
||||
voxels[j].particles[voxels[j].particleCount] = i;
|
||||
voxels[j].particleCount++;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < voxelCount; i++)
|
||||
{
|
||||
if (voxels[i].particleCount > 1)
|
||||
{
|
||||
for (int j = 0; j < voxels[i].particleCount; j++)
|
||||
{
|
||||
Vector3 directionToLocalCenter;
|
||||
Vector3 localCenter = particlePositions[voxels[i].particles[j]];
|
||||
|
||||
if (voxelLocalCenterFromBounds)
|
||||
{
|
||||
directionToLocalCenter = voxels[i].bounds.center - particlePositions[voxels[i].particles[j]];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int k = 0; k < voxels[i].particleCount; k++)
|
||||
{
|
||||
if (k == j)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
localCenter += particlePositions[voxels[i].particles[k]];
|
||||
}
|
||||
|
||||
localCenter /= voxels[i].particleCount;
|
||||
|
||||
directionToLocalCenter = localCenter - particlePositions[voxels[i].particles[j]];
|
||||
}
|
||||
|
||||
float distanceToLocalCenterSqr = directionToLocalCenter.sqrMagnitude;
|
||||
|
||||
directionToLocalCenter.Normalize();
|
||||
|
||||
Vector3 force = Vector3.zero;
|
||||
|
||||
force += directionToLocalCenter * cohesionDeltaTime;
|
||||
force -= directionToLocalCenter * ((1.0f - (distanceToLocalCenterSqr / voxelSize)) * separationDeltaTime);
|
||||
|
||||
Vector3 particleVelocity = particles[voxels[i].particles[j]].velocity;
|
||||
|
||||
particleVelocity.x += force.x;
|
||||
particleVelocity.y += force.y;
|
||||
particleVelocity.z += force.z;
|
||||
|
||||
particles[voxels[i].particles[j]].velocity = particleVelocity;
|
||||
}
|
||||
|
||||
voxels[i].particleCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float maxDistanceSqr = maxDistance * maxDistance;
|
||||
|
||||
Vector3 p1p2_difference;
|
||||
|
||||
for (int i = 0; i < particleCount; i++)
|
||||
{
|
||||
int localCount = 1;
|
||||
Vector3 localCenter = particlePositions[i];
|
||||
|
||||
for (int j = 0; j < particleCount; j++)
|
||||
{
|
||||
if (j == i)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
p1p2_difference.x = particlePositions[i].x - particlePositions[j].x;
|
||||
p1p2_difference.y = particlePositions[i].y - particlePositions[j].y;
|
||||
p1p2_difference.z = particlePositions[i].z - particlePositions[j].z;
|
||||
|
||||
float distanceSqr = Vector3.SqrMagnitude(p1p2_difference);
|
||||
|
||||
// TODO: Expand vector arithmetic for performance.
|
||||
|
||||
if (distanceSqr <= maxDistanceSqr)
|
||||
{
|
||||
localCount++;
|
||||
localCenter += particlePositions[j];
|
||||
}
|
||||
}
|
||||
|
||||
if (localCount != 1)
|
||||
{
|
||||
localCenter /= localCount;
|
||||
|
||||
Vector3 directionToLocalCenter = localCenter - particlePositions[i];
|
||||
float distanceToLocalCenterSqr = directionToLocalCenter.sqrMagnitude;
|
||||
|
||||
directionToLocalCenter.Normalize();
|
||||
|
||||
Vector3 force = Vector3.zero;
|
||||
|
||||
force += directionToLocalCenter * cohesionDeltaTime;
|
||||
force -= directionToLocalCenter * ((1.0f - (distanceToLocalCenterSqr / maxDistanceSqr)) * separationDeltaTime);
|
||||
|
||||
Vector3 particleVelocity = particles[i].velocity;
|
||||
|
||||
particleVelocity.x += force.x;
|
||||
particleVelocity.y += force.y;
|
||||
particleVelocity.z += force.z;
|
||||
|
||||
particles[i].velocity = particleVelocity;
|
||||
}
|
||||
|
||||
//Vector3 velocity = particles[i].velocity;
|
||||
|
||||
//if (velocity != Vector3.zero)
|
||||
//{
|
||||
// particles[i].rotation3D = Quaternion.LookRotation(velocity, Vector3.up).eulerAngles;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
particleSystem.SetParticles(particles, particleCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
void OnDrawGizmosSelected()
|
||||
{
|
||||
//buildVoxelGrid();
|
||||
|
||||
//for (int i = 0; i < voxels.Length; i++)
|
||||
//{
|
||||
// Gizmos.DrawWireCube(voxels[i].bounds.center, voxels[i].bounds.size);
|
||||
//}
|
||||
|
||||
float size = voxelVolume / voxelsPerAxis;
|
||||
|
||||
float sizeHalf = size / 2.0f;
|
||||
float totalSizeHalf = voxelVolume / 2.0f;
|
||||
|
||||
Vector3 positionBase = transform.position;
|
||||
|
||||
Gizmos.color = Color.red;
|
||||
|
||||
Gizmos.DrawWireCube(positionBase, Vector3.one * voxelVolume);
|
||||
|
||||
Gizmos.color = Color.white;
|
||||
|
||||
for (int x = 0; x < voxelsPerAxis; x++)
|
||||
{
|
||||
float posX = (-totalSizeHalf + sizeHalf) + (x * size);
|
||||
|
||||
for (int y = 0; y < voxelsPerAxis; y++)
|
||||
{
|
||||
float posY = (-totalSizeHalf + sizeHalf) + (y * size);
|
||||
|
||||
for (int z = 0; z < voxelsPerAxis; z++)
|
||||
{
|
||||
float posZ = (-totalSizeHalf + sizeHalf) + (z * size);
|
||||
|
||||
Gizmos.DrawWireCube(positionBase + new Vector3(posX, posY, posZ), Vector3.one * size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =================================
|
||||
// End functions.
|
||||
// =================================
|
||||
|
||||
}
|
||||
|
||||
// =================================
|
||||
// End namespace.
|
||||
// =================================
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// =================================
|
||||
// --END-- //
|
||||
// =================================
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dc4f2f91673ed344bbefeab4a66ff936
|
||||
timeCreated: 1470567812
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ced1f8ff08c38be499ef34841ec4fa6d
|
||||
folderAsset: yes
|
||||
timeCreated: 1470101287
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a74ae461ef09d524ca0587ac54bac419
|
||||
folderAsset: yes
|
||||
timeCreated: 1508401765
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,320 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 8a3bdb2cd68f901469e7cc149151eb49, type: 3}
|
||||
m_Name: Particle Force Field Post-Processing Profile
|
||||
m_EditorClassIdentifier:
|
||||
debugViews:
|
||||
m_Enabled: 1
|
||||
m_Settings:
|
||||
mode: 0
|
||||
depth:
|
||||
scale: 1
|
||||
motionVectors:
|
||||
sourceOpacity: 1
|
||||
motionImageOpacity: 0
|
||||
motionImageAmplitude: 16
|
||||
motionVectorsOpacity: 1
|
||||
motionVectorsResolution: 24
|
||||
motionVectorsAmplitude: 64
|
||||
fog:
|
||||
m_Enabled: 0
|
||||
m_Settings:
|
||||
excludeSkybox: 1
|
||||
antialiasing:
|
||||
m_Enabled: 0
|
||||
m_Settings:
|
||||
method: 0
|
||||
fxaaSettings:
|
||||
preset: 2
|
||||
taaSettings:
|
||||
jitterSpread: 0.75
|
||||
sharpen: 0.3
|
||||
stationaryBlending: 0.95
|
||||
motionBlending: 0.85
|
||||
ambientOcclusion:
|
||||
m_Enabled: 0
|
||||
m_Settings:
|
||||
intensity: 1
|
||||
radius: 0.3
|
||||
sampleCount: 10
|
||||
downsampling: 1
|
||||
forceForwardCompatibility: 0
|
||||
ambientOnly: 0
|
||||
highPrecision: 0
|
||||
screenSpaceReflection:
|
||||
m_Enabled: 0
|
||||
m_Settings:
|
||||
reflection:
|
||||
blendType: 0
|
||||
reflectionQuality: 2
|
||||
maxDistance: 100
|
||||
iterationCount: 256
|
||||
stepSize: 3
|
||||
widthModifier: 0.5
|
||||
reflectionBlur: 1
|
||||
reflectBackfaces: 0
|
||||
intensity:
|
||||
reflectionMultiplier: 1
|
||||
fadeDistance: 100
|
||||
fresnelFade: 1
|
||||
fresnelFadePower: 1
|
||||
screenEdgeMask:
|
||||
intensity: 0.03
|
||||
depthOfField:
|
||||
m_Enabled: 0
|
||||
m_Settings:
|
||||
focusDistance: 5
|
||||
aperture: 5.6
|
||||
focalLength: 50
|
||||
useCameraFov: 0
|
||||
kernelSize: 1
|
||||
motionBlur:
|
||||
m_Enabled: 0
|
||||
m_Settings:
|
||||
shutterAngle: 270
|
||||
sampleCount: 10
|
||||
frameBlending: 0
|
||||
eyeAdaptation:
|
||||
m_Enabled: 0
|
||||
m_Settings:
|
||||
lowPercent: 45
|
||||
highPercent: 95
|
||||
minLuminance: -5
|
||||
maxLuminance: 1
|
||||
keyValue: 0.25
|
||||
dynamicKeyValue: 1
|
||||
adaptationType: 0
|
||||
speedUp: 2
|
||||
speedDown: 1
|
||||
logMin: -8
|
||||
logMax: 4
|
||||
bloom:
|
||||
m_Enabled: 1
|
||||
m_Settings:
|
||||
bloom:
|
||||
intensity: 5
|
||||
threshold: 0.5
|
||||
softKnee: 0
|
||||
radius: 5.5
|
||||
antiFlicker: 0
|
||||
lensDirt:
|
||||
texture: {fileID: 0}
|
||||
intensity: 3
|
||||
colorGrading:
|
||||
m_Enabled: 1
|
||||
m_Settings:
|
||||
tonemapping:
|
||||
tonemapper: 1
|
||||
neutralBlackIn: 0.02
|
||||
neutralWhiteIn: 10
|
||||
neutralBlackOut: 0
|
||||
neutralWhiteOut: 10
|
||||
neutralWhiteLevel: 5.3
|
||||
neutralWhiteClip: 10
|
||||
basic:
|
||||
postExposure: 2
|
||||
temperature: 0
|
||||
tint: 0
|
||||
hueShift: 0
|
||||
saturation: 1
|
||||
contrast: 1
|
||||
channelMixer:
|
||||
red: {x: 1, y: 0, z: 0}
|
||||
green: {x: 0, y: 1, z: 0}
|
||||
blue: {x: 0, y: 0, z: 1}
|
||||
currentEditingChannel: 0
|
||||
colorWheels:
|
||||
mode: 1
|
||||
log:
|
||||
slope: {r: 1, g: 1, b: 1, a: 0}
|
||||
power: {r: 1, g: 1, b: 1, a: 0}
|
||||
offset: {r: 1, g: 1, b: 1, a: 0}
|
||||
linear:
|
||||
lift: {r: 0, g: 0, b: 0, a: 0}
|
||||
gamma: {r: 0, g: 0, b: 0, a: 0}
|
||||
gain: {r: 0, g: 0, b: 0, a: 0}
|
||||
curves:
|
||||
master:
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 2
|
||||
time: 0
|
||||
value: 0
|
||||
inSlope: 1
|
||||
outSlope: 1
|
||||
tangentMode: 0
|
||||
- serializedVersion: 2
|
||||
time: 1
|
||||
value: 1
|
||||
inSlope: 1
|
||||
outSlope: 1
|
||||
tangentMode: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 0
|
||||
m_Loop: 0
|
||||
m_ZeroValue: 0
|
||||
m_Range: 1
|
||||
red:
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 2
|
||||
time: 0
|
||||
value: 0
|
||||
inSlope: 1
|
||||
outSlope: 1
|
||||
tangentMode: 0
|
||||
- serializedVersion: 2
|
||||
time: 1
|
||||
value: 1
|
||||
inSlope: 1
|
||||
outSlope: 1
|
||||
tangentMode: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
m_Loop: 0
|
||||
m_ZeroValue: 0
|
||||
m_Range: 1
|
||||
green:
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 2
|
||||
time: 0
|
||||
value: 0
|
||||
inSlope: 1
|
||||
outSlope: 1
|
||||
tangentMode: 0
|
||||
- serializedVersion: 2
|
||||
time: 1
|
||||
value: 1
|
||||
inSlope: 1
|
||||
outSlope: 1
|
||||
tangentMode: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
m_Loop: 0
|
||||
m_ZeroValue: 0
|
||||
m_Range: 1
|
||||
blue:
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 2
|
||||
time: 0
|
||||
value: 0
|
||||
inSlope: 1
|
||||
outSlope: 1
|
||||
tangentMode: 0
|
||||
- serializedVersion: 2
|
||||
time: 1
|
||||
value: 1
|
||||
inSlope: 1
|
||||
outSlope: 1
|
||||
tangentMode: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
m_Loop: 0
|
||||
m_ZeroValue: 0
|
||||
m_Range: 1
|
||||
hueVShue:
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve: []
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
m_Loop: 1
|
||||
m_ZeroValue: 0.5
|
||||
m_Range: 1
|
||||
hueVSsat:
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve: []
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
m_Loop: 1
|
||||
m_ZeroValue: 0.5
|
||||
m_Range: 1
|
||||
satVSsat:
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve: []
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
m_Loop: 0
|
||||
m_ZeroValue: 0.5
|
||||
m_Range: 1
|
||||
lumVSsat:
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve: []
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
m_Loop: 0
|
||||
m_ZeroValue: 0.5
|
||||
m_Range: 1
|
||||
e_CurrentEditingCurve: 0
|
||||
e_CurveY: 1
|
||||
e_CurveR: 0
|
||||
e_CurveG: 0
|
||||
e_CurveB: 0
|
||||
userLut:
|
||||
m_Enabled: 0
|
||||
m_Settings:
|
||||
lut: {fileID: 0}
|
||||
contribution: 1
|
||||
chromaticAberration:
|
||||
m_Enabled: 1
|
||||
m_Settings:
|
||||
spectralTexture: {fileID: 0}
|
||||
intensity: 0.5
|
||||
grain:
|
||||
m_Enabled: 0
|
||||
m_Settings:
|
||||
colored: 1
|
||||
intensity: 1
|
||||
size: 0.5
|
||||
luminanceContribution: 0.8
|
||||
vignette:
|
||||
m_Enabled: 1
|
||||
m_Settings:
|
||||
mode: 0
|
||||
color: {r: 0, g: 0, b: 0, a: 1}
|
||||
center: {x: 0.5, y: 0.5}
|
||||
intensity: 0.45
|
||||
smoothness: 0.2
|
||||
roundness: 1
|
||||
mask: {fileID: 0}
|
||||
opacity: 1
|
||||
rounded: 0
|
||||
dithering:
|
||||
m_Enabled: 0
|
||||
monitors:
|
||||
currentMonitorID: 0
|
||||
refreshOnPlay: 0
|
||||
histogramMode: 3
|
||||
waveformExposure: 0.12
|
||||
waveformY: 0
|
||||
waveformR: 1
|
||||
waveformG: 1
|
||||
waveformB: 1
|
||||
paradeExposure: 0.12
|
||||
vectorscopeExposure: 0.12
|
||||
vectorscopeShowBackground: 1
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dc09589739c6fec4bbf14e80ff95ce08
|
||||
timeCreated: 1508401783
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d8b68c38e6770da4fbcd49976f2773fe
|
||||
folderAsset: yes
|
||||
timeCreated: 1508395563
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cb32a6a0595ad4b42b5d833207fe16df
|
||||
timeCreated: 1508396100
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f489c4d963cccfd4a8fc22284a646a3e
|
||||
timeCreated: 1508470395
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f729b65a61a5a3445a30c10aa956f9e2
|
||||
folderAsset: yes
|
||||
timeCreated: 1508398165
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,302 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
using MirzaBeig.Scripting.Effects;
|
||||
|
||||
public class ParticleForceFieldsDemo : MonoBehaviour
|
||||
{
|
||||
[Header("Overview")]
|
||||
|
||||
public Text FPSText;
|
||||
public Text particleCountText;
|
||||
|
||||
public Toggle postProcessingToggle;
|
||||
public MonoBehaviour postProcessing;
|
||||
|
||||
[Header("Particle System Settings")]
|
||||
|
||||
new public ParticleSystem particleSystem;
|
||||
|
||||
ParticleSystem.MainModule particleSystemMainModule;
|
||||
ParticleSystem.EmissionModule particleSystemEmissionModule;
|
||||
|
||||
public Text maxParticlesText;
|
||||
public Text particlesPerSecondText;
|
||||
|
||||
public Slider maxParticlesSlider;
|
||||
public Slider particlesPerSecondSlider;
|
||||
|
||||
[Header("Attraction Particle Force Field Settings")]
|
||||
|
||||
public AttractionParticleForceField attractionParticleForceField;
|
||||
|
||||
public Text attractionParticleForceFieldRadiusText;
|
||||
public Text attractionParticleForceFieldMaxForceText;
|
||||
|
||||
public Text attractionParticleForceFieldArrivalRadiusText;
|
||||
public Text attractionParticleForceFieldArrivedRadiusText;
|
||||
|
||||
public Text attractionParticleForceFieldPositionTextX;
|
||||
public Text attractionParticleForceFieldPositionTextY;
|
||||
public Text attractionParticleForceFieldPositionTextZ;
|
||||
|
||||
public Slider attractionParticleForceFieldRadiusSlider;
|
||||
public Slider attractionParticleForceFieldMaxForceSlider;
|
||||
|
||||
public Slider attractionParticleForceFieldArrivalRadiusSlider;
|
||||
public Slider attractionParticleForceFieldArrivedRadiusSlider;
|
||||
|
||||
public Slider attractionParticleForceFieldPositionSliderX;
|
||||
public Slider attractionParticleForceFieldPositionSliderY;
|
||||
public Slider attractionParticleForceFieldPositionSliderZ;
|
||||
|
||||
[Header("Vortex Particle Force Field Settings")]
|
||||
|
||||
public VortexParticleForceField vortexParticleForceField;
|
||||
|
||||
public Text vortexParticleForceFieldRadiusText;
|
||||
public Text vortexParticleForceFieldMaxForceText;
|
||||
|
||||
public Text vortexParticleForceFieldRotationTextX;
|
||||
public Text vortexParticleForceFieldRotationTextY;
|
||||
public Text vortexParticleForceFieldRotationTextZ;
|
||||
|
||||
public Text vortexParticleForceFieldPositionTextX;
|
||||
public Text vortexParticleForceFieldPositionTextY;
|
||||
public Text vortexParticleForceFieldPositionTextZ;
|
||||
|
||||
public Slider vortexParticleForceFieldRadiusSlider;
|
||||
public Slider vortexParticleForceFieldMaxForceSlider;
|
||||
|
||||
public Slider vortexParticleForceFieldRotationSliderX;
|
||||
public Slider vortexParticleForceFieldRotationSliderY;
|
||||
public Slider vortexParticleForceFieldRotationSliderZ;
|
||||
|
||||
public Slider vortexParticleForceFieldPositionSliderX;
|
||||
public Slider vortexParticleForceFieldPositionSliderY;
|
||||
public Slider vortexParticleForceFieldPositionSliderZ;
|
||||
|
||||
void Start()
|
||||
{
|
||||
// Overview.
|
||||
|
||||
if (postProcessing)
|
||||
{
|
||||
postProcessingToggle.isOn = postProcessing.enabled;
|
||||
}
|
||||
|
||||
// Particle system settings.
|
||||
|
||||
particleSystemMainModule = particleSystem.main;
|
||||
particleSystemEmissionModule = particleSystem.emission;
|
||||
|
||||
maxParticlesSlider.value = particleSystemMainModule.maxParticles;
|
||||
particlesPerSecondSlider.value = particleSystemEmissionModule.rateOverTime.constant;
|
||||
|
||||
maxParticlesText.text = "Max Particles: " + maxParticlesSlider.value;
|
||||
particlesPerSecondText.text = "Particles Per Second: " + particlesPerSecondSlider.value;
|
||||
|
||||
// Attraction particle force field settings.
|
||||
|
||||
attractionParticleForceFieldRadiusSlider.value = attractionParticleForceField.radius;
|
||||
attractionParticleForceFieldMaxForceSlider.value = attractionParticleForceField.force;
|
||||
|
||||
attractionParticleForceFieldArrivalRadiusSlider.value = attractionParticleForceField.arrivalRadius;
|
||||
attractionParticleForceFieldArrivedRadiusSlider.value = attractionParticleForceField.arrivedRadius;
|
||||
|
||||
Vector3 attractionParticleForceFieldPosition = attractionParticleForceField.transform.position;
|
||||
|
||||
attractionParticleForceFieldPositionSliderX.value = attractionParticleForceFieldPosition.x;
|
||||
attractionParticleForceFieldPositionSliderY.value = attractionParticleForceFieldPosition.y;
|
||||
attractionParticleForceFieldPositionSliderZ.value = attractionParticleForceFieldPosition.z;
|
||||
|
||||
attractionParticleForceFieldRadiusText.text = "Radius: " + attractionParticleForceFieldRadiusSlider.value;
|
||||
attractionParticleForceFieldMaxForceText.text = "Max Force: " + attractionParticleForceFieldMaxForceSlider.value;
|
||||
|
||||
attractionParticleForceFieldArrivalRadiusText.text = "Arrival Radius: " + attractionParticleForceFieldArrivalRadiusSlider.value;
|
||||
attractionParticleForceFieldArrivedRadiusText.text = "Arrived Radius: " + attractionParticleForceFieldArrivedRadiusSlider.value;
|
||||
|
||||
attractionParticleForceFieldPositionTextX.text = "Position X: " + attractionParticleForceFieldPositionSliderX.value;
|
||||
attractionParticleForceFieldPositionTextY.text = "Position Y: " + attractionParticleForceFieldPositionSliderY.value;
|
||||
attractionParticleForceFieldPositionTextZ.text = "Position Z: " + attractionParticleForceFieldPositionSliderZ.value;
|
||||
|
||||
// Vortex particle force field settings.
|
||||
|
||||
vortexParticleForceFieldRadiusSlider.value = vortexParticleForceField.radius;
|
||||
vortexParticleForceFieldMaxForceSlider.value = vortexParticleForceField.force;
|
||||
|
||||
Vector3 vortexParticleForceFieldRotation = vortexParticleForceField.transform.eulerAngles;
|
||||
|
||||
vortexParticleForceFieldRotationSliderX.value = vortexParticleForceFieldRotation.x;
|
||||
vortexParticleForceFieldRotationSliderY.value = vortexParticleForceFieldRotation.y;
|
||||
vortexParticleForceFieldRotationSliderZ.value = vortexParticleForceFieldRotation.z;
|
||||
|
||||
Vector3 vortexParticleForceFieldPosition = vortexParticleForceField.transform.position;
|
||||
|
||||
vortexParticleForceFieldPositionSliderX.value = vortexParticleForceFieldPosition.x;
|
||||
vortexParticleForceFieldPositionSliderY.value = vortexParticleForceFieldPosition.y;
|
||||
vortexParticleForceFieldPositionSliderZ.value = vortexParticleForceFieldPosition.z;
|
||||
|
||||
vortexParticleForceFieldRadiusText.text = "Radius: " + vortexParticleForceFieldRadiusSlider.value;
|
||||
vortexParticleForceFieldMaxForceText.text = "Max Force: " + vortexParticleForceFieldMaxForceSlider.value;
|
||||
|
||||
vortexParticleForceFieldRotationTextX.text = "Rotation X: " + vortexParticleForceFieldRotationSliderX.value;
|
||||
vortexParticleForceFieldRotationTextY.text = "Rotation Y: " + vortexParticleForceFieldRotationSliderY.value;
|
||||
vortexParticleForceFieldRotationTextZ.text = "Rotation Z: " + vortexParticleForceFieldRotationSliderZ.value;
|
||||
|
||||
vortexParticleForceFieldPositionTextX.text = "Position X: " + vortexParticleForceFieldPositionSliderX.value;
|
||||
vortexParticleForceFieldPositionTextY.text = "Position Y: " + vortexParticleForceFieldPositionSliderY.value;
|
||||
vortexParticleForceFieldPositionTextZ.text = "Position Z: " + vortexParticleForceFieldPositionSliderZ.value;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
// Overview.
|
||||
|
||||
FPSText.text = "FPS: " + 1.0f / Time.deltaTime;
|
||||
particleCountText.text = "Particle Count: " + particleSystem.particleCount;
|
||||
}
|
||||
|
||||
public void ReloadScene()
|
||||
{
|
||||
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
|
||||
}
|
||||
|
||||
// Particle system settings.
|
||||
|
||||
public void SetMaxParticles(float value)
|
||||
{
|
||||
particleSystemMainModule.maxParticles = (int)value;
|
||||
maxParticlesText.text = "Max Particles: " + value;
|
||||
}
|
||||
public void SetParticleEmissionPerSecond(float value)
|
||||
{
|
||||
particleSystemEmissionModule.rateOverTime = value;
|
||||
particlesPerSecondText.text = "Particles Per Second: " + value;
|
||||
}
|
||||
|
||||
// Attraction particle force field settings.
|
||||
|
||||
public void SetAttractionParticleForceFieldRadius(float value)
|
||||
{
|
||||
attractionParticleForceField.radius = value;
|
||||
attractionParticleForceFieldRadiusText.text = "Radius: " + value;
|
||||
}
|
||||
public void SetAttractionParticleForceFieldMaxForce(float value)
|
||||
{
|
||||
attractionParticleForceField.force = value;
|
||||
attractionParticleForceFieldMaxForceText.text = "Max Force: " + value;
|
||||
}
|
||||
public void SetAttractionParticleForceFieldArrivalRadius(float value)
|
||||
{
|
||||
attractionParticleForceField.arrivalRadius = value;
|
||||
attractionParticleForceFieldArrivalRadiusText.text = "Arrival Radius: " + value;
|
||||
}
|
||||
public void SetAttractionParticleForceFieldArrivedRadius(float value)
|
||||
{
|
||||
attractionParticleForceField.arrivedRadius = value;
|
||||
attractionParticleForceFieldArrivedRadiusText.text = "Arrived Radius: " + value;
|
||||
}
|
||||
|
||||
public void SetAttractionParticleForceFieldPositionX(float value)
|
||||
{
|
||||
Vector3 position = attractionParticleForceField.transform.position;
|
||||
|
||||
position.x = value;
|
||||
|
||||
attractionParticleForceField.transform.position = position;
|
||||
attractionParticleForceFieldPositionTextX.text = "Position X: " + value;
|
||||
}
|
||||
public void SetAttractionParticleForceFieldPositionY(float value)
|
||||
{
|
||||
Vector3 position = attractionParticleForceField.transform.position;
|
||||
|
||||
position.y = value;
|
||||
|
||||
attractionParticleForceField.transform.position = position;
|
||||
attractionParticleForceFieldPositionTextY.text = "Position Y: " + value;
|
||||
}
|
||||
public void SetAttractionParticleForceFieldPositionZ(float value)
|
||||
{
|
||||
Vector3 position = attractionParticleForceField.transform.position;
|
||||
|
||||
position.z = value;
|
||||
|
||||
attractionParticleForceField.transform.position = position;
|
||||
attractionParticleForceFieldPositionTextZ.text = "Position Z: " + value;
|
||||
}
|
||||
|
||||
// Vortex particle force field settings.
|
||||
|
||||
public void SetVortexParticleForceFieldRadius(float value)
|
||||
{
|
||||
vortexParticleForceField.radius = value;
|
||||
vortexParticleForceFieldRadiusText.text = "Radius: " + value;
|
||||
}
|
||||
public void SetVortexParticleForceFieldMaxForce(float value)
|
||||
{
|
||||
vortexParticleForceField.force = value;
|
||||
vortexParticleForceFieldMaxForceText.text = "Max Force: " + value;
|
||||
}
|
||||
|
||||
public void SetVortexParticleForceFieldRotationX(float value)
|
||||
{
|
||||
Vector3 rotation = vortexParticleForceField.transform.eulerAngles;
|
||||
|
||||
rotation.x = value;
|
||||
|
||||
vortexParticleForceField.transform.eulerAngles = rotation;
|
||||
vortexParticleForceFieldRotationTextX.text = "Rotation X: " + value;
|
||||
}
|
||||
public void SetVortexParticleForceFieldRotationY(float value)
|
||||
{
|
||||
Vector3 rotation = vortexParticleForceField.transform.eulerAngles;
|
||||
|
||||
rotation.y = value;
|
||||
|
||||
vortexParticleForceField.transform.eulerAngles = rotation;
|
||||
vortexParticleForceFieldRotationTextY.text = "Rotation Y: " + value;
|
||||
}
|
||||
public void SetVortexParticleForceFieldRotationZ(float value)
|
||||
{
|
||||
Vector3 rotation = vortexParticleForceField.transform.eulerAngles;
|
||||
|
||||
rotation.z = value;
|
||||
|
||||
vortexParticleForceField.transform.eulerAngles = rotation;
|
||||
vortexParticleForceFieldRotationTextZ.text = "Rotation Z: " + value;
|
||||
}
|
||||
|
||||
public void SetVortexParticleForceFieldPositionX(float value)
|
||||
{
|
||||
Vector3 position = vortexParticleForceField.transform.position;
|
||||
|
||||
position.x = value;
|
||||
|
||||
vortexParticleForceField.transform.position = position;
|
||||
vortexParticleForceFieldPositionTextX.text = "Position X: " + value;
|
||||
}
|
||||
public void SetVortexParticleForceFieldPositionY(float value)
|
||||
{
|
||||
Vector3 position = vortexParticleForceField.transform.position;
|
||||
|
||||
position.y = value;
|
||||
|
||||
vortexParticleForceField.transform.position = position;
|
||||
vortexParticleForceFieldPositionTextY.text = "Position Y: " + value;
|
||||
}
|
||||
public void SetVortexParticleForceFieldPositionZ(float value)
|
||||
{
|
||||
Vector3 position = vortexParticleForceField.transform.position;
|
||||
|
||||
position.z = value;
|
||||
|
||||
vortexParticleForceField.transform.position = position;
|
||||
vortexParticleForceFieldPositionTextZ.text = "Position Z: " + value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 250820ec8673f9549acc97449bee156c
|
||||
timeCreated: 1508398214
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,50 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class ParticleForceFieldsDemo_CameraRig : MonoBehaviour
|
||||
{
|
||||
public Transform pivot;
|
||||
Vector3 targetRotation;
|
||||
|
||||
[Range(0.0f, 90.0f)]
|
||||
public float rotationLimit = 90.0f;
|
||||
|
||||
public float rotationSpeed = 2.0f;
|
||||
public float rotationLerpSpeed = 4.0f;
|
||||
|
||||
Vector3 startRotation;
|
||||
|
||||
void Start()
|
||||
{
|
||||
startRotation = pivot.localEulerAngles;
|
||||
targetRotation = startRotation;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
float horizontal = Input.GetAxis("Horizontal");
|
||||
float vertical = Input.GetAxis("Vertical");
|
||||
|
||||
if (Input.GetKeyDown(KeyCode.R))
|
||||
{
|
||||
targetRotation = startRotation;
|
||||
}
|
||||
|
||||
horizontal *= rotationSpeed;
|
||||
vertical *= rotationSpeed;
|
||||
|
||||
targetRotation.y += horizontal;
|
||||
targetRotation.x += vertical;
|
||||
|
||||
targetRotation.x = Mathf.Clamp(targetRotation.x, -rotationLimit, rotationLimit);
|
||||
targetRotation.y = Mathf.Clamp(targetRotation.y, -rotationLimit, rotationLimit);
|
||||
|
||||
Vector3 currentRotation = pivot.localEulerAngles;
|
||||
|
||||
currentRotation.x = Mathf.LerpAngle(currentRotation.x, targetRotation.x, Time.deltaTime * rotationLerpSpeed);
|
||||
currentRotation.y = Mathf.LerpAngle(currentRotation.y, targetRotation.y, Time.deltaTime * rotationLerpSpeed);
|
||||
|
||||
pivot.localEulerAngles = currentRotation;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f5219d102a973a645a4b97512415c865
|
||||
timeCreated: 1508405059
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c6b070ddda83ff346a0c6789971e618a
|
||||
folderAsset: yes
|
||||
timeCreated: 1485465640
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,161 @@
|
||||
|
||||
// =================================
|
||||
// Namespaces.
|
||||
// =================================
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
// =================================
|
||||
// Define namespace.
|
||||
// =================================
|
||||
|
||||
namespace MirzaBeig
|
||||
{
|
||||
|
||||
namespace Scripting
|
||||
{
|
||||
|
||||
namespace Effects
|
||||
{
|
||||
|
||||
// =================================
|
||||
// Classes.
|
||||
// =================================
|
||||
|
||||
[AddComponentMenu("Effects/Particle Force Fields/Attraction Particle Force Field")]
|
||||
|
||||
public class AttractionParticleForceField : ParticleForceField
|
||||
{
|
||||
// =================================
|
||||
// Nested classes and structures.
|
||||
// =================================
|
||||
|
||||
// ...
|
||||
|
||||
// =================================
|
||||
// Variables.
|
||||
// =================================
|
||||
|
||||
// ...
|
||||
|
||||
[Header("ForceField Controls")]
|
||||
|
||||
[Tooltip("Tether force based on linear inverse particle distance to force field center.")]
|
||||
public float arrivalRadius = 1.0f;
|
||||
[Tooltip("Dead zone from force field center in which no additional force is applied.")]
|
||||
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.distanceToForceFieldCenterSqr < arrivedRadiusSqr)
|
||||
{
|
||||
force.x = 0.0f;
|
||||
force.y = 0.0f;
|
||||
force.z = 0.0f;
|
||||
}
|
||||
else if (parameters.distanceToForceFieldCenterSqr < arrivalRadiusSqr)
|
||||
{
|
||||
float inverseArrivalScaleNormalized = 1.0f - (parameters.distanceToForceFieldCenterSqr / arrivalRadiusSqr);
|
||||
force = Vector3.Normalize(parameters.scaledDirectionToForceFieldCenter) * inverseArrivalScaleNormalized;
|
||||
}
|
||||
else
|
||||
{
|
||||
force = Vector3.Normalize(parameters.scaledDirectionToForceFieldCenter);
|
||||
}
|
||||
|
||||
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 offsetCenter = transform.position + center;
|
||||
|
||||
Gizmos.color = Color.yellow;
|
||||
Gizmos.DrawWireSphere(offsetCenter, arrivalRadius);
|
||||
|
||||
Gizmos.color = Color.red;
|
||||
Gizmos.DrawWireSphere(offsetCenter, arrivedRadius);
|
||||
|
||||
//Gizmos.color = Color.white;
|
||||
//Gizmos.DrawLine(currentParticleSystem.transform.position, offsetCenter);
|
||||
}
|
||||
}
|
||||
|
||||
// =================================
|
||||
// End functions.
|
||||
// =================================
|
||||
|
||||
}
|
||||
|
||||
// =================================
|
||||
// End namespace.
|
||||
// =================================
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// =================================
|
||||
// --END-- //
|
||||
// =================================
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e1fdf750d337aed4f8a30771049b5559
|
||||
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
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b44853b525f9caf40bab3434705bc51e
|
||||
timeCreated: 1458196122
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,570 @@
|
||||
|
||||
// =================================
|
||||
// Namespaces.
|
||||
// =================================
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
// =================================
|
||||
// Define namespace.
|
||||
// =================================
|
||||
|
||||
namespace MirzaBeig
|
||||
{
|
||||
|
||||
namespace Scripting
|
||||
{
|
||||
|
||||
namespace Effects
|
||||
{
|
||||
|
||||
// =================================
|
||||
// Classes.
|
||||
// =================================
|
||||
|
||||
public abstract class ParticleForceField : MonoBehaviour
|
||||
{
|
||||
// =================================
|
||||
// Nested classes and structures.
|
||||
// =================================
|
||||
|
||||
// ...
|
||||
|
||||
protected struct GetForceParameters
|
||||
{
|
||||
public float distanceToForceFieldCenterSqr;
|
||||
|
||||
public Vector3 scaledDirectionToForceFieldCenter;
|
||||
public Vector3 particlePosition;
|
||||
}
|
||||
|
||||
// =================================
|
||||
// Variables.
|
||||
// =================================
|
||||
|
||||
// ...
|
||||
|
||||
[Header("Common Controls")]
|
||||
|
||||
[Tooltip("Force field spherical range.")]
|
||||
public float radius = Mathf.Infinity;
|
||||
|
||||
[Tooltip("Maximum baseline force.")]
|
||||
public float force = 5.0f;
|
||||
|
||||
[Tooltip("Internal force field position offset.")]
|
||||
public Vector3 center = Vector3.zero;
|
||||
|
||||
public float scaledRadius
|
||||
{
|
||||
get
|
||||
{
|
||||
return radius * transform.lossyScale.x;
|
||||
}
|
||||
}
|
||||
|
||||
float _radius;
|
||||
float radiusSqr;
|
||||
|
||||
Vector3 transformPosition;
|
||||
|
||||
float[] particleSystemExternalForcesMultipliers;
|
||||
|
||||
[Tooltip("Force scale as determined by distance to individual particles.")]
|
||||
public AnimationCurve forceOverDistance = 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;
|
||||
|
||||
[Tooltip(
|
||||
"If nothing no particle systems are assigned, this force field will operate globally on ALL particle systems in the scene (NOT recommended).\n\n" +
|
||||
"If attached to a particle system, the force field will operate only on that system.\n\n" +
|
||||
"If specific particle systems are assigned, then the force field will operate on those systems only, even if attached to a particle system.")]
|
||||
|
||||
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.
|
||||
|
||||
[Tooltip(
|
||||
"If TRUE, update even if target particle system(s) are invisible/offscreen.\n\n" +
|
||||
"If FALSE, update only if particles of the target system(s) are visible/onscreen.")]
|
||||
|
||||
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;
|
||||
|
||||
transformPosition = transform.position + center;
|
||||
|
||||
// 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;
|
||||
|
||||
// Force delta time should reflect particle system delta time mode.
|
||||
|
||||
float forceDeltaTime = force * (particleSystemMainModules[i].useUnscaledTime ? Time.unscaledDeltaTime : Time.deltaTime);
|
||||
|
||||
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.scaledDirectionToForceFieldCenter.x = transformPosition.x - parameters.particlePosition.x;
|
||||
parameters.scaledDirectionToForceFieldCenter.y = transformPosition.y - parameters.particlePosition.y;
|
||||
parameters.scaledDirectionToForceFieldCenter.z = transformPosition.z - parameters.particlePosition.z;
|
||||
|
||||
parameters.distanceToForceFieldCenterSqr = parameters.scaledDirectionToForceFieldCenter.sqrMagnitude;
|
||||
|
||||
if (parameters.distanceToForceFieldCenterSqr < radiusSqr)
|
||||
{
|
||||
float distanceToCenterNormalized = parameters.distanceToForceFieldCenterSqr / radiusSqr;
|
||||
float distanceScale = forceOverDistance.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.scaledDirectionToForceFieldCenter.x = transformPosition.x - parameters.particlePosition.x;
|
||||
parameters.scaledDirectionToForceFieldCenter.y = transformPosition.y - parameters.particlePosition.y;
|
||||
parameters.scaledDirectionToForceFieldCenter.z = transformPosition.z - parameters.particlePosition.z;
|
||||
|
||||
parameters.distanceToForceFieldCenterSqr = parameters.scaledDirectionToForceFieldCenter.sqrMagnitude;
|
||||
|
||||
//particleSystemParticles[i][j].velocity += forceDeltaTime * Vector3.Normalize(parameters.scaledDirectionToForceFieldCenter);
|
||||
|
||||
if (parameters.distanceToForceFieldCenterSqr < radiusSqr)
|
||||
{
|
||||
// 0.0f -> 0.99...f;
|
||||
|
||||
float distanceToCenterNormalized = parameters.distanceToForceFieldCenterSqr / 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 = forceOverDistance.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 + center, scaledRadius);
|
||||
}
|
||||
|
||||
// =================================
|
||||
// End functions.
|
||||
// =================================
|
||||
|
||||
}
|
||||
|
||||
// =================================
|
||||
// End namespace.
|
||||
// =================================
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// =================================
|
||||
// --END-- //
|
||||
// =================================
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 438d3a992ed592445b2ca9cf747b6ffc
|
||||
timeCreated: 1470567813
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,275 @@
|
||||
|
||||
// =================================
|
||||
// Namespaces.
|
||||
// =================================
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
// =================================
|
||||
// Define namespace.
|
||||
// =================================
|
||||
|
||||
namespace MirzaBeig
|
||||
{
|
||||
|
||||
namespace Scripting
|
||||
{
|
||||
|
||||
namespace Effects
|
||||
{
|
||||
|
||||
// =================================
|
||||
// Classes.
|
||||
// =================================
|
||||
|
||||
[AddComponentMenu("Effects/Particle Force Fields/Turbulence Particle Force Field")]
|
||||
|
||||
public class TurbulenceParticleForceField : ParticleForceField
|
||||
{
|
||||
// =================================
|
||||
// Nested classes and structures.
|
||||
// =================================
|
||||
|
||||
// ...
|
||||
|
||||
public enum NoiseType
|
||||
{
|
||||
PseudoPerlin,
|
||||
|
||||
Perlin,
|
||||
|
||||
Simplex,
|
||||
|
||||
OctavePerlin,
|
||||
OctaveSimplex
|
||||
}
|
||||
|
||||
// =================================
|
||||
// Variables.
|
||||
// =================================
|
||||
|
||||
// ...
|
||||
|
||||
[Header("ForceField Controls")]
|
||||
|
||||
[Tooltip("Noise texture mutation speed.")]
|
||||
|
||||
public float scrollSpeed = 1.0f;
|
||||
|
||||
[Range(0.0f, 8.0f)]
|
||||
[Tooltip("Noise texture detail amplifier.")]
|
||||
|
||||
public float frequency = 1.0f;
|
||||
|
||||
public NoiseType noiseType = NoiseType.Perlin;
|
||||
|
||||
// ...
|
||||
|
||||
[Header("Octave Variant-Only Controls")]
|
||||
|
||||
[Range(1, 8)]
|
||||
[Tooltip("Overlapping noise iterations. 1 = no additional iterations.")]
|
||||
|
||||
public int octaves = 1;
|
||||
|
||||
[Range(0.0f, 4.0f)]
|
||||
[Tooltip("Frequency scale per-octave. Can be used to change the overlap every iteration.")]
|
||||
|
||||
public float octaveMultiplier = 0.5f;
|
||||
|
||||
[Range(0.0f, 1.0f)]
|
||||
[Tooltip("Amplitude scale per-octave. Can be used to change the overlap every iteration.")]
|
||||
|
||||
public float octaveScale = 2.0f;
|
||||
|
||||
float time;
|
||||
|
||||
// Noise2 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 * scrollSpeed) + randomX;
|
||||
offsetY = (time * scrollSpeed) + randomY;
|
||||
offsetZ = (time * scrollSpeed) + 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 = Noise2.perlin(xX * frequency, yX * frequency, zX * frequency);
|
||||
force.y = Noise2.perlin(xY * frequency, yY * frequency, zY * frequency);
|
||||
force.z = Noise2.perlin(xZ * frequency, yZ * frequency, zZ * frequency);
|
||||
|
||||
return force;
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
case NoiseType.Simplex:
|
||||
{
|
||||
force.x = Noise2.simplex(xX * frequency, yX * frequency, zX * frequency);
|
||||
force.y = Noise2.simplex(xY * frequency, yY * frequency, zY * frequency);
|
||||
force.z = Noise2.simplex(xZ * frequency, yZ * frequency, zZ * frequency);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
case NoiseType.OctavePerlin:
|
||||
{
|
||||
force.x = Noise2.octavePerlin(xX, yX, zX, frequency, octaves, octaveMultiplier, octaveScale);
|
||||
force.y = Noise2.octavePerlin(xY, yY, zY, frequency, octaves, octaveMultiplier, octaveScale);
|
||||
force.z = Noise2.octavePerlin(xZ, yZ, zZ, frequency, octaves, octaveMultiplier, octaveScale);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case NoiseType.OctaveSimplex:
|
||||
{
|
||||
force.x = Noise2.octaveSimplex(xX, yX, zX, frequency, octaves, octaveMultiplier, octaveScale);
|
||||
force.y = Noise2.octaveSimplex(xY, yY, zY, frequency, octaves, octaveMultiplier, octaveScale);
|
||||
force.z = Noise2.octaveSimplex(xZ, yZ, zZ, frequency, octaves, octaveMultiplier, octaveScale);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return force;
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
protected override void OnDrawGizmosSelected()
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
base.OnDrawGizmosSelected();
|
||||
}
|
||||
}
|
||||
|
||||
// =================================
|
||||
// End functions.
|
||||
// =================================
|
||||
|
||||
}
|
||||
|
||||
// =================================
|
||||
// End namespace.
|
||||
// =================================
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// =================================
|
||||
// --END-- //
|
||||
// =================================
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7e733210563cdf8419c597d30703d906
|
||||
timeCreated: 1470567813
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,166 @@
|
||||
|
||||
// =================================
|
||||
// Namespaces.
|
||||
// =================================
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
// =================================
|
||||
// Define namespace.
|
||||
// =================================
|
||||
|
||||
namespace MirzaBeig
|
||||
{
|
||||
|
||||
namespace Scripting
|
||||
{
|
||||
|
||||
namespace Effects
|
||||
{
|
||||
|
||||
// =================================
|
||||
// Classes.
|
||||
// =================================
|
||||
|
||||
[AddComponentMenu("Effects/Particle Force Fields/Vortex Particle Force Field")]
|
||||
|
||||
public class VortexParticleForceField : ParticleForceField
|
||||
{
|
||||
// =================================
|
||||
// Nested classes and structures.
|
||||
// =================================
|
||||
|
||||
// ...
|
||||
|
||||
// =================================
|
||||
// Variables.
|
||||
// =================================
|
||||
|
||||
// ...
|
||||
|
||||
Vector3 axisOfRotation;
|
||||
|
||||
[Header("ForceField Controls")]
|
||||
|
||||
[Tooltip(
|
||||
"Internal offset for the axis of rotation.\n\n" +
|
||||
"Useful if the force field 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.scaledDirectionToForceFieldCenter));
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Vector3 offsetCenter = transform.position + center;
|
||||
Gizmos.DrawLine(offsetCenter, offsetCenter + (axisOfRotation * scaledRadius));
|
||||
}
|
||||
}
|
||||
|
||||
// =================================
|
||||
// End functions.
|
||||
// =================================
|
||||
|
||||
}
|
||||
|
||||
// =================================
|
||||
// End namespace.
|
||||
// =================================
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// =================================
|
||||
// --END-- //
|
||||
// =================================
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 37b87b5be4beb0d4dab3058662d07b44
|
||||
timeCreated: 1470567812
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5332e56ae936db64f96e78f1fd42fb10
|
||||
folderAsset: yes
|
||||
timeCreated: 1471472531
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e052bf39285577445af92b6e5cf93a94
|
||||
folderAsset: yes
|
||||
timeCreated: 1485465673
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,166 @@
|
||||
|
||||
// =================================
|
||||
// Namespaces.
|
||||
// =================================
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
// =================================
|
||||
// Define namespace.
|
||||
// =================================
|
||||
|
||||
namespace MirzaBeig
|
||||
{
|
||||
|
||||
namespace Scripting
|
||||
{
|
||||
|
||||
namespace Effects
|
||||
{
|
||||
|
||||
// =================================
|
||||
// Classes.
|
||||
// =================================
|
||||
|
||||
//[ExecuteInEditMode]
|
||||
[System.Serializable]
|
||||
|
||||
[RequireComponent(typeof(ParticleSystem))]
|
||||
|
||||
public class ParticleLights : MonoBehaviour
|
||||
{
|
||||
// =================================
|
||||
// Nested classes and structures.
|
||||
// =================================
|
||||
|
||||
// ...
|
||||
|
||||
// =================================
|
||||
// Variables.
|
||||
// =================================
|
||||
|
||||
// ...
|
||||
|
||||
ParticleSystem ps;
|
||||
List<Light> lights = new List<Light>();
|
||||
|
||||
//public LightType type = LightType.Point;
|
||||
|
||||
public float scale = 2.0f;
|
||||
|
||||
[Range(0.0f, 8.0f)]
|
||||
public float intensity = 8.0f;
|
||||
|
||||
public Color colour = Color.white;
|
||||
|
||||
[Range(0.0f, 1.0f)]
|
||||
public float colourFromParticle = 1.0f;
|
||||
|
||||
public LightShadows shadows = LightShadows.None;
|
||||
|
||||
GameObject template;
|
||||
|
||||
// =================================
|
||||
// Functions.
|
||||
// =================================
|
||||
|
||||
// ...
|
||||
|
||||
void Awake()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
void Start()
|
||||
{
|
||||
ps = GetComponent<ParticleSystem>();
|
||||
|
||||
template = new GameObject();
|
||||
template.transform.SetParent(transform);
|
||||
|
||||
template.name = "Template";
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
void LateUpdate()
|
||||
{
|
||||
ParticleSystem.Particle[] particles =
|
||||
new ParticleSystem.Particle[ps.particleCount];
|
||||
|
||||
int numOfParticles = ps.GetParticles(particles);
|
||||
|
||||
if (lights.Count != numOfParticles)
|
||||
{
|
||||
for (int i = 0; i < lights.Count; i++)
|
||||
{
|
||||
Destroy(lights[i].gameObject);
|
||||
}
|
||||
|
||||
lights.Clear();
|
||||
|
||||
for (int i = 0; i < numOfParticles; i++)
|
||||
{
|
||||
GameObject go = Instantiate(template, transform) as GameObject;
|
||||
go.name = "- " + (i + 1).ToString();
|
||||
|
||||
lights.Add(go.AddComponent<Light>());
|
||||
}
|
||||
}
|
||||
|
||||
ParticleSystem.MainModule m = ps.main;
|
||||
bool worldSpace = m.simulationSpace == ParticleSystemSimulationSpace.World;
|
||||
|
||||
for (int i = 0; i < numOfParticles; i++)
|
||||
{
|
||||
ParticleSystem.Particle p = particles[i];
|
||||
|
||||
Light light = lights[i];
|
||||
|
||||
//light.type = type;
|
||||
|
||||
//if (type == LightType.Spot)
|
||||
//{
|
||||
// light.transform.rotation = Quaternion.Euler(p.rotation3D);
|
||||
//}
|
||||
|
||||
light.range = p.GetCurrentSize(ps) * scale;
|
||||
light.color = Color.Lerp(colour, p.GetCurrentColor(ps), colourFromParticle);
|
||||
|
||||
light.intensity = intensity;
|
||||
|
||||
light.shadows = shadows;
|
||||
|
||||
light.transform.position = worldSpace ? p.position : ps.transform.TransformPoint(p.position);
|
||||
}
|
||||
}
|
||||
|
||||
// =================================
|
||||
// End functions.
|
||||
// =================================
|
||||
|
||||
}
|
||||
|
||||
// =================================
|
||||
// End namespace.
|
||||
// =================================
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// =================================
|
||||
// --END-- //
|
||||
// =================================
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f32496b72584aa54788fca63c858de5e
|
||||
timeCreated: 1470567813
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 14034914d0c5055478728ee6ebaccd5d
|
||||
folderAsset: yes
|
||||
timeCreated: 1485465588
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5cc3d79fe4d65e94f9901f89ed53e8d2
|
||||
folderAsset: yes
|
||||
timeCreated: 1508486697
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,78 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_Name: Default Particle (Additive)
|
||||
m_Shader: {fileID: 200, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_ShaderKeywords:
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 10300, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- _BumpScale: 1
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _InvFade: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _UVSec: 0
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _TintColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 35e2e3a06b6570a4cac191d4ca904974
|
||||
timeCreated: 1508486714
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,78 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_Name: Plexus Triangles
|
||||
m_Shader: {fileID: 200, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_ShaderKeywords: _ALPHABLEND_ON _EMISSION
|
||||
m_LightmapFlags: 1
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- _BumpScale: 1
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 10
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _InvFade: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 2
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 5
|
||||
- _UVSec: 0
|
||||
- _ZWrite: 0
|
||||
m_Colors:
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 0.2784314}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _TintColor: {r: 1, g: 1, b: 1, a: 0.4}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d918114c252ee445b2d579c481b0f91
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,78 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_Name: Solid White Circle (Additive)
|
||||
m_Shader: {fileID: 200, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_ShaderKeywords:
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 2800000, guid: 1a0cb63a3bc8d2342852089bfb884192, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- _BumpScale: 1
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _InvFade: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _UVSec: 0
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _TintColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f5721af2cf8d7e4b810f19ac7c6f606
|
||||
timeCreated: 1508486714
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,78 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_Name: Solid White Square (Alpha Blended)
|
||||
m_Shader: {fileID: 200, guid: 0000000000000000f000000000000000, type: 0}
|
||||
m_ShaderKeywords:
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 2800000, guid: fcc934170231d0244809002a4923c98b, type: 3}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- _BumpScale: 1
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _InvFade: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _UVSec: 0
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _TintColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01cfa300c642b654b93f44f9c3a0006f
|
||||
timeCreated: 1508486714
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f17469a07497ddd47a2328c68fde2d77
|
||||
folderAsset: yes
|
||||
timeCreated: 1508401765
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,320 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 8a3bdb2cd68f901469e7cc149151eb49, type: 3}
|
||||
m_Name: Particle Plexus Post-Processing Profile
|
||||
m_EditorClassIdentifier:
|
||||
debugViews:
|
||||
m_Enabled: 1
|
||||
m_Settings:
|
||||
mode: 0
|
||||
depth:
|
||||
scale: 1
|
||||
motionVectors:
|
||||
sourceOpacity: 1
|
||||
motionImageOpacity: 0
|
||||
motionImageAmplitude: 16
|
||||
motionVectorsOpacity: 1
|
||||
motionVectorsResolution: 24
|
||||
motionVectorsAmplitude: 64
|
||||
fog:
|
||||
m_Enabled: 0
|
||||
m_Settings:
|
||||
excludeSkybox: 1
|
||||
antialiasing:
|
||||
m_Enabled: 0
|
||||
m_Settings:
|
||||
method: 0
|
||||
fxaaSettings:
|
||||
preset: 2
|
||||
taaSettings:
|
||||
jitterSpread: 0.75
|
||||
sharpen: 0.3
|
||||
stationaryBlending: 0.95
|
||||
motionBlending: 0.85
|
||||
ambientOcclusion:
|
||||
m_Enabled: 0
|
||||
m_Settings:
|
||||
intensity: 1
|
||||
radius: 0.3
|
||||
sampleCount: 10
|
||||
downsampling: 1
|
||||
forceForwardCompatibility: 0
|
||||
ambientOnly: 0
|
||||
highPrecision: 0
|
||||
screenSpaceReflection:
|
||||
m_Enabled: 0
|
||||
m_Settings:
|
||||
reflection:
|
||||
blendType: 0
|
||||
reflectionQuality: 2
|
||||
maxDistance: 100
|
||||
iterationCount: 256
|
||||
stepSize: 3
|
||||
widthModifier: 0.5
|
||||
reflectionBlur: 1
|
||||
reflectBackfaces: 0
|
||||
intensity:
|
||||
reflectionMultiplier: 1
|
||||
fadeDistance: 100
|
||||
fresnelFade: 1
|
||||
fresnelFadePower: 1
|
||||
screenEdgeMask:
|
||||
intensity: 0.03
|
||||
depthOfField:
|
||||
m_Enabled: 0
|
||||
m_Settings:
|
||||
focusDistance: 5
|
||||
aperture: 5.6
|
||||
focalLength: 50
|
||||
useCameraFov: 0
|
||||
kernelSize: 1
|
||||
motionBlur:
|
||||
m_Enabled: 0
|
||||
m_Settings:
|
||||
shutterAngle: 270
|
||||
sampleCount: 10
|
||||
frameBlending: 0
|
||||
eyeAdaptation:
|
||||
m_Enabled: 0
|
||||
m_Settings:
|
||||
lowPercent: 45
|
||||
highPercent: 95
|
||||
minLuminance: -5
|
||||
maxLuminance: 1
|
||||
keyValue: 0.25
|
||||
dynamicKeyValue: 1
|
||||
adaptationType: 0
|
||||
speedUp: 2
|
||||
speedDown: 1
|
||||
logMin: -8
|
||||
logMax: 4
|
||||
bloom:
|
||||
m_Enabled: 1
|
||||
m_Settings:
|
||||
bloom:
|
||||
intensity: 1.5
|
||||
threshold: 0.8
|
||||
softKnee: 0
|
||||
radius: 7
|
||||
antiFlicker: 0
|
||||
lensDirt:
|
||||
texture: {fileID: 0}
|
||||
intensity: 3
|
||||
colorGrading:
|
||||
m_Enabled: 1
|
||||
m_Settings:
|
||||
tonemapping:
|
||||
tonemapper: 1
|
||||
neutralBlackIn: 0.02
|
||||
neutralWhiteIn: 10
|
||||
neutralBlackOut: 0
|
||||
neutralWhiteOut: 10
|
||||
neutralWhiteLevel: 5.3
|
||||
neutralWhiteClip: 10
|
||||
basic:
|
||||
postExposure: 1
|
||||
temperature: 0
|
||||
tint: 0
|
||||
hueShift: 0
|
||||
saturation: 0.9
|
||||
contrast: 1.15
|
||||
channelMixer:
|
||||
red: {x: 1, y: 0, z: 0}
|
||||
green: {x: 0, y: 1, z: 0}
|
||||
blue: {x: 0, y: 0, z: 1}
|
||||
currentEditingChannel: 0
|
||||
colorWheels:
|
||||
mode: 1
|
||||
log:
|
||||
slope: {r: 1, g: 1, b: 1, a: 0}
|
||||
power: {r: 1, g: 1, b: 1, a: 0}
|
||||
offset: {r: 1, g: 1, b: 1, a: 0}
|
||||
linear:
|
||||
lift: {r: 0, g: 0, b: 0, a: 0}
|
||||
gamma: {r: 0, g: 0, b: 0, a: 0}
|
||||
gain: {r: 0, g: 0, b: 0, a: 0}
|
||||
curves:
|
||||
master:
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 2
|
||||
time: 0
|
||||
value: 0
|
||||
inSlope: 1
|
||||
outSlope: 1
|
||||
tangentMode: 0
|
||||
- serializedVersion: 2
|
||||
time: 1
|
||||
value: 1
|
||||
inSlope: 1
|
||||
outSlope: 1
|
||||
tangentMode: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 0
|
||||
m_Loop: 0
|
||||
m_ZeroValue: 0
|
||||
m_Range: 1
|
||||
red:
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 2
|
||||
time: 0
|
||||
value: 0
|
||||
inSlope: 1
|
||||
outSlope: 1
|
||||
tangentMode: 0
|
||||
- serializedVersion: 2
|
||||
time: 1
|
||||
value: 1
|
||||
inSlope: 1
|
||||
outSlope: 1
|
||||
tangentMode: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
m_Loop: 0
|
||||
m_ZeroValue: 0
|
||||
m_Range: 1
|
||||
green:
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 2
|
||||
time: 0
|
||||
value: 0
|
||||
inSlope: 1
|
||||
outSlope: 1
|
||||
tangentMode: 0
|
||||
- serializedVersion: 2
|
||||
time: 1
|
||||
value: 1
|
||||
inSlope: 1
|
||||
outSlope: 1
|
||||
tangentMode: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
m_Loop: 0
|
||||
m_ZeroValue: 0
|
||||
m_Range: 1
|
||||
blue:
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 2
|
||||
time: 0
|
||||
value: 0
|
||||
inSlope: 1
|
||||
outSlope: 1
|
||||
tangentMode: 0
|
||||
- serializedVersion: 2
|
||||
time: 1
|
||||
value: 1
|
||||
inSlope: 1
|
||||
outSlope: 1
|
||||
tangentMode: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
m_Loop: 0
|
||||
m_ZeroValue: 0
|
||||
m_Range: 1
|
||||
hueVShue:
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve: []
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
m_Loop: 1
|
||||
m_ZeroValue: 0.5
|
||||
m_Range: 1
|
||||
hueVSsat:
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve: []
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
m_Loop: 1
|
||||
m_ZeroValue: 0.5
|
||||
m_Range: 1
|
||||
satVSsat:
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve: []
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
m_Loop: 0
|
||||
m_ZeroValue: 0.5
|
||||
m_Range: 1
|
||||
lumVSsat:
|
||||
curve:
|
||||
serializedVersion: 2
|
||||
m_Curve: []
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
m_Loop: 0
|
||||
m_ZeroValue: 0.5
|
||||
m_Range: 1
|
||||
e_CurrentEditingCurve: 0
|
||||
e_CurveY: 1
|
||||
e_CurveR: 0
|
||||
e_CurveG: 0
|
||||
e_CurveB: 0
|
||||
userLut:
|
||||
m_Enabled: 0
|
||||
m_Settings:
|
||||
lut: {fileID: 0}
|
||||
contribution: 1
|
||||
chromaticAberration:
|
||||
m_Enabled: 1
|
||||
m_Settings:
|
||||
spectralTexture: {fileID: 0}
|
||||
intensity: 1
|
||||
grain:
|
||||
m_Enabled: 1
|
||||
m_Settings:
|
||||
colored: 1
|
||||
intensity: 0.25
|
||||
size: 0.5
|
||||
luminanceContribution: 0.8
|
||||
vignette:
|
||||
m_Enabled: 1
|
||||
m_Settings:
|
||||
mode: 0
|
||||
color: {r: 0, g: 0, b: 0, a: 1}
|
||||
center: {x: 0.5, y: 0.5}
|
||||
intensity: 0.45
|
||||
smoothness: 0.2
|
||||
roundness: 1
|
||||
mask: {fileID: 0}
|
||||
opacity: 1
|
||||
rounded: 0
|
||||
dithering:
|
||||
m_Enabled: 0
|
||||
monitors:
|
||||
currentMonitorID: 0
|
||||
refreshOnPlay: 0
|
||||
histogramMode: 3
|
||||
waveformExposure: 0.12
|
||||
waveformY: 0
|
||||
waveformR: 1
|
||||
waveformG: 1
|
||||
waveformB: 1
|
||||
paradeExposure: 0.12
|
||||
vectorscopeExposure: 0.12
|
||||
vectorscopeShowBackground: 1
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8db3f21d0d527d74daec47111a2c2731
|
||||
timeCreated: 1508401783
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 69a3065ca67adce4c969963284e8f467
|
||||
folderAsset: yes
|
||||
timeCreated: 1508486547
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,134 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1001 &100100000
|
||||
Prefab:
|
||||
m_ObjectHideFlags: 1
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications: []
|
||||
m_RemovedComponents: []
|
||||
m_ParentPrefab: {fileID: 0}
|
||||
m_RootGameObject: {fileID: 1386574972781608}
|
||||
m_IsPrefabParent: 1
|
||||
--- !u!1 &1386574972781608
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 4165100386123906}
|
||||
- component: {fileID: 120042951271217888}
|
||||
m_Layer: 0
|
||||
m_Name: Particle Plexus Line Renderer Template 2
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &4165100386123906
|
||||
Transform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1386574972781608}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!120 &120042951271217888
|
||||
LineRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1386574972781608}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 1
|
||||
m_ReceiveShadows: 1
|
||||
m_DynamicOccludee: 1
|
||||
m_MotionVectors: 0
|
||||
m_LightProbeUsage: 0
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RenderingLayerMask: 4294967295
|
||||
m_Materials:
|
||||
- {fileID: 2100000, guid: 01cfa300c642b654b93f44f9c3a0006f, type: 2}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_PreserveUVs: 0
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 0
|
||||
m_SelectedEditorRenderState: 3
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_Positions:
|
||||
- {x: 0, y: 0, z: 0}
|
||||
- {x: 0, y: 0, z: 1}
|
||||
m_Parameters:
|
||||
serializedVersion: 2
|
||||
widthMultiplier: 0.1
|
||||
widthCurve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 3
|
||||
time: 0
|
||||
value: 1
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 0
|
||||
weightedMode: 0
|
||||
inWeight: 0.33333334
|
||||
outWeight: 0.33333334
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
colorGradient:
|
||||
serializedVersion: 2
|
||||
key0: {r: 1, g: 1, b: 1, a: 1}
|
||||
key1: {r: 1, g: 1, b: 1, a: 1}
|
||||
key2: {r: 0, g: 0, b: 0, a: 0}
|
||||
key3: {r: 0, g: 0, b: 0, a: 0}
|
||||
key4: {r: 0, g: 0, b: 0, a: 0}
|
||||
key5: {r: 0, g: 0, b: 0, a: 0}
|
||||
key6: {r: 0, g: 0, b: 0, a: 0}
|
||||
key7: {r: 0, g: 0, b: 0, a: 0}
|
||||
ctime0: 0
|
||||
ctime1: 65535
|
||||
ctime2: 0
|
||||
ctime3: 0
|
||||
ctime4: 0
|
||||
ctime5: 0
|
||||
ctime6: 0
|
||||
ctime7: 0
|
||||
atime0: 0
|
||||
atime1: 65535
|
||||
atime2: 0
|
||||
atime3: 0
|
||||
atime4: 0
|
||||
atime5: 0
|
||||
atime6: 0
|
||||
atime7: 0
|
||||
m_Mode: 0
|
||||
m_NumColorKeys: 2
|
||||
m_NumAlphaKeys: 2
|
||||
numCornerVertices: 0
|
||||
numCapVertices: 0
|
||||
alignment: 0
|
||||
textureMode: 0
|
||||
generateLightingData: 0
|
||||
m_UseWorldSpace: 1
|
||||
m_Loop: 0
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 811a192407d7b8f449de20b725a2938a
|
||||
timeCreated: 1508486655
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,130 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1001 &100100000
|
||||
Prefab:
|
||||
m_ObjectHideFlags: 1
|
||||
serializedVersion: 2
|
||||
m_Modification:
|
||||
m_TransformParent: {fileID: 0}
|
||||
m_Modifications: []
|
||||
m_RemovedComponents: []
|
||||
m_ParentPrefab: {fileID: 0}
|
||||
m_RootGameObject: {fileID: 1386574972781608}
|
||||
m_IsPrefabParent: 1
|
||||
--- !u!1 &1386574972781608
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
serializedVersion: 5
|
||||
m_Component:
|
||||
- component: {fileID: 4165100386123906}
|
||||
- component: {fileID: 120042951271217888}
|
||||
m_Layer: 0
|
||||
m_Name: Particle Plexus Line Renderer Template
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &4165100386123906
|
||||
Transform:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1386574972781608}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!120 &120042951271217888
|
||||
LineRenderer:
|
||||
m_ObjectHideFlags: 1
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 100100000}
|
||||
m_GameObject: {fileID: 1386574972781608}
|
||||
m_Enabled: 1
|
||||
m_CastShadows: 1
|
||||
m_ReceiveShadows: 1
|
||||
m_DynamicOccludee: 1
|
||||
m_MotionVectors: 0
|
||||
m_LightProbeUsage: 0
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_Materials:
|
||||
- {fileID: 2100000, guid: 35e2e3a06b6570a4cac191d4ca904974, type: 2}
|
||||
m_StaticBatchInfo:
|
||||
firstSubMesh: 0
|
||||
subMeshCount: 0
|
||||
m_StaticBatchRoot: {fileID: 0}
|
||||
m_ProbeAnchor: {fileID: 0}
|
||||
m_LightProbeVolumeOverride: {fileID: 0}
|
||||
m_ScaleInLightmap: 1
|
||||
m_PreserveUVs: 0
|
||||
m_IgnoreNormalsForChartDetection: 0
|
||||
m_ImportantGI: 0
|
||||
m_StitchLightmapSeams: 0
|
||||
m_SelectedEditorRenderState: 3
|
||||
m_MinimumChartSize: 4
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_Positions:
|
||||
- {x: 0, y: 0, z: 0}
|
||||
- {x: 0, y: 0, z: 1}
|
||||
m_Parameters:
|
||||
serializedVersion: 2
|
||||
widthMultiplier: 0.1
|
||||
widthCurve:
|
||||
serializedVersion: 2
|
||||
m_Curve:
|
||||
- serializedVersion: 2
|
||||
time: 0
|
||||
value: 1
|
||||
inSlope: 0
|
||||
outSlope: 0
|
||||
tangentMode: 0
|
||||
m_PreInfinity: 2
|
||||
m_PostInfinity: 2
|
||||
m_RotationOrder: 4
|
||||
colorGradient:
|
||||
serializedVersion: 2
|
||||
key0: {r: 1, g: 1, b: 1, a: 1}
|
||||
key1: {r: 1, g: 1, b: 1, a: 1}
|
||||
key2: {r: 0, g: 0, b: 0, a: 0}
|
||||
key3: {r: 0, g: 0, b: 0, a: 0}
|
||||
key4: {r: 0, g: 0, b: 0, a: 0}
|
||||
key5: {r: 0, g: 0, b: 0, a: 0}
|
||||
key6: {r: 0, g: 0, b: 0, a: 0}
|
||||
key7: {r: 0, g: 0, b: 0, a: 0}
|
||||
ctime0: 0
|
||||
ctime1: 65535
|
||||
ctime2: 0
|
||||
ctime3: 0
|
||||
ctime4: 0
|
||||
ctime5: 0
|
||||
ctime6: 0
|
||||
ctime7: 0
|
||||
atime0: 0
|
||||
atime1: 65535
|
||||
atime2: 0
|
||||
atime3: 0
|
||||
atime4: 0
|
||||
atime5: 0
|
||||
atime6: 0
|
||||
atime7: 0
|
||||
m_Mode: 0
|
||||
m_NumColorKeys: 2
|
||||
m_NumAlphaKeys: 2
|
||||
numCornerVertices: 0
|
||||
numCapVertices: 0
|
||||
alignment: 0
|
||||
textureMode: 0
|
||||
generateLightingData: 0
|
||||
m_UseWorldSpace: 1
|
||||
m_Loop: 0
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f3c2176600c9f849accec9070807b4c
|
||||
timeCreated: 1508486655
|
||||
licenseType: Store
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 100100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f41fb4812cb5fe947b4a34ca6417fb4d
|
||||
folderAsset: yes
|
||||
timeCreated: 1508486470
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d714a506331b704ab6494f60e605ef7
|
||||
timeCreated: 1508486513
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9d6f4d9c6527fdf448ccbece1878b71f
|
||||
timeCreated: 1508486513
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 95f78947de6b3fe458563de77b4b20a3
|
||||
folderAsset: yes
|
||||
timeCreated: 1508398165
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,50 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class ParticlePlexusDemo_CameraRig : MonoBehaviour
|
||||
{
|
||||
public Transform pivot;
|
||||
Vector3 targetRotation;
|
||||
|
||||
[Range(0.0f, 90.0f)]
|
||||
public float rotationLimit = 90.0f;
|
||||
|
||||
public float rotationSpeed = 2.0f;
|
||||
public float rotationLerpSpeed = 4.0f;
|
||||
|
||||
Vector3 startRotation;
|
||||
|
||||
void Start()
|
||||
{
|
||||
startRotation = pivot.localEulerAngles;
|
||||
targetRotation = startRotation;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
float horizontal = Input.GetAxis("Horizontal");
|
||||
float vertical = Input.GetAxis("Vertical");
|
||||
|
||||
if (Input.GetKeyDown(KeyCode.R))
|
||||
{
|
||||
targetRotation = startRotation;
|
||||
}
|
||||
|
||||
horizontal *= rotationSpeed;
|
||||
vertical *= rotationSpeed;
|
||||
|
||||
targetRotation.y += horizontal;
|
||||
targetRotation.x += vertical;
|
||||
|
||||
targetRotation.x = Mathf.Clamp(targetRotation.x, -rotationLimit, rotationLimit);
|
||||
targetRotation.y = Mathf.Clamp(targetRotation.y, -rotationLimit, rotationLimit);
|
||||
|
||||
Vector3 currentRotation = pivot.localEulerAngles;
|
||||
|
||||
currentRotation.x = Mathf.LerpAngle(currentRotation.x, targetRotation.x, Time.deltaTime * rotationLerpSpeed);
|
||||
currentRotation.y = Mathf.LerpAngle(currentRotation.y, targetRotation.y, Time.deltaTime * rotationLerpSpeed);
|
||||
|
||||
pivot.localEulerAngles = currentRotation;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c45c745708239bb4faf150bbfcddd20b
|
||||
timeCreated: 1508405059
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 11e544dc2c8eb384ba0a1b186b7a4cbf
|
||||
folderAsset: yes
|
||||
timeCreated: 1485465673
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,841 @@
|
||||
|
||||
// =================================
|
||||
// Namespaces.
|
||||
// =================================
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using System.Threading;
|
||||
|
||||
// =================================
|
||||
// Define namespace.
|
||||
// =================================
|
||||
|
||||
namespace MirzaBeig
|
||||
{
|
||||
|
||||
namespace Scripting
|
||||
{
|
||||
|
||||
namespace Effects
|
||||
{
|
||||
|
||||
// =================================
|
||||
// Classes.
|
||||
// =================================
|
||||
|
||||
[RequireComponent(typeof(ParticleSystem))]
|
||||
[AddComponentMenu("Effects/Particle Plexus")]
|
||||
|
||||
public class ParticlePlexus : MonoBehaviour
|
||||
{
|
||||
// =================================
|
||||
// Nested classes and structures.
|
||||
// =================================
|
||||
|
||||
// ...
|
||||
|
||||
// =================================
|
||||
// Variables.
|
||||
// =================================
|
||||
|
||||
// ...
|
||||
|
||||
public float maxDistance = 1.0f;
|
||||
|
||||
public int maxConnections = 5;
|
||||
public int maxLineRenderers = 100;
|
||||
|
||||
[Space]
|
||||
|
||||
[Range(0.0f, 1.0f)]
|
||||
public float widthFromParticle = 0.125f;
|
||||
|
||||
[Space]
|
||||
|
||||
[Range(0.0f, 1.0f)]
|
||||
public float colourFromParticle = 1.0f;
|
||||
|
||||
[Range(0.0f, 1.0f)]
|
||||
public float alphaFromParticle = 1.0f;
|
||||
|
||||
[Space]
|
||||
|
||||
public AnimationCurve alphaOverNormalizedDistance = AnimationCurve.Linear(0.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
//public float fadeInTime = 0.0f;
|
||||
|
||||
new ParticleSystem particleSystem;
|
||||
|
||||
ParticleSystem.Particle[] particles;
|
||||
|
||||
Vector3[] particlePositions;
|
||||
|
||||
Color[] particleColours;
|
||||
float[] particleSizes;
|
||||
|
||||
ParticleSystem.MainModule particleSystemMainModule;
|
||||
|
||||
[Space]
|
||||
|
||||
public LineRenderer lineRendererTemplate;
|
||||
List<LineRenderer> lineRenderers = new List<LineRenderer>();
|
||||
|
||||
//[System.Serializable]
|
||||
//public struct LineRendererData
|
||||
//{
|
||||
// public float currentStartParticleID;
|
||||
// public float currentEndParticleID;
|
||||
|
||||
// public float previousStartParticleID;
|
||||
// public float previousEndParticleID;
|
||||
|
||||
// public float timer;
|
||||
//}
|
||||
|
||||
//List<LineRendererData> lineRendererData = new List<LineRendererData>();
|
||||
|
||||
Transform _transform;
|
||||
|
||||
[Header("Triangle Mesh Settings")]
|
||||
|
||||
public MeshFilter trianglesMeshFilter;
|
||||
Mesh trianglesMesh;
|
||||
|
||||
List<int[]> allConnectedParticles = new List<int[]>();
|
||||
|
||||
[Space]
|
||||
|
||||
// Triangles can be limited to those with particles who
|
||||
// are a fraction of the distance limit from other particles.
|
||||
|
||||
// Example:
|
||||
|
||||
// 1.0 == use same distance as maxDistance.
|
||||
// 0.5 == half of maxDistance.
|
||||
|
||||
[Range(0.0f, 1.0f)]
|
||||
public float maxDistanceTriangleBias = 1.0f;
|
||||
|
||||
[Space]
|
||||
|
||||
// Additional filtering for triangle generation so that it's more based on distance to adjacent particles.
|
||||
|
||||
public bool trianglesDistanceCheck = false;
|
||||
|
||||
[Space]
|
||||
|
||||
[Range(0.0f, 1.0f)]
|
||||
public float triangleColourFromParticle = 1.0f;
|
||||
|
||||
[Range(0.0f, 1.0f)]
|
||||
public float triangleAlphaFromParticle = 1.0f;
|
||||
|
||||
[Header("General Performance Settings")]
|
||||
|
||||
[Range(0.0f, 1.0f)]
|
||||
public float delay = 0.0f;
|
||||
|
||||
float timer;
|
||||
|
||||
public bool alwaysUpdate = false;
|
||||
bool visible;
|
||||
|
||||
//List<Vector4> customParticleData = new List<Vector4>();
|
||||
//int uniqueParticleID;
|
||||
|
||||
// =================================
|
||||
// Functions.
|
||||
// =================================
|
||||
|
||||
// ...
|
||||
|
||||
void Start()
|
||||
{
|
||||
particleSystem = GetComponent<ParticleSystem>();
|
||||
particleSystemMainModule = particleSystem.main;
|
||||
|
||||
_transform = transform;
|
||||
|
||||
if (trianglesMeshFilter)
|
||||
{
|
||||
trianglesMesh = new Mesh();
|
||||
trianglesMeshFilter.mesh = trianglesMesh;
|
||||
|
||||
// Unparent since I don't want it following me, but I may have
|
||||
// parented in the scene for organization.
|
||||
|
||||
// EDIT: Nevermind, let the user deal with this as they see fit.
|
||||
|
||||
//if (trianglesMeshFilter.transform != transform)
|
||||
//{
|
||||
// trianglesMeshFilter.transform.parent = null;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
for (int i = 0; i < lineRenderers.Count; i++)
|
||||
{
|
||||
lineRenderers[i].enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
void OnBecameVisible()
|
||||
{
|
||||
visible = true;
|
||||
}
|
||||
void OnBecameInvisible()
|
||||
{
|
||||
visible = false;
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
void LateUpdate()
|
||||
{
|
||||
if (trianglesMeshFilter)
|
||||
{
|
||||
switch (particleSystemMainModule.simulationSpace)
|
||||
{
|
||||
case ParticleSystemSimulationSpace.World:
|
||||
{
|
||||
// Make sure this is always at origin, or triangle mesh moves out of sync since
|
||||
// the mesh triangle vertices are already set to the world space particle positions.
|
||||
|
||||
trianglesMeshFilter.transform.position = Vector3.zero;
|
||||
|
||||
break;
|
||||
}
|
||||
case ParticleSystemSimulationSpace.Local:
|
||||
{
|
||||
// In local space it should follow me.
|
||||
|
||||
trianglesMeshFilter.transform.position = transform.position;
|
||||
trianglesMeshFilter.transform.rotation = transform.rotation;
|
||||
|
||||
break;
|
||||
}
|
||||
case ParticleSystemSimulationSpace.Custom:
|
||||
{
|
||||
// In custom space it should follow the custom transform.
|
||||
|
||||
trianglesMeshFilter.transform.position = particleSystemMainModule.customSimulationSpace.position;
|
||||
trianglesMeshFilter.transform.rotation = particleSystemMainModule.customSimulationSpace.rotation;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter doesn't exist but mesh is there? That means the filter reference was lost. Clear the mesh.
|
||||
// AKA... If mesh filter is gone (deleted and/or reference nulled), clear the mesh.
|
||||
|
||||
else if (trianglesMesh)
|
||||
{
|
||||
trianglesMesh.Clear();
|
||||
}
|
||||
|
||||
int lineRenderersCount = lineRenderers.Count;
|
||||
|
||||
// In case max line renderers value is changed at runtime -> destroy extra.
|
||||
|
||||
if (lineRenderersCount > maxLineRenderers)
|
||||
{
|
||||
for (int i = maxLineRenderers; i < lineRenderersCount; i++)
|
||||
{
|
||||
Destroy(lineRenderers[i].gameObject);
|
||||
}
|
||||
|
||||
lineRenderers.RemoveRange(maxLineRenderers, lineRenderersCount - maxLineRenderers);
|
||||
//lineRendererData.RemoveRange(maxLineRenderers, lineRenderersCount - maxLineRenderers);
|
||||
|
||||
lineRenderersCount -= lineRenderersCount - maxLineRenderers;
|
||||
}
|
||||
|
||||
if (alwaysUpdate || visible)
|
||||
{
|
||||
// Prevent constant allocations so long as max particle count doesn't change.
|
||||
|
||||
int maxParticles = particleSystemMainModule.maxParticles;
|
||||
|
||||
if (particles == null || particles.Length < maxParticles)
|
||||
{
|
||||
particles = new ParticleSystem.Particle[maxParticles];
|
||||
|
||||
particlePositions = new Vector3[maxParticles];
|
||||
|
||||
particleColours = new Color[maxParticles];
|
||||
particleSizes = new float[maxParticles];
|
||||
}
|
||||
|
||||
float deltaTime = Time.deltaTime;
|
||||
|
||||
timer += deltaTime;
|
||||
|
||||
if (timer >= delay)
|
||||
{
|
||||
timer = 0.0f;
|
||||
|
||||
int lrIndex = 0;
|
||||
|
||||
allConnectedParticles.Clear();
|
||||
|
||||
// Only update if drawing/making connections.
|
||||
|
||||
if (maxConnections > 0 && maxLineRenderers > 0)
|
||||
{
|
||||
particleSystem.GetParticles(particles);
|
||||
//particleSystem.GetCustomParticleData(customParticleData, ParticleSystemCustomData.Custom1);
|
||||
|
||||
int particleCount = particleSystem.particleCount;
|
||||
|
||||
float maxDistanceSqr = maxDistance * maxDistance;
|
||||
|
||||
ParticleSystemSimulationSpace simulationSpace = particleSystemMainModule.simulationSpace;
|
||||
ParticleSystemScalingMode scalingMode = particleSystemMainModule.scalingMode;
|
||||
|
||||
Transform customSimulationSpaceTransform = particleSystemMainModule.customSimulationSpace;
|
||||
|
||||
Color lineRendererStartColour = lineRendererTemplate.startColor;
|
||||
Color lineRendererEndColour = lineRendererTemplate.endColor;
|
||||
|
||||
float lineRendererStartWidth = lineRendererTemplate.startWidth * lineRendererTemplate.widthMultiplier;
|
||||
float lineRendererEndWidth = lineRendererTemplate.endWidth * lineRendererTemplate.widthMultiplier;
|
||||
|
||||
// Save particle properties in a quick loop (accessing these is expensive and loops significantly more later, so it's better to save them once now).
|
||||
|
||||
for (int i = 0; i < particleCount; i++)
|
||||
{
|
||||
particlePositions[i] = particles[i].position;
|
||||
|
||||
particleColours[i] = particles[i].GetCurrentColor(particleSystem);
|
||||
particleSizes[i] = particles[i].GetCurrentSize(particleSystem);
|
||||
|
||||
// Default is 0.0f, so if default, this is a new particle and I need to assign a custom ID.
|
||||
|
||||
//if (customParticleData[i].x == 0.0f)
|
||||
//{
|
||||
// // ++value -> increment first, then return that value.
|
||||
// // That way it won't be zero (default) the first time I use it.
|
||||
|
||||
// customParticleData[i] = new Vector4(++uniqueParticleID, 0, 0, 0);
|
||||
//}
|
||||
}
|
||||
|
||||
//particleSystem.SetCustomParticleData(customParticleData, ParticleSystemCustomData.Custom1);
|
||||
|
||||
Vector3 p1p2_difference;
|
||||
|
||||
// If in world space, there's no need to do any of the extra calculations... simplify the loop!
|
||||
|
||||
if (simulationSpace == ParticleSystemSimulationSpace.World)
|
||||
{
|
||||
for (int i = 0; i < particleCount; i++)
|
||||
{
|
||||
if (lrIndex == maxLineRenderers)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Color particleColour = particleColours[i];
|
||||
|
||||
Color lineStartColour = Color.LerpUnclamped(lineRendererStartColour, particleColour, colourFromParticle);
|
||||
float lineStartColourOriginalAlpha = Mathf.LerpUnclamped(lineRendererStartColour.a, particleColour.a, alphaFromParticle);
|
||||
|
||||
lineStartColour.a = lineStartColourOriginalAlpha;
|
||||
|
||||
float lineStartWidth = Mathf.LerpUnclamped(lineRendererStartWidth, particleSizes[i], widthFromParticle);
|
||||
|
||||
int connections = 0;
|
||||
int[] connectedParticles = new int[maxConnections + 1];
|
||||
|
||||
for (int j = i + 1; j < particleCount; j++)
|
||||
{
|
||||
p1p2_difference.x = particlePositions[i].x - particlePositions[j].x;
|
||||
p1p2_difference.y = particlePositions[i].y - particlePositions[j].y;
|
||||
p1p2_difference.z = particlePositions[i].z - particlePositions[j].z;
|
||||
|
||||
//float distanceSqr = Vector3.SqrMagnitude(p1p2_difference);
|
||||
|
||||
float distanceSqr =
|
||||
|
||||
p1p2_difference.x * p1p2_difference.x +
|
||||
p1p2_difference.y * p1p2_difference.y +
|
||||
p1p2_difference.z * p1p2_difference.z;
|
||||
|
||||
if (distanceSqr <= maxDistanceSqr)
|
||||
{
|
||||
LineRenderer lr;
|
||||
|
||||
if (lrIndex == lineRenderersCount)
|
||||
{
|
||||
lr = Instantiate(lineRendererTemplate, _transform, false);
|
||||
|
||||
lineRenderers.Add(lr);
|
||||
lineRenderersCount++;
|
||||
}
|
||||
|
||||
lr = lineRenderers[lrIndex]; lr.enabled = true;
|
||||
|
||||
lr.SetPosition(0, particlePositions[i]);
|
||||
lr.SetPosition(1, particlePositions[j]);
|
||||
|
||||
float alphaAttenuation = alphaOverNormalizedDistance.Evaluate(distanceSqr / maxDistanceSqr);
|
||||
lineStartColour.a = lineStartColourOriginalAlpha * alphaAttenuation;
|
||||
|
||||
lr.startColor = lineStartColour;
|
||||
|
||||
particleColour = particleColours[j];
|
||||
|
||||
Color lineEndColour = Color.LerpUnclamped(lineRendererEndColour, particleColour, colourFromParticle);
|
||||
lineEndColour.a = Mathf.LerpUnclamped(lineRendererEndColour.a, particleColour.a, alphaFromParticle);
|
||||
|
||||
lr.endColor = lineEndColour;
|
||||
|
||||
lr.startWidth = lineStartWidth;
|
||||
lr.endWidth = Mathf.LerpUnclamped(lineRendererEndWidth, particleSizes[j], widthFromParticle);
|
||||
|
||||
lrIndex++;
|
||||
connections++;
|
||||
|
||||
// Intentionally taken AFTER connections++ (because index = 0 is the i'th / line origin particle).
|
||||
|
||||
connectedParticles[connections] = j;
|
||||
|
||||
if (connections == maxConnections || lrIndex == maxLineRenderers)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (connections >= 2)
|
||||
{
|
||||
connectedParticles[0] = i;
|
||||
allConnectedParticles.Add(connectedParticles);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector3 position = Vector3.zero;
|
||||
Quaternion rotation = Quaternion.identity;
|
||||
Vector3 localScale = Vector3.one;
|
||||
|
||||
Transform simulationSpaceTransform = _transform;
|
||||
|
||||
switch (simulationSpace)
|
||||
{
|
||||
case ParticleSystemSimulationSpace.Local:
|
||||
{
|
||||
position = simulationSpaceTransform.position;
|
||||
rotation = simulationSpaceTransform.rotation;
|
||||
localScale = simulationSpaceTransform.localScale;
|
||||
|
||||
break;
|
||||
}
|
||||
case ParticleSystemSimulationSpace.Custom:
|
||||
{
|
||||
simulationSpaceTransform = customSimulationSpaceTransform;
|
||||
|
||||
position = simulationSpaceTransform.position;
|
||||
rotation = simulationSpaceTransform.rotation;
|
||||
localScale = simulationSpaceTransform.localScale;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new System.NotSupportedException(
|
||||
|
||||
string.Format("Unsupported scaling mode '{0}'.", simulationSpace));
|
||||
}
|
||||
}
|
||||
|
||||
// I put these here so I can take out the default exception case.
|
||||
// Else I'd have a compiler error for potentially unassigned variables.
|
||||
|
||||
Vector3 p1_position = Vector3.zero;
|
||||
Vector3 p2_position = Vector3.zero;
|
||||
|
||||
for (int i = 0; i < particleCount; i++)
|
||||
{
|
||||
if (lrIndex == maxLineRenderers)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
switch (simulationSpace)
|
||||
{
|
||||
case ParticleSystemSimulationSpace.Local:
|
||||
case ParticleSystemSimulationSpace.Custom:
|
||||
{
|
||||
switch (scalingMode)
|
||||
{
|
||||
case ParticleSystemScalingMode.Hierarchy:
|
||||
{
|
||||
p1_position = simulationSpaceTransform.TransformPoint(particlePositions[i]);
|
||||
|
||||
break;
|
||||
}
|
||||
case ParticleSystemScalingMode.Local:
|
||||
{
|
||||
// Order is important.
|
||||
|
||||
//p1_position = Vector3.Scale(particlePositions[i], localScale);
|
||||
|
||||
p1_position.x = particlePositions[i].x * localScale.x;
|
||||
p1_position.y = particlePositions[i].y * localScale.y;
|
||||
p1_position.z = particlePositions[i].z * localScale.z;
|
||||
|
||||
p1_position = rotation * p1_position;
|
||||
//p1_position += position;
|
||||
|
||||
p1_position.x += position.x;
|
||||
p1_position.y += position.y;
|
||||
p1_position.z += position.z;
|
||||
|
||||
break;
|
||||
}
|
||||
case ParticleSystemScalingMode.Shape:
|
||||
{
|
||||
// Order is important.
|
||||
|
||||
p1_position = rotation * particlePositions[i];
|
||||
//p1_position += position;
|
||||
|
||||
p1_position.x += position.x;
|
||||
p1_position.y += position.y;
|
||||
p1_position.z += position.z;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new System.NotSupportedException(
|
||||
|
||||
string.Format("Unsupported scaling mode '{0}'.", scalingMode));
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Color particleColour = particleColours[i];
|
||||
|
||||
Color lineStartColour = Color.LerpUnclamped(lineRendererStartColour, particleColour, colourFromParticle);
|
||||
float lineStartColourOriginalAlpha = Mathf.LerpUnclamped(lineRendererStartColour.a, particleColour.a, alphaFromParticle);
|
||||
|
||||
lineStartColour.a = lineStartColourOriginalAlpha;
|
||||
|
||||
float lineStartWidth = Mathf.LerpUnclamped(lineRendererStartWidth, particleSizes[i], widthFromParticle);
|
||||
|
||||
int connections = 0;
|
||||
int[] connectedParticles = new int[maxConnections + 1];
|
||||
|
||||
for (int j = i + 1; j < particleCount; j++)
|
||||
{
|
||||
// Note that because particles array is not sorted by distance,
|
||||
// but rather by spawn time (I think), the connections made are
|
||||
// not necessarily the closest.
|
||||
|
||||
switch (simulationSpace)
|
||||
{
|
||||
case ParticleSystemSimulationSpace.Local:
|
||||
case ParticleSystemSimulationSpace.Custom:
|
||||
{
|
||||
switch (scalingMode)
|
||||
{
|
||||
case ParticleSystemScalingMode.Hierarchy:
|
||||
{
|
||||
p2_position = simulationSpaceTransform.TransformPoint(particlePositions[j]);
|
||||
|
||||
break;
|
||||
}
|
||||
case ParticleSystemScalingMode.Local:
|
||||
{
|
||||
// Order is important.
|
||||
|
||||
//p2_position = Vector3.Scale(particlePositions[j], localScale);
|
||||
|
||||
p2_position.x = particlePositions[j].x * localScale.x;
|
||||
p2_position.y = particlePositions[j].y * localScale.y;
|
||||
p2_position.z = particlePositions[j].z * localScale.z;
|
||||
|
||||
p2_position = rotation * p2_position;
|
||||
//p2_position += position;
|
||||
|
||||
p2_position.x += position.x;
|
||||
p2_position.y += position.y;
|
||||
p2_position.z += position.z;
|
||||
|
||||
break;
|
||||
}
|
||||
case ParticleSystemScalingMode.Shape:
|
||||
{
|
||||
// Order is important.
|
||||
|
||||
p2_position = rotation * particlePositions[j];
|
||||
//p2_position += position;
|
||||
|
||||
p2_position.x += position.x;
|
||||
p2_position.y += position.y;
|
||||
p2_position.z += position.z;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
throw new System.NotSupportedException(
|
||||
|
||||
string.Format("Unsupported scaling mode '{0}'.", scalingMode));
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
p1p2_difference.x = particlePositions[i].x - particlePositions[j].x;
|
||||
p1p2_difference.y = particlePositions[i].y - particlePositions[j].y;
|
||||
p1p2_difference.z = particlePositions[i].z - particlePositions[j].z;
|
||||
|
||||
// Note that distance is always calculated in WORLD SPACE.
|
||||
// Scaling the particle system will stretch the distances
|
||||
// and may require adjusting the maxDistance value.
|
||||
|
||||
// I could also do it in local space (which may actually make more
|
||||
// sense) by just getting the difference of the positions without
|
||||
// all the transformations. This also provides opportunity for
|
||||
// optimization as I can limit the world space transform calculations
|
||||
// to only happen if a particle is within range.
|
||||
|
||||
// Think about: Putting in a bool to switch between the two?
|
||||
|
||||
//float distanceSqr = Vector3.SqrMagnitude(p1p2_difference);
|
||||
|
||||
float distanceSqr =
|
||||
|
||||
p1p2_difference.x * p1p2_difference.x +
|
||||
p1p2_difference.y * p1p2_difference.y +
|
||||
p1p2_difference.z * p1p2_difference.z;
|
||||
|
||||
// If distance to particle within range, add new vertex position.
|
||||
|
||||
// The larger the max distance, the quicker connections will
|
||||
// reach its max, terminating the loop earlier. So even though more lines have
|
||||
// to be drawn, it's still faster to have a larger maxDistance value because
|
||||
// the call to Vector3.Distance() is expensive.
|
||||
|
||||
if (distanceSqr <= maxDistanceSqr)
|
||||
{
|
||||
LineRenderer lr;
|
||||
|
||||
if (lrIndex == lineRenderersCount)
|
||||
{
|
||||
lr = Instantiate(lineRendererTemplate, _transform, false);
|
||||
|
||||
lineRenderers.Add(lr);
|
||||
lineRenderersCount++;
|
||||
|
||||
//lineRendererData.Add(new LineRendererData());
|
||||
}
|
||||
|
||||
lr = lineRenderers[lrIndex];
|
||||
//LineRendererData lrd = lineRendererData[lrIndex];
|
||||
|
||||
lr.enabled = true;
|
||||
|
||||
//lrd.previousStartParticleID = lrd.currentStartParticleID;
|
||||
//lrd.previousEndParticleID = lrd.currentEndParticleID;
|
||||
|
||||
//lrd.currentStartParticleID = customParticleData[i].x;
|
||||
//lrd.currentEndParticleID = customParticleData[j].x;
|
||||
|
||||
lr.SetPosition(0, p1_position);
|
||||
lr.SetPosition(1, p2_position);
|
||||
|
||||
//if (lrd.currentStartParticleID != lrd.previousStartParticleID || lrd.currentEndParticleID != lrd.previousEndParticleID)
|
||||
//{
|
||||
// lrd.timer = 0.0f;
|
||||
//}
|
||||
|
||||
//if (lrd.timer < 1.0f)
|
||||
//{
|
||||
// lrd.timer += deltaTime / fadeInTime;
|
||||
//}
|
||||
|
||||
//if (lrd.timer > 1.0f)
|
||||
//{
|
||||
// lrd.timer = 1.0f;
|
||||
//}
|
||||
|
||||
float alphaAttenuation = alphaOverNormalizedDistance.Evaluate(distanceSqr / maxDistanceSqr);
|
||||
//float alphaAttenuation = lrd.timer * alphaOverNormalizedDistance.Evaluate(distanceSqr / maxDistanceSqr);
|
||||
|
||||
lineStartColour.a = lineStartColourOriginalAlpha * alphaAttenuation;
|
||||
|
||||
lr.startColor = lineStartColour;
|
||||
|
||||
particleColour = particleColours[j];
|
||||
|
||||
Color lineEndColour = Color.LerpUnclamped(lineRendererEndColour, particleColour, colourFromParticle);
|
||||
lineEndColour.a = Mathf.LerpUnclamped(lineRendererEndColour.a, particleColour.a, alphaFromParticle) * alphaAttenuation;
|
||||
|
||||
lr.endColor = lineEndColour;
|
||||
|
||||
lr.startWidth = lineStartWidth;
|
||||
lr.endWidth = Mathf.LerpUnclamped(lineRendererEndWidth, particleSizes[j], widthFromParticle);
|
||||
|
||||
//lineRendererData[lrIndex] = lrd;
|
||||
|
||||
lrIndex++;
|
||||
connections++;
|
||||
|
||||
// Intentionally taken AFTER connections++ (because index = 0 is the i'th / line origin particle).
|
||||
|
||||
connectedParticles[connections] = j;
|
||||
|
||||
if (connections == maxConnections || lrIndex == maxLineRenderers)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (connections >= 2)
|
||||
{
|
||||
connectedParticles[0] = i;
|
||||
allConnectedParticles.Add(connectedParticles);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Disable remaining line renderers from the pool that weren't used.
|
||||
|
||||
for (int i = lrIndex; i < lineRenderersCount; i++)
|
||||
{
|
||||
if (lineRenderers[i].enabled)
|
||||
{
|
||||
lineRenderers[i].enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
// I check against the filter rather than the mesh because the mesh should always exist as long as the filter reference is there.
|
||||
// This way I can stop drawing/updating should the filter reference be lost.
|
||||
|
||||
if (trianglesMeshFilter)
|
||||
{
|
||||
// Triangles mesh.
|
||||
|
||||
// For efficiency (and my own general laziness), I only bother taking the first triangle formed.
|
||||
// It doesn't matter all that much since this is an abstract effect anyway.
|
||||
|
||||
int vertexCount = allConnectedParticles.Count * 3;
|
||||
|
||||
Vector3[] vertices = new Vector3[vertexCount];
|
||||
int[] triangles = new int[vertexCount];
|
||||
|
||||
Vector2[] uv = new Vector2[vertexCount];
|
||||
|
||||
Color[] colours = new Color[vertexCount];
|
||||
|
||||
float maxDistanceSqr = (maxDistance * maxDistance) * maxDistanceTriangleBias;
|
||||
|
||||
for (int i = 0; i < allConnectedParticles.Count; i++)
|
||||
{
|
||||
int[] connectedParticles = allConnectedParticles[i];
|
||||
|
||||
float distanceSqr = 0.0f;
|
||||
|
||||
if (trianglesDistanceCheck)
|
||||
{
|
||||
Vector3 particlePositionA = particlePositions[connectedParticles[1]];
|
||||
Vector3 particlePositionB = particlePositions[connectedParticles[2]];
|
||||
|
||||
//distance = Vector3.Distance(particlePositionA, particlePositionB);
|
||||
|
||||
Vector3 difference;
|
||||
|
||||
difference.x = particlePositionA.x - particlePositionB.x;
|
||||
difference.y = particlePositionA.y - particlePositionB.y;
|
||||
difference.z = particlePositionA.z - particlePositionB.z;
|
||||
|
||||
distanceSqr =
|
||||
|
||||
difference.x * difference.x +
|
||||
difference.y * difference.y +
|
||||
difference.z * difference.z;
|
||||
}
|
||||
|
||||
if (distanceSqr < maxDistanceSqr)
|
||||
{
|
||||
int i3 = i * 3;
|
||||
|
||||
vertices[i3 + 0] = particlePositions[connectedParticles[0]];
|
||||
vertices[i3 + 1] = particlePositions[connectedParticles[1]];
|
||||
vertices[i3 + 2] = particlePositions[connectedParticles[2]];
|
||||
|
||||
uv[i3 + 0] = new Vector2(0.0f, 0.0f);
|
||||
uv[i3 + 1] = new Vector2(0.0f, 1.0f);
|
||||
uv[i3 + 2] = new Vector2(1.0f, 1.0f);
|
||||
|
||||
triangles[i3 + 0] = i3 + 0;
|
||||
triangles[i3 + 1] = i3 + 1;
|
||||
triangles[i3 + 2] = i3 + 2;
|
||||
|
||||
colours[i3 + 0] = particleColours[connectedParticles[0]];
|
||||
colours[i3 + 1] = particleColours[connectedParticles[1]];
|
||||
colours[i3 + 2] = particleColours[connectedParticles[2]];
|
||||
|
||||
colours[i3 + 0] = Color.LerpUnclamped(Color.white, particleColours[connectedParticles[0]], triangleColourFromParticle);
|
||||
colours[i3 + 1] = Color.LerpUnclamped(Color.white, particleColours[connectedParticles[1]], triangleColourFromParticle);
|
||||
colours[i3 + 2] = Color.LerpUnclamped(Color.white, particleColours[connectedParticles[2]], triangleColourFromParticle);
|
||||
|
||||
colours[i3 + 0].a = Mathf.LerpUnclamped(1.0f, particleColours[connectedParticles[0]].a, triangleAlphaFromParticle);
|
||||
colours[i3 + 1].a = Mathf.LerpUnclamped(1.0f, particleColours[connectedParticles[1]].a, triangleAlphaFromParticle);
|
||||
colours[i3 + 2].a = Mathf.LerpUnclamped(1.0f, particleColours[connectedParticles[2]].a, triangleAlphaFromParticle);
|
||||
}
|
||||
}
|
||||
|
||||
trianglesMesh.Clear();
|
||||
|
||||
trianglesMesh.vertices = vertices;
|
||||
|
||||
trianglesMesh.uv = uv;
|
||||
|
||||
trianglesMesh.triangles = triangles;
|
||||
trianglesMesh.colors = colours;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =================================
|
||||
// End functions.
|
||||
// =================================
|
||||
|
||||
}
|
||||
|
||||
// =================================
|
||||
// End namespace.
|
||||
// =================================
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// =================================
|
||||
// --END-- //
|
||||
// =================================
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 75a5a8e349c9cf54496babb3e7fd5191
|
||||
timeCreated: 1458196122
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 76c3b696fa9b1e84b9b417fcbec52a51
|
||||
folderAsset: yes
|
||||
timeCreated: 1514855790
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
@@ -0,0 +1,77 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1a0cb63a3bc8d2342852089bfb884192
|
||||
timeCreated: 1514855896
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
wrapU: -1
|
||||
wrapV: -1
|
||||
wrapW: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
@@ -0,0 +1,77 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fcc934170231d0244809002a4923c98b
|
||||
timeCreated: 1514855896
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
wrapU: -1
|
||||
wrapV: -1
|
||||
wrapW: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/NEW VFX TO CHECK/Scripting/Effects/_Common.meta
Normal file
9
Assets/NEW VFX TO CHECK/Scripting/Effects/_Common.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5431348cc70e26a4e9bbacb93a76cf2f
|
||||
folderAsset: yes
|
||||
timeCreated: 1472356639
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
119
Assets/NEW VFX TO CHECK/Scripting/Effects/_Common/CreateLUT.cs
Normal file
119
Assets/NEW VFX TO CHECK/Scripting/Effects/_Common/CreateLUT.cs
Normal file
@@ -0,0 +1,119 @@
|
||||
|
||||
// =================================
|
||||
// Namespaces.
|
||||
// =================================
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
// =================================
|
||||
// Define namespace.
|
||||
// =================================
|
||||
|
||||
namespace MirzaBeig
|
||||
{
|
||||
|
||||
namespace Scripting
|
||||
{
|
||||
|
||||
namespace Effects
|
||||
{
|
||||
|
||||
// =================================
|
||||
// Classes.
|
||||
// =================================
|
||||
|
||||
//[ExecuteInEditMode]
|
||||
//[System.Serializable]
|
||||
|
||||
//[RequireComponent(typeof(ParticleSystem))]
|
||||
|
||||
static public class CreateLUT
|
||||
{
|
||||
// =================================
|
||||
// Nested classes and structures.
|
||||
// =================================
|
||||
|
||||
// ...
|
||||
|
||||
// =================================
|
||||
// Variables.
|
||||
// =================================
|
||||
|
||||
// ...
|
||||
|
||||
// =================================
|
||||
// Functions.
|
||||
// =================================
|
||||
|
||||
// ...
|
||||
|
||||
public static void fromGradient(int steps, Gradient gradient, ref Texture2D texture)
|
||||
{
|
||||
if (texture)
|
||||
{
|
||||
MonoBehaviour.Destroy(texture);
|
||||
}
|
||||
|
||||
texture = new Texture2D(steps, 1);
|
||||
|
||||
// Assign the first and last beforehand.
|
||||
// Min LUT width resolution is 2, so this will work without problems.
|
||||
|
||||
texture.SetPixel(0, 0, gradient.Evaluate(0.0f));
|
||||
texture.SetPixel(steps - 1, 0, gradient.Evaluate(1.0f));
|
||||
|
||||
// Then fill the middle (if any -> meaning if resolution > 2).
|
||||
|
||||
for (int i = 1; i < steps - 1; i++)
|
||||
{
|
||||
Color colour = gradient.Evaluate(i / (float)steps);
|
||||
texture.SetPixel(i, 0, colour);
|
||||
}
|
||||
|
||||
texture.Apply();
|
||||
}
|
||||
public static void fromAnimationCurve(int steps, AnimationCurve curve, ref Texture2D texture)
|
||||
{
|
||||
if (texture)
|
||||
{
|
||||
MonoBehaviour.Destroy(texture);
|
||||
}
|
||||
|
||||
texture = new Texture2D(steps, 1);
|
||||
|
||||
// Assign the first and last beforehand.
|
||||
// Min LUT width resolution is 2, so this will work without problems.
|
||||
|
||||
texture.SetPixel(0, 0, new Color(0.0f, 0.0f, 0.0f, curve.Evaluate(0.0f)));
|
||||
texture.SetPixel(steps - 1, 0, new Color(0.0f, 0.0f, 0.0f, curve.Evaluate(1.0f)));
|
||||
|
||||
// Then fill the middle (if any -> meaning if resolution > 2).
|
||||
|
||||
for (int i = 1; i < steps - 1; i++)
|
||||
{
|
||||
float value = curve.Evaluate(i / (float)steps);
|
||||
texture.SetPixel(i, 0, new Color(0.0f, 0.0f, 0.0f, value));
|
||||
}
|
||||
|
||||
texture.Apply();
|
||||
}
|
||||
|
||||
// =================================
|
||||
// End functions.
|
||||
// =================================
|
||||
|
||||
}
|
||||
|
||||
// =================================
|
||||
// End namespace.
|
||||
// =================================
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// =================================
|
||||
// --END-- //
|
||||
// =================================
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c4c0dbe010be294facfeebdb24ccbb5
|
||||
timeCreated: 1470567813
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user