Skip to content

Commit

Permalink
feat: optimization for vertices transforms and adding node for trails
Browse files Browse the repository at this point in the history
Close #75

BREAKING CHANGE: The bake-task has changed significantly. It may look different from previous versions.
  • Loading branch information
mob-sakai committed Aug 19, 2020
1 parent 14f1c78 commit e070e8d
Show file tree
Hide file tree
Showing 4 changed files with 432 additions and 539 deletions.
120 changes: 32 additions & 88 deletions Packages/UIParticle/Scripts/Editor/UIParticleEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,28 @@
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
using System;
using ShaderPropertyType = Coffee.UIExtensions.AnimatableProperty.ShaderPropertyType;

namespace Coffee.UIExtensions
{
[CustomEditor(typeof(UIParticle))]
[CanEditMultipleObjects]
public class UIParticleEditor : GraphicEditor
internal class UIParticleEditor : GraphicEditor
{
//################################
// Constant or Static Members.
//################################
static readonly GUIContent s_ContentParticleMaterial = new GUIContent("Particle Material", "The material for rendering particles");
static readonly GUIContent s_ContentTrailMaterial = new GUIContent("Trail Material", "The material for rendering particle trails");
static readonly List<ParticleSystem> s_ParticleSystems = new List<ParticleSystem>();
static readonly Color s_GizmoColor = new Color(1f, 0.7f, 0.7f, 0.9f);

static readonly List<string> s_MaskablePropertyNames = new List<string>()
private static readonly GUIContent s_ContentParticleMaterial = new GUIContent("Particle Material", "The material for rendering particles");
private static readonly GUIContent s_ContentTrailMaterial = new GUIContent("Trail Material", "The material for rendering particle trails");
private static readonly GUIContent s_ContentAdvancedOptions = new GUIContent("Advanced Options");
private static readonly List<ParticleSystem> s_ParticleSystems = new List<ParticleSystem>();

private SerializedProperty _spParticleSystem;
private SerializedProperty _spScale3D;
private SerializedProperty _spIgnoreCanvasScaler;
private SerializedProperty _spAnimatableProperties;
private bool _xyzMode;

private static readonly List<string> s_MaskablePropertyNames = new List<string>
{
"_Stencil",
"_StencilComp",
Expand All @@ -30,6 +34,7 @@ public class UIParticleEditor : GraphicEditor
"_ColorMask",
};


//################################
// Public/Protected Members.
//################################
Expand All @@ -40,32 +45,29 @@ protected override void OnEnable()
{
base.OnEnable();
_spParticleSystem = serializedObject.FindProperty("m_ParticleSystem");
_spTrailParticle = serializedObject.FindProperty("m_TrailParticle");
_spScale = serializedObject.FindProperty("m_Scale");
_spIgnoreParent = serializedObject.FindProperty("m_IgnoreParent");
_spScale3D = serializedObject.FindProperty("m_Scale3D");
_spIgnoreCanvasScaler = serializedObject.FindProperty("m_IgnoreCanvasScaler");
_spAnimatableProperties = serializedObject.FindProperty("m_AnimatableProperties");
_particles = targets.Cast<UIParticle>().ToArray();
_shapeModuleUIs = null;

var targetsGos = targets.Cast<UIParticle>().Select(x => x.gameObject).ToArray();
_inspector = Resources.FindObjectsOfTypeAll<ParticleSystemInspector>()
.FirstOrDefault(x => x.targets.Cast<ParticleSystem>().Select(x => x.gameObject).SequenceEqual(targetsGos));
}

/// <summary>
/// Implement this function to make a custom inspector.
/// </summary>
public override void OnInspectorGUI()
{
var current = target as UIParticle;
if (current == null) return;

serializedObject.Update();

EditorGUI.BeginDisabledGroup(true);
EditorGUILayout.PropertyField(_spParticleSystem);
EditorGUI.EndDisabledGroup();

// Draw materials.
EditorGUI.indentLevel++;
var ps = _spParticleSystem.objectReferenceValue as ParticleSystem;
if (ps)
if (ps != null)
{
var pr = ps.GetComponent<ParticleSystemRenderer>();
var sp = new SerializedObject(pr).FindProperty("m_Materials");
Expand All @@ -91,22 +93,17 @@ public override void OnInspectorGUI()

EditorGUI.indentLevel--;

EditorGUI.BeginDisabledGroup(true);
EditorGUILayout.PropertyField(_spTrailParticle);
EditorGUI.EndDisabledGroup();
// Advanced Options
EditorGUILayout.Space();
EditorGUILayout.LabelField(s_ContentAdvancedOptions, EditorStyles.boldLabel);

var current = target as UIParticle;

EditorGUILayout.PropertyField(_spIgnoreParent);

EditorGUI.BeginDisabledGroup(!current.isRoot);
EditorGUILayout.PropertyField(_spScale);
EditorGUI.EndDisabledGroup();
EditorGUILayout.PropertyField(_spIgnoreCanvasScaler);

// AnimatableProperties
AnimatedPropertiesEditor.DrawAnimatableProperties(_spAnimatableProperties, current.material);

current.GetComponentsInChildren<ParticleSystem>(true, s_ParticleSystems);
// Fix
current.GetComponentsInChildren(true, s_ParticleSystems);
if (s_ParticleSystems.Any(x => x.GetComponent<UIParticle>() == null))
{
GUILayout.BeginHorizontal();
Expand All @@ -126,74 +123,21 @@ public override void OnInspectorGUI()

s_ParticleSystems.Clear();

// Does the shader support UI masks?
if (current.maskable && current.material && current.material.shader)
{
var mat = current.material;
var shader = mat.shader;
foreach (var propName in s_MaskablePropertyNames)
{
if (!mat.HasProperty(propName))
{
EditorGUILayout.HelpBox(string.Format("Shader {0} doesn't have '{1}' property. This graphic is not maskable.", shader.name, propName), MessageType.Warning);
break;
}
if (mat.HasProperty(propName)) continue;

EditorGUILayout.HelpBox(string.Format("Shader '{0}' doesn't have '{1}' property. This graphic cannot be masked.", shader.name, propName), MessageType.Warning);
break;
}
}

serializedObject.ApplyModifiedProperties();
}


//################################
// Private Members.
//################################
SerializedProperty _spParticleSystem;
SerializedProperty _spTrailParticle;
SerializedProperty _spScale;
SerializedProperty _spIgnoreParent;
SerializedProperty _spAnimatableProperties;
UIParticle[] _particles;
ShapeModuleUI[] _shapeModuleUIs;
ParticleSystemInspector _inspector;

void OnSceneGUI()
{
_shapeModuleUIs = _shapeModuleUIs ?? _inspector?.m_ParticleEffectUI?.m_Emitters?.SelectMany(x => x.m_Modules).OfType<ShapeModuleUI>()?.ToArray();
if (_shapeModuleUIs == null || _shapeModuleUIs.Length == 0 || _shapeModuleUIs[0].GetParticleSystem() != (target as UIParticle).cachedParticleSystem)
return;

Action postAction = () => { };
Color origin = ShapeModuleUI.s_GizmoColor.m_Color;
Color originDark = ShapeModuleUI.s_GizmoColor.m_Color;
ShapeModuleUI.s_GizmoColor.m_Color = s_GizmoColor;
ShapeModuleUI.s_GizmoColor.m_OptionalDarkColor = s_GizmoColor;

_particles
.Distinct()
.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;
trans.localScale = Vector3.Scale(localScale, x.canvas.rootCanvas.transform.localScale * x.scale);
});

try
{
foreach (var ui in _shapeModuleUIs)
ui.OnSceneViewGUI();
}
catch
{
}

postAction();
ShapeModuleUI.s_GizmoColor.m_Color = origin;
ShapeModuleUI.s_GizmoColor.m_OptionalDarkColor = originDark;
}
}
}
Loading

0 comments on commit e070e8d

Please sign in to comment.