/// <summary> /// Apply the changes to the particle system /// </summary> private void ChangeVelocityCurve(SplineParticles _target) { ParticleSystem myParticleSystem = _target.gameObject.GetComponent <ParticleSystem>(); SerializedObject newSerializedObject = new SerializedObject(myParticleSystem); SerializedProperty enableVelocityModule = newSerializedObject.FindProperty("VelocityModule.enabled"); SerializedProperty velocityModuleTypeX = newSerializedObject.FindProperty("VelocityModule.x.minMaxState"); SerializedProperty velocityModuleTypeY = newSerializedObject.FindProperty("VelocityModule.y.minMaxState"); SerializedProperty velocityModuleTypeZ = newSerializedObject.FindProperty("VelocityModule.z.minMaxState"); SerializedProperty velocityModuleInWorldSpace = newSerializedObject.FindProperty("VelocityModule.inWorldSpace"); SerializedProperty speedCurveX = newSerializedObject.FindProperty("VelocityModule.x.maxCurve"); SerializedProperty scalarCurveX = newSerializedObject.FindProperty("VelocityModule.x.scalar"); SerializedProperty speedCurveY = newSerializedObject.FindProperty("VelocityModule.y.maxCurve"); SerializedProperty scalarCurveY = newSerializedObject.FindProperty("VelocityModule.y.scalar"); SerializedProperty speedCurveZ = newSerializedObject.FindProperty("VelocityModule.z.maxCurve"); SerializedProperty scalarCurveZ = newSerializedObject.FindProperty("VelocityModule.z.scalar"); if (_target.autoEnableParticleVelocityCurves == true) { if (!_target.hasCreatedTheCurveOnce) { _target.GetComponent <ParticleSystem>().startSpeed = 0; _target.hasCreatedTheCurveOnce = true; } velocityModuleInWorldSpace.boolValue = false; enableVelocityModule.boolValue = _target.autoEnableParticleVelocityCurves; velocityModuleTypeX.intValue = 1; velocityModuleTypeY.intValue = 1; velocityModuleTypeZ.intValue = 1; _target.GetComponent <ParticleSystem>().startSpeed = 0; } scalarCurveX.floatValue = xVelocityCurveScale; scalarCurveY.floatValue = yVelocityCurveScale; scalarCurveZ.floatValue = zVelocityCurveScale; speedCurveX.animationCurveValue = _target.velocityCurveX; speedCurveY.animationCurveValue = _target.velocityCurveY; speedCurveZ.animationCurveValue = _target.velocityCurveZ; newSerializedObject.ApplyModifiedProperties(); }
public override void OnEnable() { base.OnEnable(); SplineParticles particlesFollowPath = target as SplineParticles; //Get the original values to know if any change to the particleSystem has been made previousRotation = particlesFollowPath.transform.rotation; previousScale = particlesFollowPath.transform.localScale; previousParticleLifeTime = particlesFollowPath.GetComponent <ParticleSystem>().startLifetime; }
/// <summary> /// Creates the velocity curve. /// </summary> /// <param name='_target'> /// _target. /// </param> private void CreateVelocityCurve(SplineParticles _target) { if (_target.pathQuality <= 0) { Debug.LogWarning("Too much quality on particle follow path"); return; } BaseSpline.SplineIterator splineIterator; if (_target.splinePath == null) { splineIterator = _target.GetComponent <SplineParticles>().Spline.GetIterator(); } else { splineIterator = _target.splinePath.Spline.GetIterator(); } //Clear curve values _target.velocityCurveX = new AnimationCurve(); _target.velocityCurveY = new AnimationCurve(); _target.velocityCurveZ = new AnimationCurve(); if (_target.loopNumber <= 1) //Set the curve points for each loop { SetCurvePoints(1, splineIterator, _target, 0); } else { for (int i = 0; i < _target.loopNumber; i++) { SetCurvePoints(_target.loopNumber, splineIterator, _target, (float)i / (float)_target.loopNumber); } } //Check if there is any key on the last keyframe, for precision problems if (1 - _target.velocityCurveX.keys[_target.velocityCurveX.keys.Length - 1].time >= 0.0001f) { CalculatePoint(1, 1, splineIterator, _target, 0); } }
/// <summary> /// Calculates the point each animation curve point. /// </summary> private void CalculatePoint(float _point, int _loopNumber, BaseSpline.SplineIterator _iterator, SplineParticles _target, float _offset) { _iterator.SetOffsetPercent(_point); //Calc modifiers float lifeTimeModifier = _target.GetComponent <ParticleSystem>().startLifetime; float loopsModifier = _target.loopNumber; Vector3 currentPosition = _target.transform.TransformPoint(_iterator.GetPosition()); Vector3 tangentAtPoint = (_iterator.GetTangent().normalized); Vector3 velocityAtPoint = Vector3.zero; if (_point == 0 && _target.Spline.WrapMode == BaseSpline.SplineWrapMode.Loop) { _iterator.SetOffsetPercent(1 - _target.pathQuality); previousPoint = _target.transform.TransformPoint(_iterator.GetPosition()); } else if (_point == 0 && _target.Spline.WrapMode != BaseSpline.SplineWrapMode.Loop) { _iterator.SetOffsetPercent(_point + _target.pathQuality); previousPoint = _target.transform.TransformPoint(_iterator.GetPosition()); } velocityAtPoint = (currentPosition - previousPoint).magnitude * tangentAtPoint; previousPoint = currentPosition; velocityAtPoint *= loopsModifier * (1 / _target.pathQuality) / lifeTimeModifier; _target.velocityCurveX.AddKey(_point / _loopNumber + _offset, velocityAtPoint.x); _target.velocityCurveY.AddKey(_point / _loopNumber + _offset, velocityAtPoint.y); _target.velocityCurveZ.AddKey(_point / _loopNumber + _offset, velocityAtPoint.z); }
public override void OnInspectorGUI() { base.OnInspectorGUI(); //EditorGUIUtility.LookLikeInspector(); DrawDefaultInspector(); SplineParticles particlesFollowPath = target as SplineParticles; //Get the target //Check if we have made any changes to the particle system that affect the sline if (particlesFollowPath.enableContinuosEditorUpdate && (particlesFollowPath.transform.rotation != previousRotation || particlesFollowPath.transform.localScale != previousScale || previousParticleLifeTime != particlesFollowPath.GetComponent <ParticleSystem>().startLifetime)) { CreateAndSetVelocityCurves(particlesFollowPath); } previousScale = particlesFollowPath.transform.localScale; previousRotation = particlesFollowPath.transform.rotation; previousParticleLifeTime = particlesFollowPath.GetComponent <ParticleSystem>().startLifetime; //Parameters EditorGUILayout.Separator(); particlesFollowPath.useSpiral = EditorGUILayout.Toggle("Is spiral", particlesFollowPath.useSpiral); if (particlesFollowPath.useSpiral) { particlesFollowPath.spiralLoops = EditorGUILayout.FloatField("Spiral loops", particlesFollowPath.spiralLoops); particlesFollowPath.spiralAmplitude = EditorGUILayout.FloatField("Spiral Amplitude", particlesFollowPath.spiralAmplitude); particlesFollowPath.spiralAxis = (SplineParticles.SPIRAL_AXIS)EditorGUILayout.EnumPopup("Spiral Axis", particlesFollowPath.spiralAxis); EditorGUILayout.Separator(); } GUILayout.BeginHorizontal(); GUILayout.Label(" Path subdivisions " + "(" + particlesFollowPath.pathQuality.ToString("0.000") + ")"); particlesFollowPath.pathQuality = GUILayout.HorizontalSlider(particlesFollowPath.pathQuality, 0.001f, 0.25f); GUILayout.Label(" Path simplify margin" + "(" + particlesFollowPath.pathSimplifyError.ToString("0.00") + ")"); particlesFollowPath.pathSimplifyError = GUILayout.HorizontalSlider(particlesFollowPath.pathSimplifyError, 0, 1); GUILayout.EndHorizontal(); if (particlesFollowPath.Spline.WrapMode == BaseSpline.SplineWrapMode.Loop) { particlesFollowPath.loopNumber = EditorGUILayout.IntField("Loops", particlesFollowPath.loopNumber); } else { particlesFollowPath.loopNumber = 1; } //Buttons GUIStyle buttonStyleRed = new GUIStyle("button"); buttonStyleRed.normal.textColor = Color.red; GUIStyle buttonStyleGreen = new GUIStyle("button"); buttonStyleGreen.normal.textColor = Color.green; if (GUILayout.Button("Create velocity curve", buttonStyleGreen)) { CreateAndSetVelocityCurves(particlesFollowPath); } if (GUILayout.Button("Set velocity curve")) { ChangeVelocityCurve(particlesFollowPath); } if (GUILayout.Button("Clear velocity curve", buttonStyleRed)) { ClearCurves(particlesFollowPath); } if (GUI.changed && particlesFollowPath.enableContinuosEditorUpdate) { CreateAndSetVelocityCurves(particlesFollowPath); EditorUtility.SetDirty(particlesFollowPath); } }
/// <summary> /// Apply the changes to the particle system /// </summary> private void ChangeVelocityCurve(SplineParticles _target) { ParticleSystem myParticleSystem = _target.gameObject.GetComponent<ParticleSystem>(); SerializedObject newSerializedObject = new SerializedObject(myParticleSystem); SerializedProperty enableVelocityModule = newSerializedObject.FindProperty("VelocityModule.enabled"); SerializedProperty velocityModuleTypeX = newSerializedObject.FindProperty("VelocityModule.x.minMaxState"); SerializedProperty velocityModuleTypeY = newSerializedObject.FindProperty("VelocityModule.y.minMaxState"); SerializedProperty velocityModuleTypeZ = newSerializedObject.FindProperty("VelocityModule.z.minMaxState"); SerializedProperty velocityModuleInWorldSpace = newSerializedObject.FindProperty("VelocityModule.inWorldSpace"); SerializedProperty speedCurveX = newSerializedObject.FindProperty("VelocityModule.x.maxCurve"); SerializedProperty scalarCurveX = newSerializedObject.FindProperty("VelocityModule.x.scalar"); SerializedProperty speedCurveY = newSerializedObject.FindProperty("VelocityModule.y.maxCurve"); SerializedProperty scalarCurveY = newSerializedObject.FindProperty("VelocityModule.y.scalar"); SerializedProperty speedCurveZ = newSerializedObject.FindProperty("VelocityModule.z.maxCurve"); SerializedProperty scalarCurveZ = newSerializedObject.FindProperty("VelocityModule.z.scalar"); if (_target.autoEnableParticleVelocityCurves == true) { if (!_target.hasCreatedTheCurveOnce) { _target.GetComponent<ParticleSystem>().startSpeed = 0; _target.hasCreatedTheCurveOnce = true; } velocityModuleInWorldSpace.boolValue = false; enableVelocityModule.boolValue = _target.autoEnableParticleVelocityCurves; velocityModuleTypeX.intValue = 1; velocityModuleTypeY.intValue = 1; velocityModuleTypeZ.intValue = 1; _target.GetComponent<ParticleSystem>().startSpeed = 0; } scalarCurveX.floatValue = xVelocityCurveScale; scalarCurveY.floatValue = yVelocityCurveScale; scalarCurveZ.floatValue = zVelocityCurveScale; speedCurveX.animationCurveValue = _target.velocityCurveX; speedCurveY.animationCurveValue = _target.velocityCurveY; speedCurveZ.animationCurveValue = _target.velocityCurveZ; newSerializedObject.ApplyModifiedProperties(); }
/// <summary> /// Calculates the point each animation curve point. /// </summary> private void CalculatePoint(float _point, int _loopNumber, BaseSpline.SplineIterator _iterator, SplineParticles _target, float _offset) { _iterator.SetOffsetPercent(_point); //Calc modifiers float lifeTimeModifier = _target.GetComponent<ParticleSystem>().startLifetime; float loopsModifier = _target.loopNumber; Vector3 currentPosition = _target.transform.TransformPoint(_iterator.GetPosition()); Vector3 tangentAtPoint = (_iterator.GetTangent().normalized); Vector3 velocityAtPoint = Vector3.zero; if (_point == 0 && _target.Spline.WrapMode == BaseSpline.SplineWrapMode.Loop) { _iterator.SetOffsetPercent(1-_target.pathQuality); previousPoint = _target.transform.TransformPoint(_iterator.GetPosition()); } else if (_point == 0 && _target.Spline.WrapMode != BaseSpline.SplineWrapMode.Loop) { _iterator.SetOffsetPercent(_point+_target.pathQuality); previousPoint = _target.transform.TransformPoint(_iterator.GetPosition()); } velocityAtPoint = (currentPosition - previousPoint).magnitude * tangentAtPoint; previousPoint = currentPosition; velocityAtPoint *= loopsModifier*(1/_target.pathQuality)/lifeTimeModifier; _target.velocityCurveX.AddKey(_point/_loopNumber + _offset,velocityAtPoint.x); _target.velocityCurveY.AddKey(_point/_loopNumber + _offset,velocityAtPoint.y); _target.velocityCurveZ.AddKey(_point/_loopNumber + _offset,velocityAtPoint.z); }
/// <summary> /// Creates the velocity curve. /// </summary> /// <param name='_target'> /// _target. /// </param> private void CreateVelocityCurve(SplineParticles _target) { if (_target.pathQuality <= 0) { Debug.LogWarning("Too much quality on particle follow path"); return; } BaseSpline.SplineIterator splineIterator; if (_target.splinePath == null) splineIterator = _target.GetComponent<SplineParticles>().Spline.GetIterator(); else splineIterator = _target.splinePath.Spline.GetIterator(); //Clear curve values _target.velocityCurveX = new AnimationCurve(); _target.velocityCurveY = new AnimationCurve(); _target.velocityCurveZ = new AnimationCurve(); if (_target.loopNumber <= 1) //Set the curve points for each loop { SetCurvePoints(1, splineIterator, _target, 0); } else { for (int i = 0; i < _target.loopNumber; i++) SetCurvePoints(_target.loopNumber, splineIterator, _target, (float)i/(float)_target.loopNumber); } //Check if there is any key on the last keyframe, for precision problems if (1 - _target.velocityCurveX.keys[_target.velocityCurveX.keys.Length-1].time >= 0.0001f) { CalculatePoint(1, 1, splineIterator, _target, 0); } }