diff --git a/.releaserc b/.releaserc
deleted file mode 100644
index e69de29..0000000
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a3cab20..303b7cf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,17 @@
+# [3.0.0-preview.38](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v3.0.0-preview.37...v3.0.0-preview.38) (2020-10-04)
+
+
+### Bug Fixes
+
+* delete unused file in package ([2e69974](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/2e699749a8f0f620505621a13a628aa87f192875))
+* material dirty on validate (on editor) ([fa34301](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/fa3430130cdffa3f934e926645958ad9f19edc5d))
+
+
+### Features
+
+* display material properties in inspector ([313c1fc](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/313c1fc159429034f84b2e7c30424158c43b71e9)), closes [#104](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/104)
+* support 3D scaling ([a508c3b](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/a508c3bb86ad6694722868303385b20adc914134)), closes [#105](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/105)
+
# [3.0.0-preview.37](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v3.0.0-preview.36...v3.0.0-preview.37) (2020-10-01)
diff --git a/README.md b/README.md
index 1df8db4..e659cdf 100644
--- a/README.md
+++ b/README.md
@@ -121,7 +121,8 @@ Unity 2018.2 supports embedded packages.
1. Open `Package Manager` window
2. Select `UI Particle` package in package list
-3. Click `Import Sample` button
+3. Click `Import Sample` button
+
4. The demo project is imported into `Assets/Samples/UI Particle/{version}/Demo`
5. Open `UIParticle_Demo` scene and play it
@@ -137,22 +138,58 @@ Unity 2018.2 supports embedded packages.
## Usage
+### UIParticle component
+
+`UIParticle` controls the ParticleSystems that is attached to its own game objects and child game objects.
+
+| Properties | Screenshot |
+| -- | -- |
+| **Ignore Canvas Scale:** Ignore the scale of the root canvas. This prevents it from displaying small even in hierarchy scaling mode of ParticleSystem.
**Scale:** Scale the rendering. When the `3D` toggle is enabled, 3D scale (x,y,z) is supported.
**AnimatableProperties:** If you want update material properties (e.g. `_MainTex_ST`, `_Color`) in AnimationClip, use this to mark the changes.
**Rendering Order:** The ParticleSystems to be rendered. You can change the rendering order and the materials. | ![][inspector] |
+
+[inspector]:https://user-images.githubusercontent.com/12690315/95017219-1cea2c00-0693-11eb-9490-c52b8d0fdbb6.png
+
+NOTE: Press `Refresh` button to reconstruct rendering order based on children ParticleSystem's sorting order and z position.
+
+
+
### Basically usage
-1. Select `Game Object/UI/ParticleSystem` to create UIParticle.
-2. (Option) If you want to mask particles, set **a UI shader** such as `UI/UIAdditive` to material for ParticleSystem.
-
-3. Adjust the Scale property to change the size of the effect.
-
+1. Select `Game Object/UI/ParticleSystem` to create UIParticle with a ParticleSystem.
+
+2. Adjust the ParticleSystem as you like.
+
-### With VFX assets
+
-1. Select `Game Object/UI/ParticleSystem (Empty)` to create UIParticle.
-2. Drag & drop VFX asset on UIParticle.
-3. Click `Refresh` to setup.
-4. Adjust the Scale property to change the size of the effect.
+### With your ParticleSystem prefab
+
+1. Select `Game Object/UI/ParticleSystem (Empty)` to create UIParticle.
+
+2. Drag & drop your ParticleSystem prefab on UIParticle.
+
+
+
+
+### With `Mask` or `MaskRect2D` component
+
+If you want to mask particles, set a stencil supported shader (such as `UI/UIAdditive`) to material for ParticleSystem.
+
+
+
+
+### Script usage
+
+```cs
+// Instant ParticleSystem prefab with UIParticle on runtime.
+var go = GameObject.Instantiate(prefab);
+var uiParticle = go.AddComponent();
+
+// Play/Stop the controled ParticleSystems.
+uiParticle.Play();
+uiParticle.Stop();
+```
@@ -224,5 +261,4 @@ With your support, I can spend more time on development. :)
* GitHub page : https://github.com/mob-sakai/ParticleEffectForUGUI
* Releases : https://github.com/mob-sakai/ParticleEffectForUGUI/releases
* Issue tracker : https://github.com/mob-sakai/ParticleEffectForUGUI/issues
-* Current project : https://github.com/mob-sakai/ParticleEffectForUGUI/projects/1
* Change log : https://github.com/mob-sakai/ParticleEffectForUGUI/blob/upm/CHANGELOG.md
diff --git a/Scripts/Editor/UIParticleEditor.cs b/Scripts/Editor/UIParticleEditor.cs
index 5f41458..cc4ce86 100644
--- a/Scripts/Editor/UIParticleEditor.cs
+++ b/Scripts/Editor/UIParticleEditor.cs
@@ -18,6 +18,10 @@ namespace Coffee.UIExtensions
private static readonly GUIContent s_ContentRenderingOrder = new GUIContent("Rendering Order");
private static readonly GUIContent s_ContentRefresh = new GUIContent("Refresh");
private static readonly GUIContent s_ContentFix = new GUIContent("Fix");
+ private static readonly GUIContent s_ContentMaterial = new GUIContent("Material");
+ private static readonly GUIContent s_ContentTrailMaterial = new GUIContent("Trail Material");
+ private static readonly GUIContent s_Content3D = new GUIContent("3D");
+ private static readonly GUIContent s_ContentScale = new GUIContent("Scale");
private static readonly List s_TempParents = new List();
private static readonly List s_TempChildren = new List();
@@ -26,6 +30,7 @@ namespace Coffee.UIExtensions
private SerializedProperty _spAnimatableProperties;
private ReorderableList _ro;
+ private bool _xyzMode;
private static readonly List s_MaskablePropertyNames = new List
{
@@ -47,24 +52,48 @@ namespace Coffee.UIExtensions
protected override void OnEnable()
{
base.OnEnable();
- _spScale = serializedObject.FindProperty("m_Scale");
+ _spScale = serializedObject.FindProperty("m_Scale3D");
_spIgnoreCanvasScaler = serializedObject.FindProperty("m_IgnoreCanvasScaler");
_spAnimatableProperties = serializedObject.FindProperty("m_AnimatableProperties");
var sp = serializedObject.FindProperty("m_Particles");
- _ro = new ReorderableList(sp.serializedObject, sp, true, true, false, false);
- _ro.elementHeight = EditorGUIUtility.singleLineHeight + 4;
+ _ro = new ReorderableList(sp.serializedObject, sp, true, true, true, true);
+ _ro.elementHeight = EditorGUIUtility.singleLineHeight * 3 + 4;
_ro.drawElementCallback = (rect, index, active, focused) =>
{
+ EditorGUI.BeginDisabledGroup(sp.hasMultipleDifferentValues);
rect.y += 1;
rect.height = EditorGUIUtility.singleLineHeight;
- EditorGUI.ObjectField(rect, sp.GetArrayElementAtIndex(index), GUIContent.none);
+ var p = sp.GetArrayElementAtIndex(index);
+ EditorGUI.ObjectField(rect, p, GUIContent.none);
+
+ rect.x += 15;
+ rect.width -= 15;
+ var ps = p.objectReferenceValue as ParticleSystem;
+ var materials = ps
+ ? new SerializedObject(ps.GetComponent()).FindProperty("m_Materials")
+ : null;
+ rect.y += rect.height + 1;
+ MaterialField(rect, s_ContentMaterial, materials, 0);
+ rect.y += rect.height + 1;
+ MaterialField(rect, s_ContentTrailMaterial, materials, 1);
+ EditorGUI.EndDisabledGroup();
+ if (materials != null)
+ {
+ materials.serializedObject.ApplyModifiedProperties();
+ }
};
_ro.drawHeaderCallback += rect =>
{
EditorGUI.LabelField(new Rect(rect.x, rect.y, 150, rect.height), s_ContentRenderingOrder);
- if (GUI.Button(new Rect(rect.width - 80, rect.y - 1, 80, rect.height), s_ContentRefresh, EditorStyles.miniButton))
+ #if UNITY_2019_3_OR_NEWER
+ rect = new Rect(rect.width - 55, rect.y, 80, rect.height);
+ #else
+ rect = new Rect(rect.width - 55, rect.y - 1, 80, rect.height);
+ #endif
+
+ if (GUI.Button(rect, s_ContentRefresh, EditorStyles.miniButton))
{
foreach (UIParticle t in targets)
{
@@ -74,6 +103,20 @@ namespace Coffee.UIExtensions
};
}
+ private static void MaterialField(Rect rect, GUIContent label, SerializedProperty sp, int index)
+ {
+ if (sp == null || sp.arraySize <= index)
+ {
+ EditorGUI.BeginDisabledGroup(true);
+ EditorGUI.ObjectField(rect, label, null, typeof(Material), true);
+ EditorGUI.EndDisabledGroup();
+ }
+ else
+ {
+ EditorGUI.PropertyField(rect, sp.GetArrayElementAtIndex(index), label);
+ }
+ }
+
///
/// Implement this function to make a custom inspector.
///
@@ -98,7 +141,7 @@ namespace Coffee.UIExtensions
}
// Scale
- EditorGUILayout.PropertyField(_spScale);
+ _xyzMode = DrawFloatOrVector3Field(_spScale, _xyzMode);
// AnimatableProperties
var mats = current.particles
@@ -106,8 +149,17 @@ namespace Coffee.UIExtensions
.Select(x => x.GetComponent().sharedMaterial)
.Where(x => x)
.ToArray();
- AnimatedPropertiesEditor.DrawAnimatableProperties(_spAnimatableProperties, mats);
+ // Animated properties
+ EditorGUI.BeginChangeCheck();
+ AnimatedPropertiesEditor.DrawAnimatableProperties(_spAnimatableProperties, mats);
+ if (EditorGUI.EndChangeCheck())
+ {
+ foreach (UIParticle t in targets)
+ t.SetMaterialDirty();
+ }
+
+ // Target ParticleSystems.
_ro.DoLayoutList();
serializedObject.ApplyModifiedProperties();
@@ -180,5 +232,42 @@ namespace Coffee.UIExtensions
}
}
}
+
+ private static bool DrawFloatOrVector3Field(SerializedProperty sp, bool showXyz)
+ {
+ var x = sp.FindPropertyRelative("x");
+ var y = sp.FindPropertyRelative("y");
+ var z = sp.FindPropertyRelative("z");
+
+ showXyz |= !Mathf.Approximately(x.floatValue, y.floatValue) ||
+ !Mathf.Approximately(y.floatValue, z.floatValue) ||
+ y.hasMultipleDifferentValues ||
+ z.hasMultipleDifferentValues;
+
+ EditorGUILayout.BeginHorizontal();
+ if (showXyz)
+ {
+ EditorGUILayout.PropertyField(sp);
+ }
+ else
+ {
+ EditorGUI.BeginChangeCheck();
+ EditorGUILayout.PropertyField(x, s_ContentScale);
+ if (EditorGUI.EndChangeCheck())
+ z.floatValue = y.floatValue = x.floatValue;
+ }
+
+ x.floatValue = Mathf.Max(0.001f, x.floatValue);
+ y.floatValue = Mathf.Max(0.001f, y.floatValue);
+ z.floatValue = Mathf.Max(0.001f, z.floatValue);
+
+ EditorGUI.BeginChangeCheck();
+ showXyz = GUILayout.Toggle(showXyz, s_Content3D, EditorStyles.miniButton, GUILayout.Width(30));
+ if (EditorGUI.EndChangeCheck() && !showXyz)
+ z.floatValue = y.floatValue = x.floatValue;
+ EditorGUILayout.EndHorizontal();
+
+ return showXyz;
+ }
}
}
diff --git a/Scripts/UIParticle.cs b/Scripts/UIParticle.cs
index 04db9ca..995166f 100755
--- a/Scripts/UIParticle.cs
+++ b/Scripts/UIParticle.cs
@@ -30,6 +30,9 @@ namespace Coffee.UIExtensions
[Tooltip("Particle effect scale")] [SerializeField]
float m_Scale = 100;
+ [Tooltip("Particle effect scale")] [SerializeField]
+ private Vector3 m_Scale3D;
+
[Tooltip("Animatable material properties. If you want to change the material properties of the ParticleSystem in Animation, enable it.")] [SerializeField]
internal AnimatableProperty[] m_AnimatableProperties = new AnimatableProperty[0];
@@ -74,8 +77,27 @@ namespace Coffee.UIExtensions
///
public float scale
{
- get { return m_Scale; }
- set { m_Scale = Mathf.Max(0.001f, value); }
+ get { return m_Scale3D.x; }
+ set
+ {
+ m_Scale = Mathf.Max(0.001f, value);
+ m_Scale3D = new Vector3(m_Scale, m_Scale, m_Scale);
+ }
+ }
+
+ ///
+ /// Particle effect scale.
+ ///
+ public Vector3 scale3D
+ {
+ get { return m_Scale3D; }
+ set
+ {
+ if (m_Scale3D == value) return;
+ m_Scale3D.x = Mathf.Max(0.001f, value.x);
+ m_Scale3D.y = Mathf.Max(0.001f, value.y);
+ m_Scale3D.z = Mathf.Max(0.001f, value.z);
+ }
}
internal Mesh bakedMesh
@@ -410,6 +432,14 @@ namespace Coffee.UIExtensions
}
#if UNITY_EDITOR
+ protected override void OnValidate()
+ {
+ SetLayoutDirty();
+ SetVerticesDirty();
+ m_ShouldRecalculateStencil = true;
+ RecalculateClipping();
+ }
+
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
if (Application.isPlaying) return;
@@ -418,6 +448,11 @@ namespace Coffee.UIExtensions
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
+ if (m_Scale3D == Vector3.zero)
+ {
+ scale = m_Scale;
+ }
+
UnityEditor.EditorApplication.delayCall += () =>
{
if (Application.isPlaying || !this) return;
diff --git a/Scripts/UIParticleUpdater.cs b/Scripts/UIParticleUpdater.cs
index 6eee462..3fc0391 100755
--- a/Scripts/UIParticleUpdater.cs
+++ b/Scripts/UIParticleUpdater.cs
@@ -138,13 +138,17 @@ namespace Coffee.UIExtensions
var rootMatrix = Matrix4x4.Rotate(root.rotation).inverse
* Matrix4x4.Scale(root.lossyScale).inverse;
var scale = particle.ignoreCanvasScaler
- ? particle.canvas.rootCanvas.transform.localScale.x * particle.scale
- : particle.scale;
- var scaleMatrix = Matrix4x4.Scale(scale * Vector3.one);
+ ? Vector3.Scale( particle.canvas.rootCanvas.transform.localScale, particle.scale3D)
+ : particle.scale3D;
+ var scaleMatrix = Matrix4x4.Scale(scale);
// Cache position
var position = particle.transform.position;
- var diff = (position - particle.cachedPosition) * (1 - 1 / scale);
+ var diff = position - particle.cachedPosition;
+ diff.x *= 1f - 1f / Mathf.Max(0.001f, scale.x);
+ diff.y *= 1f - 1f / Mathf.Max(0.001f, scale.y);
+ diff.z *= 1f - 1f / Mathf.Max(0.001f, scale.z);
+
particle.cachedPosition = position;
for (var i = 0; i < particle.particles.Count; i++)
diff --git a/package.json b/package.json
index f9445e1..df38495 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "com.coffee.ui-particle",
"displayName": "UI Particle",
"description": "This plugin provide a component to render particle effect for uGUI.\nThe particle rendering is maskable and sortable, without Camera, RenderTexture or Canvas.",
- "version": "3.0.0-preview.37",
+ "version": "3.0.0-preview.38",
"unity": "2018.2",
"license": "MIT",
"repository": {