diff --git a/Packages/UIParticle/Scripts/Editor/UIParticleEditor.cs b/Packages/UIParticle/Scripts/Editor/UIParticleEditor.cs index bf861b2..bf5dd16 100644 --- a/Packages/UIParticle/Scripts/Editor/UIParticleEditor.cs +++ b/Packages/UIParticle/Scripts/Editor/UIParticleEditor.cs @@ -160,13 +160,11 @@ protected override void OnEnable () _particles = targets.Cast ().ToArray (); - - // var psi = Resources.FindObjectsOfTypeAll() - // .FirstOrDefault(x => x.targets.SequenceEqual(this.targets)); - - // // var a = psi.m_ParticleEffectUI?.m_Emitters; - // Debug.Log(psi); + _shapeModuleUIs = null; + var targetsGos = targets.Cast().Select(x => x.gameObject).ToArray(); + _inspector = Resources.FindObjectsOfTypeAll() + .FirstOrDefault(x => x.targets.Cast().Select(x => x.gameObject).SequenceEqual(targetsGos)); } /// @@ -263,6 +261,8 @@ public override void OnInspectorGUI () BoxBoundsHandle _boxBoundsHandle = new BoxBoundsHandle (); SphereBoundsHandle _sphereBoundsHandle = new SphereBoundsHandle (); Mesh _spriteMesh; + ShapeModuleUI[] _shapeModuleUIs; + ParticleSystemInspector _inspector; static T Call (Type type, string method, params object [] args) { @@ -275,407 +275,38 @@ static T Call (Type type, string method, params object [] args) return (T)mi.Invoke (null, args); } - void OnSceneGUI () - { - Color origCol = Handles.color; - Handles.color = s_GizmoColor; - - Matrix4x4 orgMatrix = Handles.matrix; - - EditorGUI.BeginChangeCheck (); - - foreach (UIParticle uip in _particles) - { - ParticleSystem ps = uip.cachedParticleSystem; - if (!ps || !uip.canvas) - { - continue; - } - - var shapeModule = ps.shape; - var mainModule = ps.main; - - ParticleSystemShapeType type = shapeModule.shapeType; - - Matrix4x4 transformMatrix = new Matrix4x4 (); - if (mainModule.scalingMode == ParticleSystemScalingMode.Local) - { - transformMatrix.SetTRS (ps.transform.position, ps.transform.rotation, ps.transform.localScale); - } - else if (mainModule.scalingMode == ParticleSystemScalingMode.Hierarchy) - { - transformMatrix = ps.transform.localToWorldMatrix; - } - else - { - transformMatrix.SetTRS (ps.transform.position, ps.transform.rotation, ps.transform.lossyScale); - } - - bool isBox = (type == ParticleSystemShapeType.Box || type == ParticleSystemShapeType.BoxShell || type == ParticleSystemShapeType.BoxEdge || type == ParticleSystemShapeType.Rectangle); - - Vector3 emitterScale = isBox ? Vector3.one : shapeModule.scale; - Matrix4x4 emitterMatrix = Matrix4x4.TRS (shapeModule.position, Quaternion.Euler (shapeModule.rotation), emitterScale); - transformMatrix *= emitterMatrix; - Handles.matrix = transformMatrix; - - if (uip.canvas.renderMode == RenderMode.ScreenSpaceOverlay || ps.main.scalingMode == ParticleSystemScalingMode.Hierarchy) - { - Handles.matrix = Handles.matrix * Matrix4x4.Scale (Vector3.one * uip.scale); - } - else - { - Handles.matrix = Handles.matrix * Matrix4x4.Scale (uip.canvas.rootCanvas.transform.localScale * uip.scale); - } - - if (type == ParticleSystemShapeType.Sphere) - { - // Thickness - Handles.color *= s_ShapeGizmoThicknessTint; - EditorGUI.BeginChangeCheck (); - //float radiusThickness = Handles.DoSimpleRadiusHandle (Quaternion.identity, Vector3.zero, shapeModule.radius * (1.0f - shapeModule.radiusThickness), false, shapeModule.arc); - float radiusThickness = Handles.RadiusHandle (Quaternion.identity, Vector3.zero, shapeModule.radius * (1.0f - shapeModule.radiusThickness), false); - if (EditorGUI.EndChangeCheck ()) - { - Undo.RecordObject (ps, "Sphere Thickness Handle Change"); - shapeModule.radiusThickness = 1.0f - (radiusThickness / shapeModule.radius); - } - - // Sphere - Handles.color = s_GizmoColor; - EditorGUI.BeginChangeCheck (); - //float radius = Handles.DoSimpleRadiusHandle (Quaternion.identity, Vector3.zero, shapeModule.radius, false, shapeModule.arc); - float radius = Handles.RadiusHandle (Quaternion.identity, Vector3.zero, shapeModule.radius, false); - if (EditorGUI.EndChangeCheck ()) - { - Undo.RecordObject (ps, "Sphere Handle Change"); - shapeModule.radius = radius; - } - - // Texture - //Matrix4x4 textureTransform = transformMatrix * Matrix4x4.TRS (Vector3.zero, Quaternion.identity, Vector3.one * shapeModule.radius * 2.0f); - //OnSceneViewTextureGUI (shapeModule, s_SphereMesh, false, s_SphereTextureMaterial, textureTransform); - } - else if (type == ParticleSystemShapeType.Circle) - { - // Thickness - EditorGUI.BeginChangeCheck (); - - _arcHandle.angle = shapeModule.arc; - _arcHandle.radius = shapeModule.radius * (1.0f - shapeModule.radiusThickness); - _arcHandle.SetColorWithRadiusHandle (s_ShapeGizmoThicknessTint, 0f); - _arcHandle.angleHandleColor = Color.clear; - - using (new Handles.DrawingScope (Handles.matrix * s_ArcHandleOffsetMatrix)) - _arcHandle.DrawHandle (); - - if (EditorGUI.EndChangeCheck ()) - { - Undo.RecordObject (ps, "Circle Thickness Handle Change"); - shapeModule.radiusThickness = 1.0f - (_arcHandle.radius / shapeModule.radius); - } - - // Circle - EditorGUI.BeginChangeCheck (); - - _arcHandle.radius = shapeModule.radius; - _arcHandle.SetColorWithRadiusHandle (Color.white, 0f); - - using (new Handles.DrawingScope (Handles.matrix * s_ArcHandleOffsetMatrix)) - _arcHandle.DrawHandle (); - - if (EditorGUI.EndChangeCheck ()) - { - Undo.RecordObject (ps, "Circle Handle Change"); - shapeModule.radius = _arcHandle.radius; - shapeModule.arc = _arcHandle.angle; - } - - // Texture - //Matrix4x4 textureTransform = transformMatrix * Matrix4x4.TRS (Vector3.zero, Quaternion.Euler (90.0f, 0.0f, 180.0f), Vector3.one * shapeModule.radius * 2.0f); - //OnSceneViewTextureGUI (shapeModule, s_CircleMesh, true, s_TextureMaterial, textureTransform); - } - else if (type == ParticleSystemShapeType.Hemisphere) - { - // Thickness - Handles.color *= s_ShapeGizmoThicknessTint; - EditorGUI.BeginChangeCheck (); - //float radiusThickness = Handles.DoSimpleRadiusHandle (Quaternion.identity, Vector3.zero, shapeModule.radius * (1.0f - shapeModule.radiusThickness), true, shapeModule.arc); - //float radiusThickness = Call (typeof (Handles), "DoSimpleRadiusHandle", Quaternion.identity, Vector3.zero, shapeModule.radius * (1.0f - shapeModule.radiusThickness), true, shapeModule.arc); - float radiusThickness = Handles.RadiusHandle (Quaternion.identity, Vector3.zero, shapeModule.radius * (1.0f - shapeModule.radiusThickness), true); - if (EditorGUI.EndChangeCheck ()) - { - Undo.RecordObject (ps, "Hemisphere Thickness Handle Change"); - shapeModule.radiusThickness = 1.0f - (radiusThickness / shapeModule.radius); - } - - // Hemisphere - Handles.color = s_GizmoColor; - EditorGUI.BeginChangeCheck (); - //float radius = Handles.DoSimpleRadiusHandle (Quaternion.identity, Vector3.zero, shapeModule.radius, true, shapeModule.arc); - float radius = Handles.RadiusHandle (Quaternion.identity, Vector3.zero, shapeModule.radius, true); - if (EditorGUI.EndChangeCheck ()) - { - Undo.RecordObject (ps, "Hemisphere Handle Change"); - shapeModule.radius = radius; - } - - // Texture - //Matrix4x4 textureTransform = transformMatrix * Matrix4x4.TRS (Vector3.zero, Quaternion.identity, Vector3.one * shapeModule.radius * 2.0f); - //OnSceneViewTextureGUI (shapeModule, s_HemisphereMesh, false, s_SphereTextureMaterial, textureTransform); - } - else if (type == ParticleSystemShapeType.Cone) - { - // Thickness - Handles.color *= s_ShapeGizmoThicknessTint; - EditorGUI.BeginChangeCheck (); - float angleThickness = Mathf.Lerp (shapeModule.angle, 0.0f, shapeModule.radiusThickness); - Vector3 radiusThicknessAngleRange = new Vector3 (shapeModule.radius * (1.0f - shapeModule.radiusThickness), angleThickness, mainModule.startSpeedMultiplier); - //radiusThicknessAngleRange = Handles.ConeFrustrumHandle (Quaternion.identity, Vector3.zero, radiusThicknessAngleRange, Handles.ConeHandles.Radius); -#if UNITY_2018_3_OR_NEWER - radiusThicknessAngleRange = Call (typeof (Handles), "ConeFrustrumHandle", Quaternion.identity, Vector3.zero, radiusThicknessAngleRange, 1); -#else - radiusThicknessAngleRange = Call (typeof (Handles), "ConeFrustrumHandle", Quaternion.identity, Vector3.zero, radiusThicknessAngleRange); -#endif - if (EditorGUI.EndChangeCheck ()) - { - Undo.RecordObject (ps, "Cone Thickness Handle Change"); - shapeModule.radiusThickness = 1.0f - (radiusThicknessAngleRange.x / shapeModule.radius); - } - - // Cone - Handles.color = s_GizmoColor; - EditorGUI.BeginChangeCheck (); - Vector3 radiusAngleRange = new Vector3 (shapeModule.radius, shapeModule.angle, mainModule.startSpeedMultiplier); - //radiusAngleRange = Handles.ConeFrustrumHandle (Quaternion.identity, Vector3.zero, radiusAngleRange); -#if UNITY_2018_3_OR_NEWER - radiusAngleRange = Call (typeof (Handles), "ConeFrustrumHandle", Quaternion.identity, Vector3.zero, radiusAngleRange, 7); -#else - radiusAngleRange = Call (typeof (Handles), "ConeFrustrumHandle", Quaternion.identity, Vector3.zero, radiusAngleRange); -#endif - if (EditorGUI.EndChangeCheck ()) - { - Undo.RecordObject (ps, "Cone Handle Change"); - shapeModule.radius = radiusAngleRange.x; - shapeModule.angle = radiusAngleRange.y; - mainModule.startSpeedMultiplier = radiusAngleRange.z; - } - - // Texture - //Matrix4x4 textureTransform = transformMatrix * Matrix4x4.TRS (Vector3.zero, Quaternion.Euler (90.0f, 0.0f, 180.0f), Vector3.one * shapeModule.radius * 2.0f); - //OnSceneViewTextureGUI (shapeModule, s_CircleMesh, true, s_TextureMaterial, textureTransform); - } - else if (type == ParticleSystemShapeType.ConeVolume) - { - // Thickness - Handles.color *= s_ShapeGizmoThicknessTint; - EditorGUI.BeginChangeCheck (); - float angleThickness = Mathf.Lerp (shapeModule.angle, 0.0f, shapeModule.radiusThickness); - Vector3 radiusThicknessAngleLength = new Vector3 (shapeModule.radius * (1.0f - shapeModule.radiusThickness), angleThickness, shapeModule.length); - //radiusThicknessAngleLength = Handles.ConeFrustrumHandle (Quaternion.identity, Vector3.zero, radiusThicknessAngleLength, Handles.ConeHandles.Radius); -#if UNITY_2018_3_OR_NEWER - radiusThicknessAngleLength = Call (typeof (Handles), "ConeFrustrumHandle", Quaternion.identity, Vector3.zero, radiusThicknessAngleLength, 1); -#else - radiusThicknessAngleLength = Call (typeof (Handles), "ConeFrustrumHandle", Quaternion.identity, Vector3.zero, radiusThicknessAngleLength); -#endif - if (EditorGUI.EndChangeCheck ()) - { - Undo.RecordObject (ps, "Cone Volume Thickness Handle Change"); - shapeModule.radiusThickness = 1.0f - (radiusThicknessAngleLength.x / shapeModule.radius); - } - - // Cone - Handles.color = s_GizmoColor; - EditorGUI.BeginChangeCheck (); - Vector3 radiusAngleLength = new Vector3 (shapeModule.radius, shapeModule.angle, shapeModule.length); - //radiusAngleLength = Handles.ConeFrustrumHandle (Quaternion.identity, Vector3.zero, radiusAngleLength); -#if UNITY_2018_3_OR_NEWER - radiusAngleLength = Call (typeof (Handles), "ConeFrustrumHandle", Quaternion.identity, Vector3.zero, radiusAngleLength, 7); -#else - radiusAngleLength = Call (typeof (Handles), "ConeFrustrumHandle", Quaternion.identity, Vector3.zero, radiusAngleLength); -#endif - if (EditorGUI.EndChangeCheck ()) - { - Undo.RecordObject (ps, "Cone Volume Handle Change"); - shapeModule.radius = radiusAngleLength.x; - shapeModule.angle = radiusAngleLength.y; - shapeModule.length = radiusAngleLength.z; - } - - // Texture - //Matrix4x4 textureTransform = transformMatrix * Matrix4x4.TRS (Vector3.zero, Quaternion.Euler (90.0f, 0.0f, 180.0f), Vector3.one * shapeModule.radius * 2.0f); - //OnSceneViewTextureGUI (shapeModule, s_CircleMesh, true, s_TextureMaterial, textureTransform); - } - else if (type == ParticleSystemShapeType.Box || type == ParticleSystemShapeType.BoxShell || type == ParticleSystemShapeType.BoxEdge) - { - EditorGUI.BeginChangeCheck (); - - _boxBoundsHandle.center = Vector3.zero; - _boxBoundsHandle.size = shapeModule.scale; - _boxBoundsHandle.DrawHandle (); - - if (EditorGUI.EndChangeCheck ()) - { - Undo.RecordObject (ps, "Box Handle Change"); - shapeModule.scale = _boxBoundsHandle.size; - } - - //Matrix4x4 textureTransform = transformMatrix * Matrix4x4.TRS (new Vector3 (0.0f, 0.0f, -m_BoxBoundsHandle.size.z * 0.5f), Quaternion.identity, m_BoxBoundsHandle.size); - //OnSceneViewTextureGUI (shapeModule, s_QuadMesh, true, s_TextureMaterial, textureTransform); - } - else if (type == ParticleSystemShapeType.Donut) - { - // Radius - EditorGUI.BeginChangeCheck (); - - _arcHandle.radius = shapeModule.radius; - _arcHandle.angle = shapeModule.arc; - _arcHandle.SetColorWithRadiusHandle (Color.white, 0f); - _arcHandle.wireframeColor = Color.clear; - - using (new Handles.DrawingScope (Handles.matrix * s_ArcHandleOffsetMatrix)) - _arcHandle.DrawHandle (); - - if (EditorGUI.EndChangeCheck ()) - { - Undo.RecordObject (ps, "Donut Handle Change"); - shapeModule.radius = _arcHandle.radius; - shapeModule.arc = _arcHandle.angle; - } - - // Donut extents - using (new Handles.DrawingScope (Handles.matrix * s_ArcHandleOffsetMatrix)) - { - float excessAngle = shapeModule.arc % 360f; - float angle = Mathf.Abs (shapeModule.arc) >= 360f ? 360f : excessAngle; - - Handles.DrawWireArc (new Vector3 (0.0f, shapeModule.donutRadius, 0.0f), Vector3.up, Vector3.forward, angle, shapeModule.radius); - Handles.DrawWireArc (new Vector3 (0.0f, -shapeModule.donutRadius, 0.0f), Vector3.up, Vector3.forward, angle, shapeModule.radius); - Handles.DrawWireArc (Vector3.zero, Vector3.up, Vector3.forward, angle, shapeModule.radius + shapeModule.donutRadius); - Handles.DrawWireArc (Vector3.zero, Vector3.up, Vector3.forward, angle, shapeModule.radius - shapeModule.donutRadius); - - if (shapeModule.arc != 360.0f) - { - Quaternion arcRotation = Quaternion.AngleAxis (shapeModule.arc, Vector3.up); - Vector3 capCenter = arcRotation * Vector3.forward * shapeModule.radius; - Handles.DrawWireDisc (capCenter, arcRotation * Vector3.right, shapeModule.donutRadius); - } - } - - // Donut thickness - _sphereBoundsHandle.axes = PrimitiveBoundsHandle.Axes.X | PrimitiveBoundsHandle.Axes.Y; - _sphereBoundsHandle.radius = shapeModule.donutRadius * (1.0f - shapeModule.radiusThickness); - _sphereBoundsHandle.center = Vector3.zero; - _sphereBoundsHandle.SetColor (s_ShapeGizmoThicknessTint); - - const float handleInterval = 90.0f; - int numOuterRadii = Mathf.Max (1, (int)Mathf.Ceil (shapeModule.arc / handleInterval)); - Matrix4x4 donutRadiusStartMatrix = Matrix4x4.TRS (new Vector3 (shapeModule.radius, 0.0f, 0.0f), Quaternion.Euler (90.0f, 0.0f, 0.0f), Vector3.one); - - for (int i = 0; i < numOuterRadii; i++) - { - EditorGUI.BeginChangeCheck (); - using (new Handles.DrawingScope (Handles.matrix * (Matrix4x4.Rotate (Quaternion.Euler (0.0f, 0.0f, handleInterval * i)) * donutRadiusStartMatrix))) - _sphereBoundsHandle.DrawHandle (); - if (EditorGUI.EndChangeCheck ()) - { - Undo.RecordObject (ps, "Donut Radius Thickness Handle Change"); - shapeModule.radiusThickness = 1.0f - (_sphereBoundsHandle.radius / shapeModule.donutRadius); - } - } - - // Donut radius - _sphereBoundsHandle.radius = shapeModule.donutRadius; - _sphereBoundsHandle.SetColor (Color.white); - - for (int i = 0; i < numOuterRadii; i++) - { - EditorGUI.BeginChangeCheck (); - using (new Handles.DrawingScope (Handles.matrix * (Matrix4x4.Rotate (Quaternion.Euler (0.0f, 0.0f, handleInterval * i)) * donutRadiusStartMatrix))) - _sphereBoundsHandle.DrawHandle (); - if (EditorGUI.EndChangeCheck ()) - { - Undo.RecordObject (ps, "Donut Radius Handle Change"); - shapeModule.donutRadius = _sphereBoundsHandle.radius; - } - } - - // Texture - //Matrix4x4 textureTransform = transformMatrix * Matrix4x4.TRS (new Vector3 (shapeModule.radius, 0.0f, 0.0f), Quaternion.Euler (180.0f, 0.0f, 180.0f), Vector3.one * shapeModule.donutRadius * 2.0f); - //OnSceneViewTextureGUI (shapeModule, s_CircleMesh, true, s_TextureMaterial, textureTransform); - } - else if (type == ParticleSystemShapeType.SingleSidedEdge) - { - EditorGUI.BeginChangeCheck (); - //float radius = Handles.DoSimpleEdgeHandle (Quaternion.identity, Vector3.zero, shapeModule.radius); -#if UNITY_2019_1_OR_NEWER - float radius = Call (typeof (Handles), "DoSimpleEdgeHandle", Quaternion.identity, Vector3.zero, shapeModule.radius, true); -#else - float radius = Call (typeof (Handles), "DoSimpleEdgeHandle", Quaternion.identity, Vector3.zero, shapeModule.radius); -#endif - if (EditorGUI.EndChangeCheck ()) - { - Undo.RecordObject (ps, "Edge Handle Change"); - shapeModule.radius = radius; - } - } - else if (type == ParticleSystemShapeType.Mesh) - { - Mesh mesh = shapeModule.mesh; - if (mesh) - { - bool orgWireframeMode = GL.wireframe; - GL.wireframe = true; - s_Material.SetPass (0); - Graphics.DrawMeshNow (mesh, transformMatrix); - GL.wireframe = orgWireframeMode; - - //OnSceneViewTextureGUI (shapeModule, mesh, false, s_TextureMaterial, transformMatrix); - } - } - else if (type == ParticleSystemShapeType.Rectangle) - { - EditorGUI.BeginChangeCheck (); - - _boxBoundsHandle.center = Vector3.zero; - _boxBoundsHandle.size = new Vector3 (shapeModule.scale.x, shapeModule.scale.y, 0.0f); - _boxBoundsHandle.DrawHandle (); - - if (EditorGUI.EndChangeCheck ()) - { - Undo.RecordObject (ps, "Rectangle Handle Change"); - shapeModule.scale = new Vector3 (_boxBoundsHandle.size.x, _boxBoundsHandle.size.y, 0.0f); - } - - //OnSceneViewTextureGUI (shapeModule, s_QuadMesh, true, s_TextureMaterial, transformMatrix * Matrix4x4.Scale (m_BoxBoundsHandle.size)); - } - else if (type == ParticleSystemShapeType.Sprite) - { - Sprite sprite = shapeModule.sprite; - if (sprite) - { - if (!_spriteMesh) - { - _spriteMesh = new Mesh (); - _spriteMesh.name = "ParticleSpritePreview"; - _spriteMesh.hideFlags |= HideFlags.HideAndDontSave; - } - - _spriteMesh.vertices = Array.ConvertAll (sprite.vertices, i => (Vector3)i); - _spriteMesh.uv = sprite.uv; - _spriteMesh.triangles = Array.ConvertAll (sprite.triangles, i => (int)i); - - bool orgWireframeMode = GL.wireframe; - GL.wireframe = true; - s_Material.SetPass (0); - Graphics.DrawMeshNow (_spriteMesh, transformMatrix); - GL.wireframe = orgWireframeMode; - - //OnSceneViewTextureGUI (shapeModule, m_SpriteMesh, false, s_TextureMaterial, transformMatrix); - } - } - } - Handles.color = origCol; - Handles.matrix = orgMatrix; - } + void OnSceneGUI() + { + _shapeModuleUIs ??= _inspector?.m_ParticleEffectUI?.m_Emitters?.SelectMany(x => x.m_Modules).OfType()?.ToArray(); + if (_shapeModuleUIs == null) + return; + + Action postAction = () => { }; + Color origin = ShapeModuleUI.s_GizmoColor.m_Color; + Color originDark = ShapeModuleUI.s_GizmoColor.m_Color; + ShapeModuleUI.s_GizmoColor.m_Color = new Color(1f, 0.7f, 0.7f, 0.9f); + ShapeModuleUI.s_GizmoColor.m_OptionalDarkColor = new Color(1f, 0.7f, 0.7f, 0.9f); + + _particles + .Select(x => new { canvas = x.canvas, ps = x.cachedParticleSystem, scale = x.scale }) + .Where(x => x.ps && x.canvas) + .ToList() + .ForEach(x => + { + var trans = x.ps.transform; + var hasChanged = trans.hasChanged; + var localScale = trans.localScale; + postAction = () => trans.localScale = localScale; + postAction = () => trans.hasChanged = hasChanged; + trans.localScale = Vector3.Scale(localScale, x.canvas.rootCanvas.transform.localScale * x.scale); + }); + + foreach (var ui in _shapeModuleUIs) + ui.OnSceneViewGUI(); + + postAction(); + ShapeModuleUI.s_GizmoColor.m_Color = origin; + ShapeModuleUI.s_GizmoColor.m_OptionalDarkColor = originDark; + } } }