OldBlueWater/BlueWater/Assets/AssetKits/ParticleImage/Editor/ParticleImageEditor.cs
2023-08-09 16:47:55 +09:00

707 lines
36 KiB
C#

// Version: 1.1.0
using AssetKits.ParticleImage.Enumerations;
using UnityEditor;
using UnityEditor.Experimental.SceneManagement;
using UnityEditor.SceneManagement;
using UnityEngine;
using PlayMode = AssetKits.ParticleImage.Enumerations.PlayMode;
namespace AssetKits.ParticleImage.Editor
{
[CanEditMultipleObjects]
[CustomEditor(typeof(ParticleImage))]
public class ParticleImageEditor : UnityEditor.Editor
{
private ParticleImage _particle;
//General Properties
private SerializedProperty _space;
private SerializedProperty _timeScale;
private SerializedProperty _playMode;
private SerializedProperty _loop;
private SerializedProperty _duration;
private SerializedProperty _delay;
private SerializedProperty _life;
private SerializedProperty _speed;
private SerializedProperty _startSize;
private SerializedProperty _startRotation;
private SerializedProperty _startColor;
private SerializedProperty _raycast;
private SerializedProperty _maskable;
//Emitter Properties
private SerializedProperty _rate;
private SerializedProperty _rateOverLifetime;
private SerializedProperty _rateOverDistance;
private SerializedProperty _burst;
private SerializedProperty _emitterShape;
private SerializedProperty _width;
private SerializedProperty _height;
private SerializedProperty _length;
private SerializedProperty _radius;
private SerializedProperty _angle;
private SerializedProperty _surface;
private SerializedProperty _edge;
private SerializedProperty _spreadType;
private SerializedProperty _spreadLoop;
private SerializedProperty _startPoint;
private SerializedProperty _startPointTrans;
//Particle Properties
private SerializedProperty _texture;
private SerializedProperty _material;
private SerializedProperty _speedOverLifetime;
private SerializedProperty _sizeOverLifetime;
private SerializedProperty _sizeBySpeed;
private SerializedProperty _sizeSpeedRange;
private SerializedProperty _colorOverLifetime;
private SerializedProperty _colorBySpeed;
private SerializedProperty _colorSpeedRange;
private SerializedProperty _rotateOverLifetime;
private SerializedProperty _rotationBySpeed;
private SerializedProperty _rotationSpeedRange;
private SerializedProperty _alignDirection;
private SerializedProperty _sheetModule;
private SerializedProperty _sheetType;
private SerializedProperty _tile;
private SerializedProperty _frameOverTime;
private SerializedProperty _startFrame;
private SerializedProperty _frameSpeedRange;
private SerializedProperty _frameFps;
private SerializedProperty _cycles;
private SerializedProperty _trailModule;
private SerializedProperty _trailWidth;
private SerializedProperty _trailColorOverLifetime;
private SerializedProperty _trailColorOverTrail;
private SerializedProperty _trailLifetime;
private SerializedProperty _inheritColor;
private SerializedProperty _dieWithParticle;
private SerializedProperty _trailRatio;
private SerializedProperty _minimumVertexDistance;
//Movement Properties
private SerializedProperty _targetModule;
private SerializedProperty _targetTransform;
private SerializedProperty _targetCurve;
private SerializedProperty _targetMode;
private SerializedProperty _noiseModule;
private SerializedProperty _noiseFreq;
private SerializedProperty _noiseOct;
private SerializedProperty _noiseStrength;
private SerializedProperty _velocityModule;
private SerializedProperty _velocitySpace;
private SerializedProperty _velocityOverLifetime;
private SerializedProperty _gravityModule;
private SerializedProperty _gravity;
private SerializedProperty _vortexModule;
private SerializedProperty _vortexStrength;
//Event Properties
private SerializedProperty _onStart;
private SerializedProperty _onFinish;
private SerializedProperty _onFirstParticleFinish;
private SerializedProperty _onLastParticleFinish;
private SerializedProperty _onParticleFinish;
//Editor Icons
private Texture _particleModuleIcon;
private Texture _movementModuleIcon;
private Texture _emitterModuleIcon;
private Texture _eventModuleIcon;
//Module Foldouts
private GUIStyle _foldoutStyle;
private GUIStyle FoldoutStyle
{
get
{
if (_foldoutStyle == null)
{
_foldoutStyle = new GUIStyle("ShurikenModuleTitle");
_foldoutStyle.font = new GUIStyle(EditorStyles.label).font;
_foldoutStyle.border = new RectOffset(15, 7, 4, 4);
_foldoutStyle.fixedHeight = 24;
_foldoutStyle.contentOffset = new Vector2(20f, -2f);
}
return _foldoutStyle;
}
}
void Awake()
{
//Set Icons
MonoScript.FromMonoBehaviour(target as ParticleImage).SetIcon(Resources.Load<Texture2D>("ComponentIcon"));
_emitterModuleIcon = EditorGUIUtility.IconContent("AreaLight Gizmo").image;
_particleModuleIcon = Resources.Load<Texture>("ParticleModule");
_movementModuleIcon = Resources.Load<Texture>("MovementModule");
_eventModuleIcon = Resources.Load<Texture>("EventModule");
}
private void OnEnable()
{
serializedObject.Update();
_particle = target as ParticleImage;
//Initialize Properties
_startPoint = serializedObject.FindProperty("_emitterConstraintEnabled");
_startPointTrans = serializedObject.FindProperty("_emitterConstraintTransform");
_timeScale = serializedObject.FindProperty("_timeScale");
_playMode = serializedObject.FindProperty("_playMode");
_delay = serializedObject.FindProperty("_startDelay");
_loop = serializedObject.FindProperty("_loop");
_duration = serializedObject.FindProperty("_duration");
_maskable = serializedObject.FindProperty("m_Maskable");
_raycast = serializedObject.FindProperty("m_RaycastTarget");
_rate = serializedObject.FindProperty("_rate");
_rateOverLifetime = serializedObject.FindProperty("_rateOverLifetime");
_rateOverDistance = serializedObject.FindProperty("_rateOverDistance");
_emitterShape = serializedObject.FindProperty("_shape");
_spreadType = serializedObject.FindProperty("_spread");
_spreadLoop = serializedObject.FindProperty("_spreadLoop");
_space = serializedObject.FindProperty("_space");
_angle = serializedObject.FindProperty("_angle");
_width = serializedObject.FindProperty("_width");
_height = serializedObject.FindProperty("_height");
_length = serializedObject.FindProperty("_length");
_radius = serializedObject.FindProperty("_radius");
_surface = serializedObject.FindProperty("_emitOnSurface");
_edge = serializedObject.FindProperty("_emitterThickness");
_colorOverLifetime = serializedObject.FindProperty("_colorOverLifetime");
_colorBySpeed = serializedObject.FindProperty("_colorBySpeed");
_colorSpeedRange = serializedObject.FindProperty("_colorSpeedRange");
_sizeOverLifetime = serializedObject.FindProperty("_sizeOverLifetime");
_sizeBySpeed = serializedObject.FindProperty("_sizeBySpeed");
_sizeSpeedRange = serializedObject.FindProperty("_sizeSpeedRange");
_startRotation = serializedObject.FindProperty("_startRotation");
_rotateOverLifetime = serializedObject.FindProperty("_rotationOverLifetime");
_rotationBySpeed = serializedObject.FindProperty("_rotationBySpeed");
_rotationSpeedRange = serializedObject.FindProperty("_rotationSpeedRange");
_targetTransform = serializedObject.FindProperty("_attractorTarget");
_targetCurve = serializedObject.FindProperty("_toTarget");
_burst = serializedObject.FindProperty("_bursts");
_speed = serializedObject.FindProperty("_startSpeed");
_startSize = serializedObject.FindProperty("_startSize");
_material = serializedObject.FindProperty("m_Material");
_startColor = serializedObject.FindProperty("_startColor");
_life = serializedObject.FindProperty("_lifetime");
_speedOverLifetime = serializedObject.FindProperty("_speedOverLifetime");
_texture = serializedObject.FindProperty("m_Texture");
_sheetModule = serializedObject.FindProperty("_sheetModule");
_sheetType = serializedObject.FindProperty("_sheetType");
_tile = serializedObject.FindProperty("_textureTile");
_frameOverTime = serializedObject.FindProperty("_frameOverTime");
_startFrame = serializedObject.FindProperty("_startFrame");
_frameSpeedRange = serializedObject.FindProperty("_frameSpeedRange");
_frameFps = serializedObject.FindProperty("_textureSheetFPS");
_cycles = serializedObject.FindProperty("_textureSheetCycles");
_targetMode = serializedObject.FindProperty("_targetMode");
_gravity = serializedObject.FindProperty("_gravity");
_targetModule = serializedObject.FindProperty("_targetModule");
_noiseModule = serializedObject.FindProperty("_noiseModule");
_noiseFreq = serializedObject.FindProperty("_noiseFrequency");
_noiseOct = serializedObject.FindProperty("_noiseOctaves");
_noiseStrength = serializedObject.FindProperty("_noiseStrength");
_gravityModule = serializedObject.FindProperty("_gravityModule");
_vortexModule = serializedObject.FindProperty("_vortexModule");
_vortexStrength = serializedObject.FindProperty("_vortexStrength");
_velocityModule = serializedObject.FindProperty("_velocityModule");
_velocitySpace = serializedObject.FindProperty("_velocitySpace");
_velocityOverLifetime = serializedObject.FindProperty("_velocityOverLifetime");
_alignDirection = serializedObject.FindProperty("_alignToDirection");
_trailModule = serializedObject.FindProperty("_trailModule");
_trailWidth = serializedObject.FindProperty("_trailWidth");
_trailColorOverLifetime = serializedObject.FindProperty("_trailColorOverLifetime");
_trailColorOverTrail = serializedObject.FindProperty("_trailColorOverTrail");
_trailLifetime = serializedObject.FindProperty("_trailLifetime");
_inheritColor = serializedObject.FindProperty("_inheritParticleColor");
_dieWithParticle = serializedObject.FindProperty("_dieWithParticle");
_trailRatio = serializedObject.FindProperty("_trailRatio");
_minimumVertexDistance = serializedObject.FindProperty("_minimumVertexDistance");
_onStart = serializedObject.FindProperty("_onStart");
_onFinish = serializedObject.FindProperty("_onStop");
_onFirstParticleFinish = serializedObject.FindProperty("_onFirstParticleFinish");
_onLastParticleFinish = serializedObject.FindProperty("_onLastParticleFinish");
_onParticleFinish = serializedObject.FindProperty("_onParticleFinish");
_particle.OnEnable();
if (Application.isEditor && !EditorApplication.isPlaying)
{
_particle.Invoke(nameof(ParticleImage.Play), 0.1f);
}
EditorApplication.update += EditorUpdate;
SceneView.duringSceneGui += DrawSceneWindow;
Undo.undoRedoPerformed += UndoRedoPerformed;
}
private void OnDisable()
{
EditorApplication.update -= EditorUpdate;
SceneView.duringSceneGui -= DrawSceneWindow;
Undo.undoRedoPerformed -= UndoRedoPerformed;
if (Application.isEditor && !EditorApplication.isPlaying && _particle)
{
_particle.CancelInvoke();
_particle.Pause();
}
}
private void UndoRedoPerformed()
{
// Temporary fix for NullReferenceException on undo performed when Curve Editor is open (Unity bug)
if (EditorWindow.focusedWindow.titleContent.text == "Curve Editor")
{
EditorWindow.focusedWindow.Close();
}
}
void OnSceneGUI()
{
Handles.color = Color.cyan;
Handles.matrix = _particle.transform.localToWorldMatrix;
// Draw emitter shape
switch (_particle.shape)
{
case EmitterShape.Circle:
Handles.DrawWireDisc(Vector3.zero, Vector3.forward, _particle.circleRadius);
if (_particle.emitOnSurface)
break;
// Draw inner circle
Handles.color = Color.gray;
Handles.DrawWireDisc(Vector3.zero, Vector3.forward,
_particle.circleRadius - _particle.emitterThickness);
break;
case EmitterShape.Rectangle:
Handles.DrawWireCube(Vector3.zero, new Vector3(_particle.rectWidth, _particle.rectHeight));
if(_particle.emitOnSurface)
break;
// Draw inner rectangle
Handles.DrawWireCube(Vector3.zero, new Vector3(_particle.rectWidth - _particle.emitterThickness, _particle.rectHeight - _particle.emitterThickness));
break;
case EmitterShape.Line:
Handles.DrawLine(new Vector3(-_particle.lineLength/2, 0, 0), new Vector3(_particle.lineLength/2, 0, 0));
break;
case EmitterShape.Directional:
Handles.DrawWireArc(Vector3.zero, Vector3.forward, PointInCircle(_angle.floatValue/2).normalized, _angle.floatValue,100);
Handles.DrawLine(Vector3.zero, PointInCircle(_angle.floatValue/2).normalized * 100f);
Handles.DrawLine(Vector3.zero, PointInCircle(-_angle.floatValue/2).normalized * 100f);
break;
}
Handles.color = Color.white;
}
// Get point on circle from angle
private Vector3 PointInCircle(float angle){
var rad = angle * Mathf.Deg2Rad;
return new Vector3(Mathf.Sin( rad ), Mathf.Cos( rad ), 0);
}
// Draw control panel in scene view
void DrawSceneWindow(SceneView sceneView)
{
Handles.BeginGUI();
Rect rect;
if (PrefabStageUtility.GetCurrentPrefabStage())
{
rect = new Rect(Screen.width / EditorGUIUtility.pixelsPerPoint - 230,
Screen.height / EditorGUIUtility.pixelsPerPoint - 168, 220, 88);
}
else
{
rect = new Rect(Screen.width / EditorGUIUtility.pixelsPerPoint - 230,
Screen.height / EditorGUIUtility.pixelsPerPoint - 142, 220, 88);
}
GUILayout.BeginArea(rect, new GUIContent(_particle.gameObject.name),new GUIStyle("window"));
GUILayout.BeginHorizontal();
if (GUILayout.Button(_particle.isPlaying ? "Pause" : "Play", new GUIStyle("ButtonLeft")))
{
if (_particle.isPlaying)
_particle.Pause();
else
_particle.Play();
}
if (GUILayout.Button("Reset", new GUIStyle("ButtonMid")))
{
_particle.Stop(true);
_particle.Play();
}
if (GUILayout.Button("Stop", new GUIStyle("ButtonRight")))
{
_particle.Stop(true);
}
GUILayout.EndHorizontal();
EditorGUILayout.LabelField("Playback Time",_particle.main ? _particle.main.time.ToString("F") : _particle.time.ToString("F"));
EditorGUILayout.LabelField("Particles",_particle.particles.Count.ToString());
GUILayout.EndArea();
Handles.EndGUI();
}
public override void OnInspectorGUI()
{
EditorGUILayout.PropertyField(_space, new GUIContent("Simulation Space"), false);
EditorGUILayout.PropertyField(_timeScale, new GUIContent("Simulation Time"), false);
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(_playMode, new GUIContent("Play*", "Shared between the particles group"), false);
if (EditorGUI.EndChangeCheck())
{
_particle.PlayMode = (PlayMode)_playMode.enumValueIndex;
EditorUtility.SetDirty(_particle);
}
EditorGUILayout.PropertyField(_loop, false);
EditorGUILayout.PropertyField(_duration, false);
EditorGUILayout.PropertyField(_delay,new GUIContent("Start Delay"), false);
EditorGUILayout.PropertyField(_life, false);
EditorGUILayout.PropertyField(_speed, false);
EditorGUILayout.PropertyField(_startSize, new GUIContent("Start Size"), false);
EditorGUILayout.PropertyField(_startRotation, new GUIContent("Start Rotation"), false);
EditorGUILayout.PropertyField(_startColor, new GUIContent("Start Color"), false);
EditorGUILayout.PropertyField(_raycast, false);
EditorGUILayout.PropertyField(_maskable, false);
_particle.moduleEmitterFoldout = Foldout("Emission", _particle.moduleEmitterFoldout, _emitterModuleIcon);
if (_particle.moduleEmitterFoldout)
{
EditorGUILayout.PropertyField(_rate, new GUIContent("Rate per Second"), false);
EditorGUILayout.PropertyField(_rateOverLifetime, new GUIContent("Rate over Duration") ,false);
EditorGUILayout.PropertyField(_rateOverDistance, new GUIContent("Rate over Distance"), false);
EditorGUILayout.PropertyField(_burst, true);
DrawHorizontalLine();
EditorGUILayout.PropertyField(_emitterShape, new GUIContent("Shape"),false);
switch (_particle.shape)
{
case EmitterShape.Point:
EditorGUILayout.PropertyField(_spreadType, new GUIContent("Spread"), false);
if (_particle.spreadType == SpreadType.Uniform)
{
EditorGUILayout.PropertyField(_spreadLoop, new GUIContent("Loop"), false);
}
break;
case EmitterShape.Circle:
EditorGUI.BeginDisabledGroup(_particle.fitRect);
EditorGUILayout.PropertyField(_radius,new GUIContent("Radius"), false);
EditorGUI.EndDisabledGroup();
_particle.fitRect = EditorGUILayout.Toggle("Fit Rect", _particle.fitRect);
EditorGUILayout.PropertyField(_surface, false);
if(!_surface.boolValue)
EditorGUILayout.PropertyField(_edge, false);
_edge.floatValue= Mathf.Clamp(_edge.floatValue, 0f, _particle.circleRadius);
EditorGUILayout.PropertyField(_spreadType, new GUIContent("Spread"), false);
if (_particle.spreadType == SpreadType.Uniform)
{
EditorGUILayout.PropertyField(_spreadLoop, new GUIContent("Loop"), false);
}
break;
case EmitterShape.Rectangle:
EditorGUI.BeginDisabledGroup(_particle.fitRect);
EditorGUILayout.PropertyField(_width, false);
EditorGUILayout.PropertyField(_height, false);
EditorGUI.EndDisabledGroup();
_particle.fitRect = EditorGUILayout.Toggle("Fit Rect",_particle.fitRect);
EditorGUILayout.PropertyField(_surface, false);
if(!_surface.boolValue)
EditorGUILayout.PropertyField(_edge, false);
_edge.floatValue= Mathf.Clamp(_edge.floatValue, 0f, _particle.rectTransform.sizeDelta.x<_particle.rectTransform.sizeDelta.y?_particle.rectWidth:_particle.rectHeight);
EditorGUILayout.PropertyField(_spreadType, new GUIContent("Spread"), false);
if (_particle.spreadType == SpreadType.Uniform)
{
EditorGUILayout.PropertyField(_spreadLoop, new GUIContent("Loop"), false);
}
break;
case EmitterShape.Line:
EditorGUI.BeginDisabledGroup(_particle.fitRect);
EditorGUILayout.PropertyField(_length, false);
EditorGUI.EndDisabledGroup();
_particle.fitRect = EditorGUILayout.Toggle("Fit Rect",_particle.fitRect);
EditorGUILayout.PropertyField(_spreadType, new GUIContent("Spread"), false);
if (_particle.spreadType == SpreadType.Uniform)
{
EditorGUILayout.PropertyField(_spreadLoop, new GUIContent("Loop"), false);
}
break;
case EmitterShape.Directional:
EditorGUILayout.PropertyField(_angle, false);
EditorGUILayout.PropertyField(_spreadType, new GUIContent("Spread"), false);
if (_particle.spreadType == SpreadType.Uniform)
{
EditorGUILayout.PropertyField(_spreadLoop, new GUIContent("Loop"), false);
}
break;
}
DrawHorizontalLine();
EditorGUILayout.PropertyField(_startPoint,new GUIContent("Emitter Constraint"), false);
if (_particle.emitterConstraintEnabled)
{
EditorGUILayout.PropertyField(_startPointTrans,new GUIContent("Transform"), false);
}
GUILayout.Space(2);
}
_particle.moduleParticleFoldout = Foldout("Particle", _particle.moduleParticleFoldout,_particleModuleIcon);
if (_particle.moduleParticleFoldout)
{
EditorGUILayout.PropertyField(_texture, new GUIContent("Texture"));
EditorGUILayout.PropertyField(_material, new GUIContent("Material"));
DrawHorizontalLine();
EditorGUILayout.PropertyField(_speedOverLifetime, false);
DrawHorizontalLine();
EditorGUILayout.PropertyField(_sizeOverLifetime, false);
EditorGUILayout.PropertyField(_sizeBySpeed, false);
EditorGUILayout.PropertyField(_sizeSpeedRange, new GUIContent("Size Speed Range"), false);
DrawHorizontalLine();
EditorGUILayout.PropertyField(_colorOverLifetime, false);
EditorGUILayout.PropertyField(_colorBySpeed, false);
EditorGUILayout.PropertyField(_colorSpeedRange, new GUIContent("Color Speed Range"), false);
DrawHorizontalLine();
EditorGUILayout.PropertyField(_rotateOverLifetime, false);
EditorGUILayout.PropertyField(_rotationBySpeed, false);
EditorGUILayout.PropertyField(_rotationSpeedRange, new GUIContent("Rotation Speed Range"), false);
EditorGUILayout.PropertyField(_alignDirection);
DrawHorizontalLine();
EditorGUILayout.PropertyField(_sheetModule, new GUIContent("Texture Sheet"));
if (_sheetModule.FindPropertyRelative("enabled").boolValue)
{
EditorGUILayout.PropertyField(_tile, new GUIContent("Tiles"), false);
EditorGUILayout.PropertyField(_sheetType, new GUIContent("Time Mode"), false);
switch (_particle.textureSheetType)
{
case SheetType.Lifetime:
EditorGUILayout.PropertyField(_frameOverTime, false);
EditorGUILayout.PropertyField(_startFrame, false);
EditorGUILayout.PropertyField(_cycles, false);
ParticleSystem.MinMaxCurve c = _particle.textureSheetFrameOverTime;
switch (_particle.textureSheetFrameOverTime.mode)
{
case ParticleSystemCurveMode.Curve:
c.curveMultiplier = Mathf.Clamp(_particle.textureSheetFrameOverTime.curveMultiplier, 0, _particle.textureTile.x*_particle.textureTile.y);
break;
case ParticleSystemCurveMode.TwoCurves:
c.curveMultiplier = Mathf.Clamp(_particle.textureSheetFrameOverTime.curveMultiplier, 0, _particle.textureTile.x*_particle.textureTile.y);
break;
case ParticleSystemCurveMode.TwoConstants:
c.constantMax = Mathf.Clamp(_particle.textureSheetFrameOverTime.constantMax, 0, _particle.textureTile.x*_particle.textureTile.y);
break;
case ParticleSystemCurveMode.Constant:
c.constant = Mathf.Clamp(_particle.textureSheetFrameOverTime.constant, 0, _particle.textureTile.x*_particle.textureTile.y);
break;
}
_particle.textureSheetFrameOverTime = c;
break;
case SheetType.Speed:
EditorGUILayout.PropertyField(_frameSpeedRange, new GUIContent("Speed Range"), false);
EditorGUILayout.PropertyField(_startFrame, false);
break;
case SheetType.FPS:
EditorGUILayout.PropertyField(_startFrame, false);
EditorGUILayout.PropertyField(_frameFps, new GUIContent("FPS"),false);
break;
}
ParticleSystem.MinMaxCurve sf = _particle.textureSheetStartFrame;
switch (_particle.textureSheetStartFrame.mode)
{
case ParticleSystemCurveMode.Curve:
sf.curveMultiplier = Mathf.Clamp(_particle.textureSheetStartFrame.curveMultiplier, 0, _particle.textureTile.x*_particle.textureTile.y);
break;
case ParticleSystemCurveMode.TwoCurves:
sf.curveMultiplier = Mathf.Clamp(_particle.textureSheetStartFrame.curveMultiplier, 0, _particle.textureTile.x*_particle.textureTile.y);
break;
case ParticleSystemCurveMode.TwoConstants:
sf.constantMax = Mathf.Clamp(_particle.textureSheetStartFrame.constantMax, 0, _particle.textureTile.x*_particle.textureTile.y);
break;
case ParticleSystemCurveMode.Constant:
sf.constant = Mathf.Clamp(_particle.textureSheetStartFrame.constant, 0, _particle.textureTile.x*_particle.textureTile.y);
break;
}
_particle.textureSheetStartFrame = sf;
}
DrawHorizontalLine();
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(_trailModule, new GUIContent("Trails"), false);
if (EditorGUI.EndChangeCheck())
{
if (_trailModule.FindPropertyRelative("enabled").boolValue)
{
GameObject tr = new GameObject("Trails");
tr.transform.parent = _particle.transform;
tr.transform.localPosition = Vector3.zero;
tr.transform.localScale = Vector3.one;
tr.transform.localEulerAngles = Vector3.zero;
tr.AddComponent<CanvasRenderer>();
ParticleTrailRenderer r = tr.AddComponent<ParticleTrailRenderer>();
_particle.particleTrailRenderer = r;
r.particle = _particle;
}
else
{
var ch = _particle.GetComponentsInChildren<ParticleTrailRenderer>();
for (int i = 0; i < ch.Length; i++)
{
DestroyImmediate(ch[i].gameObject);
}
}
}
if (_trailModule.FindPropertyRelative("enabled").boolValue)
{
EditorGUILayout.HelpBox("Please note that trails are in the beta stage and are not optimized for production use. Therefore, it is recommended that you apply for as few particles as possible.", MessageType.Warning);
EditorGUILayout.PropertyField(_trailRatio, new GUIContent("Trail Ratio"),false);
EditorGUILayout.PropertyField(_minimumVertexDistance, new GUIContent("Vertex Distance"),false);
EditorGUILayout.PropertyField(_trailLifetime, new GUIContent("Trail Lifetime"),false);
EditorGUILayout.PropertyField(_trailWidth, new GUIContent("Trail Width"),false);
EditorGUILayout.PropertyField(_inheritColor, new GUIContent("Inherit Particle Color"),false);
EditorGUILayout.PropertyField(_trailColorOverLifetime, new GUIContent("Color over Lifetime"),false);
EditorGUILayout.PropertyField(_trailColorOverTrail, new GUIContent("Color over Trail"),false);
EditorGUILayout.PropertyField(_dieWithParticle, new GUIContent("Die With Particle"),false);
}
GUILayout.Space(4);
}
_particle.moduleMovementFoldout = Foldout("Movement", _particle.moduleMovementFoldout,_movementModuleIcon);
if (_particle.moduleMovementFoldout)
{
EditorGUILayout.PropertyField(_targetModule, new GUIContent("Attractor"),false);
if (_targetModule.FindPropertyRelative("enabled").boolValue)
{
EditorGUILayout.PropertyField(_targetTransform,new GUIContent("Attractor"), false);
EditorGUILayout.PropertyField(_targetCurve,new GUIContent("Attractor Lerp"), false);
if(_particle.attractorTarget != null)
EditorGUI.BeginDisabledGroup(_particle.attractorTarget.GetType() != typeof(RectTransform));
else
EditorGUI.BeginDisabledGroup(false);
EditorGUILayout.PropertyField(_targetMode, new GUIContent("Attractor Mode"),false);
EditorGUI.EndDisabledGroup();
}
DrawHorizontalLine();
EditorGUILayout.PropertyField(_noiseModule, new GUIContent("Noise"), false);
if (_noiseModule.FindPropertyRelative("enabled").boolValue)
{
EditorGUILayout.PropertyField(_noiseStrength,new GUIContent("Strength"), false);
EditorGUILayout.PropertyField(_noiseFreq,new GUIContent("Frequency"), false);
EditorGUILayout.PropertyField(_noiseOct, new GUIContent("Octaves"),false);
_particle.noise.SetFrequency(_particle.noiseFrequency/100f);
_particle.noise.SetFractalOctaves(_particle.noiseOctaves);
}
DrawHorizontalLine();
EditorGUILayout.PropertyField(_velocityModule, new GUIContent("Velocity"), false);
if (_velocityModule.FindPropertyRelative("enabled").boolValue)
{
EditorGUILayout.PropertyField(_velocitySpace,new GUIContent("Space"), false);
EditorGUILayout.PropertyField(_velocityOverLifetime,new GUIContent("Velocity Over Lifetime"), false);
}
DrawHorizontalLine();
EditorGUILayout.PropertyField(_gravityModule, new GUIContent("Gravity"), false);
if (_gravityModule.FindPropertyRelative("enabled").boolValue)
{
EditorGUILayout.PropertyField(_gravity,new GUIContent("Gravity Force"), false);
}
DrawHorizontalLine();
EditorGUILayout.PropertyField(_vortexModule, new GUIContent("Vortex"), false);
if (_vortexModule.FindPropertyRelative("enabled").boolValue)
{
EditorGUILayout.PropertyField(_vortexStrength, false);
}
GUILayout.Space(4);
}
_particle.moduleEventsFoldout = Foldout("Events", _particle.moduleEventsFoldout,_eventModuleIcon);
if (_particle.moduleEventsFoldout)
{
EditorGUILayout.PropertyField(_onStart, false);
EditorGUILayout.PropertyField(_onFirstParticleFinish, false);
EditorGUILayout.PropertyField(_onParticleFinish, false);
EditorGUILayout.PropertyField(_onLastParticleFinish, false);
EditorGUILayout.PropertyField(_onFinish, false);
}
serializedObject.ApplyModifiedProperties();
}
void EditorUpdate()
{
EditorApplication.QueuePlayerLoopUpdate();
}
private void DrawHorizontalLine(int height = 1) {
GUILayout.Space(2);
Rect rect = GUILayoutUtility.GetRect(10, height, GUILayout.ExpandWidth(true));
rect.height = height;
rect.xMin = 18;
rect.xMax = EditorGUIUtility.currentViewWidth - 18;
Color lineColor = new Color(0.15f, 0.15f, 0.15f, 1);
EditorGUI.DrawRect(rect, lineColor);
GUILayout.Space(2);
}
private bool Foldout(string title, bool display, Texture icon)
{
var rect = GUILayoutUtility.GetRect(16f, 24f, FoldoutStyle);
GUI.Box(rect, title, FoldoutStyle);
var e = Event.current;
var toggleRect = new Rect(rect.x + 4f, rect.y + 4f, 13f, 13f);
if (e.type == EventType.Repaint)
{
EditorStyles.foldout.Draw(new Rect(rect.width - 4f, rect.y + 4f, 13f, 13f), false, false, display, false);
GUI.DrawTexture(toggleRect, icon);
}
if (e.type == EventType.MouseDown && rect.Contains(e.mousePosition))
{
display = !display;
e.Use();
}
return display;
}
}
}