You've already forked ParticleEffectForUGUI
mirror of
https://github.com/mob-sakai/ParticleEffectForUGUI.git
synced 2026-05-14 20:20:06 +00:00
3.0.0-preview.18
# [3.0.0-preview.18](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v3.0.0-preview.17...v3.0.0-preview.18) (2020-08-19) ### Bug Fixes * AsmdefEx is no longer required ([50e749c](50e749c183)) * fix camera for baking mesh ([6395a4f](6395a4fa74)) * support .Net Framework 3.5 (again) ([23fcb06](23fcb06bf9)) ### Features * 3.0.0 updater ([f99292b](f99292b9a1)) * add menu to create UIParticle ([14f1c78](14f1c782ff)) * Combine baked meshes to improve performance ([633d058](633d058756)) * improve performance ([77c056a](77c056ad5f)) * optimization for vertices transforms and adding node for trails ([e070e8d](e070e8d5ee)), closes [#75](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/75) * option to ignoring canvas scaling ([fe85fed](fe85fed3c0)) * support 3d scaling ([42a84bc](42a84bc5e1)) * support custom simulation space ([a83e647](a83e64761c)), closes [#78](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/78) * support for particle systems including trail only ([f389d39](f389d39953)), closes [#61](https://github.com/mob-sakai/ParticleEffectForUGUI/issues/61) ### BREAKING CHANGES * The bake-task has changed significantly. It may look different from previous versions.
This commit is contained in:
@@ -1,12 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Profiling;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.UI;
|
||||
using ShaderPropertyType = Coffee.UIExtensions.UIParticle.AnimatableProperty.ShaderPropertyType;
|
||||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using System.Reflection;
|
||||
#endif
|
||||
|
||||
namespace Coffee.UIExtensions
|
||||
{
|
||||
@@ -17,16 +11,6 @@ namespace Coffee.UIExtensions
|
||||
[RequireComponent(typeof(CanvasRenderer))]
|
||||
public class UIParticle : MaskableGraphic
|
||||
{
|
||||
//################################
|
||||
// Constant or Readonly Static Members.
|
||||
//################################
|
||||
static readonly int s_IdMainTex = Shader.PropertyToID("_MainTex");
|
||||
static readonly List<Vector3> s_Vertices = new List<Vector3>();
|
||||
static readonly List<Color32> s_Colors = new List<Color32>();
|
||||
static readonly List<UIParticle> s_TempRelatables = new List<UIParticle>();
|
||||
static readonly List<UIParticle> s_ActiveParticles = new List<UIParticle>();
|
||||
|
||||
|
||||
//################################
|
||||
// Serialize Members.
|
||||
//################################
|
||||
@@ -34,153 +18,36 @@ namespace Coffee.UIExtensions
|
||||
ParticleSystem m_ParticleSystem;
|
||||
|
||||
[Tooltip("The UIParticle to render trail effect")] [SerializeField]
|
||||
UIParticle m_TrailParticle;
|
||||
internal UIParticle m_TrailParticle;
|
||||
|
||||
[HideInInspector] [SerializeField] bool m_IsTrail = false;
|
||||
|
||||
[Tooltip("Particle effect scale")] [SerializeField]
|
||||
float m_Scale = 1;
|
||||
[Tooltip("Ignore canvas scaler")] [SerializeField]
|
||||
bool m_IgnoreCanvasScaler = false;
|
||||
|
||||
[Tooltip("Ignore parent scale")] [SerializeField]
|
||||
bool m_IgnoreParent = false;
|
||||
|
||||
[Tooltip("Animatable material properties. AnimationでParticleSystemのマテリアルプロパティを変更する場合、有効にしてください。")] [SerializeField]
|
||||
AnimatableProperty[] m_AnimatableProperties = new AnimatableProperty[0];
|
||||
[Tooltip("Particle effect scale")] [SerializeField]
|
||||
float m_Scale = 0;
|
||||
|
||||
static MaterialPropertyBlock s_Mpb;
|
||||
[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];
|
||||
|
||||
[System.Serializable]
|
||||
public class AnimatableProperty : ISerializationCallbackReceiver
|
||||
{
|
||||
public enum ShaderPropertyType
|
||||
{
|
||||
Color,
|
||||
Vector,
|
||||
Float,
|
||||
Range,
|
||||
Texture,
|
||||
};
|
||||
|
||||
[SerializeField] string m_Name = "";
|
||||
[SerializeField] ShaderPropertyType m_Type = ShaderPropertyType.Vector;
|
||||
public int id { get; private set; }
|
||||
|
||||
public ShaderPropertyType type
|
||||
{
|
||||
get { return m_Type; }
|
||||
}
|
||||
|
||||
|
||||
public void OnBeforeSerialize()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnAfterDeserialize()
|
||||
{
|
||||
id = Shader.PropertyToID(m_Name);
|
||||
}
|
||||
}
|
||||
[Tooltip("Particle effect scale")] [SerializeField]
|
||||
internal Vector3 m_Scale3D = Vector3.one;
|
||||
|
||||
private readonly Material[] _maskMaterials = new Material[2];
|
||||
private DrivenRectTransformTracker _tracker;
|
||||
private Mesh _bakedMesh;
|
||||
private ParticleSystemRenderer _renderer;
|
||||
private int _cachedSharedMaterialId;
|
||||
private int _cachedTrailMaterialId;
|
||||
private bool _cachedSpritesModeAndHasTrail;
|
||||
|
||||
//################################
|
||||
// Public/Protected Members.
|
||||
//################################
|
||||
public override Texture mainTexture
|
||||
{
|
||||
get
|
||||
{
|
||||
Texture tex = null;
|
||||
if (!m_IsTrail && cachedParticleSystem)
|
||||
{
|
||||
Profiler.BeginSample("Check TextureSheetAnimation module");
|
||||
var textureSheet = cachedParticleSystem.textureSheetAnimation;
|
||||
if (textureSheet.enabled && textureSheet.mode == ParticleSystemAnimationMode.Sprites && 0 < textureSheet.spriteCount)
|
||||
{
|
||||
tex = GetActualTexture(textureSheet.GetSprite(0));
|
||||
}
|
||||
|
||||
Profiler.EndSample();
|
||||
}
|
||||
|
||||
if (!tex && _renderer)
|
||||
{
|
||||
Profiler.BeginSample("Check material");
|
||||
var mat = material;
|
||||
if (mat && mat.HasProperty(s_IdMainTex))
|
||||
{
|
||||
tex = mat.mainTexture;
|
||||
}
|
||||
|
||||
Profiler.EndSample();
|
||||
}
|
||||
|
||||
return tex ?? s_WhiteTexture;
|
||||
}
|
||||
}
|
||||
|
||||
public override Material material
|
||||
{
|
||||
get
|
||||
{
|
||||
return _renderer
|
||||
? m_IsTrail
|
||||
? _renderer.trailMaterial
|
||||
: _renderer.sharedMaterial
|
||||
: null;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (!_renderer)
|
||||
{
|
||||
}
|
||||
else if (m_IsTrail && _renderer.trailMaterial != value)
|
||||
{
|
||||
_renderer.trailMaterial = value;
|
||||
SetMaterialDirty();
|
||||
}
|
||||
else if (!m_IsTrail && _renderer.sharedMaterial != value)
|
||||
{
|
||||
_renderer.sharedMaterial = value;
|
||||
SetMaterialDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Particle effect scale.
|
||||
/// </summary>
|
||||
public float scale
|
||||
{
|
||||
get { return _parent ? _parent.scale : m_Scale; }
|
||||
set { m_Scale = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Should the soft mask ignore parent soft masks?
|
||||
/// </summary>
|
||||
/// <value>If set to true the soft mask will ignore any parent soft mask settings.</value>
|
||||
public bool ignoreParent
|
||||
{
|
||||
get { return m_IgnoreParent; }
|
||||
set
|
||||
{
|
||||
if (m_IgnoreParent != value)
|
||||
{
|
||||
m_IgnoreParent = value;
|
||||
OnTransformParentChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is this the root UIParticle?
|
||||
/// </summary>
|
||||
public bool isRoot
|
||||
{
|
||||
get { return !_parent; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Should this graphic be considered a target for raycasting?
|
||||
/// </summary>
|
||||
@@ -191,7 +58,7 @@ namespace Coffee.UIExtensions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ParticleSystem.
|
||||
/// Cached ParticleSystem.
|
||||
/// </summary>
|
||||
public ParticleSystem cachedParticleSystem
|
||||
{
|
||||
@@ -199,21 +66,134 @@ namespace Coffee.UIExtensions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Perform material modification in this function.
|
||||
/// Cached ParticleSystem.
|
||||
/// </summary>
|
||||
/// <returns>Modified material.</returns>
|
||||
/// <param name="baseMaterial">Configured Material.</param>
|
||||
public override Material GetModifiedMaterial(Material baseMaterial)
|
||||
internal ParticleSystemRenderer cachedRenderer
|
||||
{
|
||||
Material mat = null;
|
||||
if (!_renderer)
|
||||
mat = baseMaterial;
|
||||
else if (m_AnimatableProperties.Length == 0)
|
||||
mat = _renderer.sharedMaterial;
|
||||
else
|
||||
mat = new Material(material);
|
||||
get { return _renderer; }
|
||||
}
|
||||
|
||||
return base.GetModifiedMaterial(mat);
|
||||
public bool ignoreCanvasScaler
|
||||
{
|
||||
get { return m_IgnoreCanvasScaler; }
|
||||
set { m_IgnoreCanvasScaler = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Particle effect scale.
|
||||
/// </summary>
|
||||
public float scale
|
||||
{
|
||||
get { return m_Scale3D.x; }
|
||||
set { m_Scale3D.Set(value, value, value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Particle effect scale.
|
||||
/// </summary>
|
||||
public Vector3 scale3D
|
||||
{
|
||||
get { return m_Scale3D; }
|
||||
set { m_Scale3D = value; }
|
||||
}
|
||||
|
||||
internal bool isTrailParticle
|
||||
{
|
||||
get { return m_IsTrail; }
|
||||
}
|
||||
|
||||
internal bool isSpritesMode
|
||||
{
|
||||
get { return textureSheetAnimationModule.enabled && textureSheetAnimationModule.mode == ParticleSystemAnimationMode.Sprites; }
|
||||
}
|
||||
|
||||
private bool isSpritesModeAndHasTrail
|
||||
{
|
||||
get { return isSpritesMode && trailModule.enabled; }
|
||||
}
|
||||
|
||||
private ParticleSystem.TextureSheetAnimationModule textureSheetAnimationModule
|
||||
{
|
||||
get { return cachedParticleSystem.textureSheetAnimation; }
|
||||
}
|
||||
|
||||
internal ParticleSystem.TrailModule trailModule
|
||||
{
|
||||
get { return cachedParticleSystem.trails; }
|
||||
}
|
||||
|
||||
internal ParticleSystem.MainModule mainModule
|
||||
{
|
||||
get { return cachedParticleSystem.main; }
|
||||
}
|
||||
|
||||
public bool isValid
|
||||
{
|
||||
get { return m_ParticleSystem && _renderer && canvas; }
|
||||
}
|
||||
|
||||
public Mesh bakedMesh
|
||||
{
|
||||
get { return _bakedMesh; }
|
||||
}
|
||||
|
||||
protected override void UpdateMaterial()
|
||||
{
|
||||
if (!_renderer) return;
|
||||
|
||||
if (!isSpritesMode) // Non sprite mode: canvas renderer has main and trail materials.
|
||||
{
|
||||
canvasRenderer.materialCount = trailModule.enabled ? 2 : 1;
|
||||
canvasRenderer.SetMaterial(GetModifiedMaterial(_renderer.sharedMaterial, 0), 0);
|
||||
if (trailModule.enabled)
|
||||
canvasRenderer.SetMaterial(GetModifiedMaterial(_renderer.trailMaterial, 1), 1);
|
||||
}
|
||||
else if (isTrailParticle) // Sprite mode (Trail): canvas renderer has trail material.
|
||||
{
|
||||
canvasRenderer.materialCount = 1;
|
||||
canvasRenderer.SetMaterial(GetModifiedMaterial(_renderer.trailMaterial, 0), 0);
|
||||
}
|
||||
else // Sprite mode (Main): canvas renderer has main material.
|
||||
{
|
||||
canvasRenderer.materialCount = 1;
|
||||
canvasRenderer.SetMaterial(GetModifiedMaterial(_renderer.sharedMaterial, 0), 0);
|
||||
}
|
||||
}
|
||||
|
||||
private Material GetModifiedMaterial(Material baseMaterial, int index)
|
||||
{
|
||||
if (!baseMaterial || 1 < index || !isActiveAndEnabled) return null;
|
||||
|
||||
var hasAnimatableProperties = 0 < m_AnimatableProperties.Length && index == 0;
|
||||
if (hasAnimatableProperties || isTrailParticle)
|
||||
baseMaterial = new Material(baseMaterial);
|
||||
|
||||
var baseMat = baseMaterial;
|
||||
if (m_ShouldRecalculateStencil)
|
||||
{
|
||||
m_ShouldRecalculateStencil = false;
|
||||
|
||||
if (maskable)
|
||||
{
|
||||
var sortOverrideCanvas = MaskUtilities.FindRootSortOverrideCanvas(transform);
|
||||
m_StencilValue = MaskUtilities.GetStencilDepth(transform, sortOverrideCanvas) + index;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_StencilValue = 0;
|
||||
}
|
||||
}
|
||||
|
||||
var component = GetComponent<Mask>();
|
||||
if (m_StencilValue <= 0 || (component != null && component.IsActive())) return baseMat;
|
||||
|
||||
var stencilId = (1 << m_StencilValue) - 1;
|
||||
var maskMaterial = StencilMaterial.Add(baseMat, stencilId, StencilOp.Keep, CompareFunction.Equal, ColorWriteMask.All, stencilId, 0);
|
||||
StencilMaterial.Remove(_maskMaterials[index]);
|
||||
_maskMaterials[index] = maskMaterial;
|
||||
baseMat = _maskMaterials[index];
|
||||
|
||||
return baseMat;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -221,41 +201,24 @@ namespace Coffee.UIExtensions
|
||||
/// </summary>
|
||||
protected override void OnEnable()
|
||||
{
|
||||
// Register.
|
||||
if (s_ActiveParticles.Count == 0)
|
||||
{
|
||||
Canvas.willRenderCanvases += UpdateMeshes;
|
||||
s_Mpb = new MaterialPropertyBlock();
|
||||
}
|
||||
UpdateVersionIfNeeded();
|
||||
|
||||
s_ActiveParticles.Add(this);
|
||||
|
||||
// Reset the parent-child relation.
|
||||
GetComponentsInChildren<UIParticle>(false, s_TempRelatables);
|
||||
for (int i = s_TempRelatables.Count - 1; 0 <= i; i--)
|
||||
{
|
||||
s_TempRelatables[i].OnTransformParentChanged();
|
||||
}
|
||||
|
||||
s_TempRelatables.Clear();
|
||||
_tracker.Add(this, rectTransform, DrivenTransformProperties.Scale);
|
||||
|
||||
// Initialize.
|
||||
_renderer = cachedParticleSystem ? cachedParticleSystem.GetComponent<ParticleSystemRenderer>() : null;
|
||||
if (_renderer && Application.isPlaying)
|
||||
{
|
||||
if (_renderer != null)
|
||||
_renderer.enabled = false;
|
||||
}
|
||||
|
||||
CheckMaterials();
|
||||
|
||||
// Create objects.
|
||||
_mesh = new Mesh();
|
||||
_mesh.MarkDynamic();
|
||||
CheckTrail();
|
||||
_bakedMesh = new Mesh();
|
||||
_bakedMesh.MarkDynamic();
|
||||
|
||||
if (cachedParticleSystem)
|
||||
{
|
||||
_oldPos = cachedParticleSystem.main.scalingMode == ParticleSystemScalingMode.Local
|
||||
? rectTransform.localPosition
|
||||
: rectTransform.position;
|
||||
}
|
||||
MeshHelper.Register();
|
||||
BakingCamera.Register();
|
||||
UIParticleUpdater.Register(this);
|
||||
|
||||
base.OnEnable();
|
||||
}
|
||||
@@ -265,46 +228,28 @@ namespace Coffee.UIExtensions
|
||||
/// </summary>
|
||||
protected override void OnDisable()
|
||||
{
|
||||
// Unregister.
|
||||
s_ActiveParticles.Remove(this);
|
||||
if (s_ActiveParticles.Count == 0)
|
||||
_tracker.Clear();
|
||||
|
||||
// Destroy object.
|
||||
DestroyImmediate(_bakedMesh);
|
||||
_bakedMesh = null;
|
||||
|
||||
MeshHelper.Unregister();
|
||||
BakingCamera.Unregister();
|
||||
UIParticleUpdater.Unregister(this);
|
||||
|
||||
CheckMaterials();
|
||||
|
||||
// Remove mask materials.
|
||||
for (var i = 0; i < _maskMaterials.Length; i++)
|
||||
{
|
||||
Canvas.willRenderCanvases -= UpdateMeshes;
|
||||
StencilMaterial.Remove(_maskMaterials[i]);
|
||||
_maskMaterials[i] = null;
|
||||
}
|
||||
|
||||
// Reset the parent-child relation.
|
||||
for (int i = _children.Count - 1; 0 <= i; i--)
|
||||
{
|
||||
_children[i].SetParent(_parent);
|
||||
}
|
||||
|
||||
_children.Clear();
|
||||
SetParent(null);
|
||||
|
||||
// Destroy objects.
|
||||
DestroyImmediate(_mesh);
|
||||
_mesh = null;
|
||||
CheckTrail();
|
||||
|
||||
base.OnDisable();
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>
|
||||
/// Reset to default values.
|
||||
/// </summary>
|
||||
protected override void Reset()
|
||||
{
|
||||
// Disable ParticleSystemRenderer on reset.
|
||||
if (cachedParticleSystem)
|
||||
{
|
||||
cachedParticleSystem.GetComponent<ParticleSystemRenderer>().enabled = false;
|
||||
}
|
||||
|
||||
base.Reset();
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Call to update the geometry of the Graphic onto the CanvasRenderer.
|
||||
/// </summary>
|
||||
@@ -317,20 +262,6 @@ namespace Coffee.UIExtensions
|
||||
/// </summary>
|
||||
protected override void OnTransformParentChanged()
|
||||
{
|
||||
UIParticle newParent = null;
|
||||
if (isActiveAndEnabled && !m_IgnoreParent)
|
||||
{
|
||||
var parentTransform = transform.parent;
|
||||
while (parentTransform && (!newParent || !newParent.enabled))
|
||||
{
|
||||
newParent = parentTransform.GetComponent<UIParticle>();
|
||||
parentTransform = parentTransform.parent;
|
||||
}
|
||||
}
|
||||
|
||||
SetParent(newParent);
|
||||
|
||||
base.OnTransformParentChanged();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -340,327 +271,75 @@ namespace Coffee.UIExtensions
|
||||
{
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>
|
||||
/// This function is called when the script is loaded or a value is changed in the inspector(Called in the editor only).
|
||||
/// </summary>
|
||||
protected override void OnValidate()
|
||||
{
|
||||
OnTransformParentChanged();
|
||||
base.OnValidate();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//################################
|
||||
// Private Members.
|
||||
//################################
|
||||
Mesh _mesh;
|
||||
ParticleSystemRenderer _renderer;
|
||||
UIParticle _parent;
|
||||
List<UIParticle> _children = new List<UIParticle>();
|
||||
Matrix4x4 scaleaMatrix = default(Matrix4x4);
|
||||
Vector3 _oldPos;
|
||||
static readonly Vector3 minimumVec3 = new Vector3(0.0000001f, 0.0000001f, 0.0000001f);
|
||||
static ParticleSystem.Particle[] s_Particles = new ParticleSystem.Particle[4096];
|
||||
|
||||
/// <summary>
|
||||
/// Update meshes.
|
||||
/// </summary>
|
||||
static void UpdateMeshes()
|
||||
private static bool HasMaterialChanged(Material material, ref int current)
|
||||
{
|
||||
for (int i = 0; i < s_ActiveParticles.Count; i++)
|
||||
{
|
||||
if (s_ActiveParticles[i])
|
||||
{
|
||||
s_ActiveParticles[i].UpdateMesh();
|
||||
}
|
||||
}
|
||||
var old = current;
|
||||
current = material ? material.GetInstanceID() : 0;
|
||||
return current != old;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update meshe.
|
||||
/// </summary>
|
||||
void UpdateMesh()
|
||||
internal void UpdateTrailParticle()
|
||||
{
|
||||
try
|
||||
{
|
||||
Profiler.BeginSample("CheckTrail");
|
||||
CheckTrail();
|
||||
Profiler.EndSample();
|
||||
|
||||
if (m_ParticleSystem && canvas)
|
||||
{
|
||||
// I do not know why, but it worked fine when setting `transform.localPosition.z` to `0.01`. (#34, #39)
|
||||
{
|
||||
Vector3 pos = rectTransform.localPosition;
|
||||
if (Mathf.Abs(pos.z) < 0.01f)
|
||||
{
|
||||
pos.z = 0.01f;
|
||||
rectTransform.localPosition = pos;
|
||||
}
|
||||
}
|
||||
|
||||
var rootCanvas = canvas.rootCanvas;
|
||||
Profiler.BeginSample("Disable ParticleSystemRenderer");
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
_renderer.enabled = false;
|
||||
}
|
||||
|
||||
Profiler.EndSample();
|
||||
|
||||
// #69: Editor crashes when mesh is set to null when ParticleSystem.RenderMode=Mesh
|
||||
if (_renderer.renderMode == ParticleSystemRenderMode.Mesh && !_renderer.mesh)
|
||||
return;
|
||||
|
||||
// #61: When ParticleSystem.RenderMode=None, an error occurs
|
||||
if (_renderer.renderMode == ParticleSystemRenderMode.None)
|
||||
return;
|
||||
|
||||
Profiler.BeginSample("Make Matrix");
|
||||
ParticleSystem.MainModule main = m_ParticleSystem.main;
|
||||
scaleaMatrix = main.scalingMode == ParticleSystemScalingMode.Hierarchy
|
||||
? Matrix4x4.Scale(scale * Vector3.one)
|
||||
: Matrix4x4.Scale(scale * rootCanvas.transform.localScale);
|
||||
Matrix4x4 matrix = default(Matrix4x4);
|
||||
switch (main.simulationSpace)
|
||||
{
|
||||
case ParticleSystemSimulationSpace.Local:
|
||||
matrix =
|
||||
scaleaMatrix
|
||||
* Matrix4x4.Rotate(rectTransform.rotation).inverse
|
||||
* Matrix4x4.Scale(rectTransform.lossyScale + minimumVec3).inverse;
|
||||
break;
|
||||
case ParticleSystemSimulationSpace.World:
|
||||
matrix =
|
||||
scaleaMatrix
|
||||
* rectTransform.worldToLocalMatrix;
|
||||
|
||||
bool isLocalScaling = main.scalingMode == ParticleSystemScalingMode.Local;
|
||||
Vector3 newPos = rectTransform.position;
|
||||
Vector3 delta = (newPos - _oldPos);
|
||||
_oldPos = newPos;
|
||||
|
||||
if (!Mathf.Approximately(scale, 0) && 0 < delta.sqrMagnitude)
|
||||
{
|
||||
if (isLocalScaling)
|
||||
{
|
||||
var s = rootCanvas.transform.localScale * scale;
|
||||
delta.x *= 1f - 1f / s.x;
|
||||
delta.y *= 1f - 1f / s.y;
|
||||
delta.z *= 1f - 1f / s.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
delta = delta * (1 - 1 / scale);
|
||||
}
|
||||
|
||||
int count = m_ParticleSystem.particleCount;
|
||||
if (s_Particles.Length < count)
|
||||
{
|
||||
s_Particles = new ParticleSystem.Particle[s_Particles.Length * 2];
|
||||
}
|
||||
|
||||
m_ParticleSystem.GetParticles(s_Particles);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var p = s_Particles[i];
|
||||
p.position = p.position + delta;
|
||||
s_Particles[i] = p;
|
||||
}
|
||||
|
||||
m_ParticleSystem.SetParticles(s_Particles, count);
|
||||
}
|
||||
|
||||
break;
|
||||
case ParticleSystemSimulationSpace.Custom:
|
||||
break;
|
||||
}
|
||||
|
||||
Profiler.EndSample();
|
||||
|
||||
_mesh.Clear();
|
||||
if (0 < m_ParticleSystem.particleCount)
|
||||
{
|
||||
Profiler.BeginSample("Bake Mesh");
|
||||
var cam = rootCanvas.renderMode == RenderMode.ScreenSpaceOverlay
|
||||
? UIParticleOverlayCamera.GetCameraForOvrelay(rootCanvas)
|
||||
: canvas.worldCamera ?? Camera.main;
|
||||
|
||||
if (!cam)
|
||||
{
|
||||
Profiler.EndSample();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_IsTrail)
|
||||
{
|
||||
_renderer.BakeTrailsMesh(_mesh, cam, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
_renderer.BakeMesh(_mesh, cam, true);
|
||||
}
|
||||
|
||||
Profiler.EndSample();
|
||||
|
||||
// Apply matrix.
|
||||
Profiler.BeginSample("Apply matrix to position");
|
||||
|
||||
if (QualitySettings.activeColorSpace == ColorSpace.Linear)
|
||||
{
|
||||
_mesh.GetColors(s_Colors);
|
||||
var count_c = s_Colors.Count;
|
||||
for (int i = 0; i < count_c; i++)
|
||||
{
|
||||
s_Colors[i] = ((Color) s_Colors[i]).gamma;
|
||||
}
|
||||
|
||||
_mesh.SetColors(s_Colors);
|
||||
}
|
||||
|
||||
_mesh.GetVertices(s_Vertices);
|
||||
var count = s_Vertices.Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
s_Vertices[i] = matrix.MultiplyPoint3x4(s_Vertices[i]);
|
||||
}
|
||||
|
||||
_mesh.SetVertices(s_Vertices);
|
||||
_mesh.RecalculateBounds();
|
||||
s_Vertices.Clear();
|
||||
s_Colors.Clear();
|
||||
Profiler.EndSample();
|
||||
}
|
||||
|
||||
|
||||
// Set mesh to CanvasRenderer.
|
||||
Profiler.BeginSample("Set mesh and texture to CanvasRenderer");
|
||||
canvasRenderer.SetMesh(_mesh);
|
||||
canvasRenderer.SetTexture(mainTexture);
|
||||
|
||||
// Copy the value from MaterialPropertyBlock to CanvasRenderer (#41)
|
||||
UpdateAnimatableMaterialProperties();
|
||||
|
||||
Profiler.EndSample();
|
||||
}
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
Debug.LogException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks the trail.
|
||||
/// </summary>
|
||||
void CheckTrail()
|
||||
{
|
||||
if (isActiveAndEnabled && !m_IsTrail && m_ParticleSystem && m_ParticleSystem.trails.enabled)
|
||||
// Should have a UIParticle for trail particle?
|
||||
if (isActiveAndEnabled && isValid && !isTrailParticle && isSpritesModeAndHasTrail)
|
||||
{
|
||||
if (!m_TrailParticle)
|
||||
{
|
||||
// Create new UIParticle for trail particle
|
||||
m_TrailParticle = new GameObject("[UIParticle] Trail").AddComponent<UIParticle>();
|
||||
var trans = m_TrailParticle.transform;
|
||||
trans.SetParent(transform);
|
||||
trans.localPosition = Vector3.zero;
|
||||
trans.localRotation = Quaternion.identity;
|
||||
trans.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
|
||||
trans.localScale = Vector3.one;
|
||||
trans.SetParent(transform, false);
|
||||
|
||||
m_TrailParticle._renderer = GetComponent<ParticleSystemRenderer>();
|
||||
m_TrailParticle.m_ParticleSystem = GetComponent<ParticleSystem>();
|
||||
m_TrailParticle._renderer = _renderer;
|
||||
m_TrailParticle.m_ParticleSystem = m_ParticleSystem;
|
||||
m_TrailParticle.m_IsTrail = true;
|
||||
}
|
||||
|
||||
m_TrailParticle.enabled = true;
|
||||
m_TrailParticle.gameObject.hideFlags = HideFlags.DontSave;
|
||||
}
|
||||
else if (m_TrailParticle)
|
||||
{
|
||||
m_TrailParticle.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the parent of the soft mask.
|
||||
/// </summary>
|
||||
/// <param name="newParent">The parent soft mask to use.</param>
|
||||
void SetParent(UIParticle newParent)
|
||||
{
|
||||
if (_parent != newParent && this != newParent)
|
||||
{
|
||||
if (_parent && _parent._children.Contains(this))
|
||||
{
|
||||
_parent._children.Remove(this);
|
||||
_parent._children.RemoveAll(x => x == null);
|
||||
}
|
||||
|
||||
_parent = newParent;
|
||||
}
|
||||
|
||||
if (_parent && !_parent._children.Contains(this))
|
||||
{
|
||||
_parent._children.Add(this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy the value from MaterialPropertyBlock to CanvasRenderer (#41)
|
||||
/// </summary>
|
||||
void UpdateAnimatableMaterialProperties()
|
||||
{
|
||||
// Destroy a UIParticle for trail particle.
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
return;
|
||||
if (!Application.isPlaying)
|
||||
DestroyImmediate(m_TrailParticle.gameObject);
|
||||
else
|
||||
#endif
|
||||
if (0 == m_AnimatableProperties.Length)
|
||||
return;
|
||||
Destroy(m_TrailParticle.gameObject);
|
||||
|
||||
_renderer.GetPropertyBlock(s_Mpb);
|
||||
for (int i = 0; i < canvasRenderer.materialCount; i++)
|
||||
{
|
||||
var mat = canvasRenderer.GetMaterial(i);
|
||||
foreach (var ap in m_AnimatableProperties)
|
||||
{
|
||||
switch (ap.type)
|
||||
{
|
||||
case ShaderPropertyType.Color:
|
||||
mat.SetColor(ap.id, s_Mpb.GetColor(ap.id));
|
||||
break;
|
||||
case ShaderPropertyType.Vector:
|
||||
mat.SetVector(ap.id, s_Mpb.GetVector(ap.id));
|
||||
break;
|
||||
case ShaderPropertyType.Float:
|
||||
case ShaderPropertyType.Range:
|
||||
mat.SetFloat(ap.id, s_Mpb.GetFloat(ap.id));
|
||||
break;
|
||||
case ShaderPropertyType.Texture:
|
||||
mat.SetTexture(ap.id, s_Mpb.GetTexture(ap.id));
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_TrailParticle = null;
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private static Type tSpriteEditorExtension = Type.GetType("UnityEditor.Experimental.U2D.SpriteEditorExtension, UnityEditor")
|
||||
?? Type.GetType("UnityEditor.U2D.SpriteEditorExtension, UnityEditor");
|
||||
private static MethodInfo miGetActiveAtlasTexture = tSpriteEditorExtension
|
||||
.GetMethod("GetActiveAtlasTexture", BindingFlags.Static | BindingFlags.NonPublic);
|
||||
|
||||
static Texture2D GetActualTexture(Sprite sprite)
|
||||
internal void CheckMaterials()
|
||||
{
|
||||
if (!sprite) return null;
|
||||
if (!_renderer) return;
|
||||
|
||||
if (Application.isPlaying) return sprite.texture;
|
||||
var ret = miGetActiveAtlasTexture.Invoke(null, new[] {sprite}) as Texture2D;
|
||||
return ret ? ret : sprite.texture;
|
||||
var matChanged = HasMaterialChanged(_renderer.sharedMaterial, ref _cachedSharedMaterialId);
|
||||
var matChanged2 = HasMaterialChanged(_renderer.trailMaterial, ref _cachedTrailMaterialId);
|
||||
var modeChanged = _cachedSpritesModeAndHasTrail != isSpritesModeAndHasTrail;
|
||||
_cachedSpritesModeAndHasTrail = isSpritesModeAndHasTrail;
|
||||
|
||||
if (matChanged || matChanged2 || modeChanged)
|
||||
SetMaterialDirty();
|
||||
}
|
||||
#else
|
||||
static Texture2D GetActualTexture(Sprite sprite)
|
||||
|
||||
private void UpdateVersionIfNeeded()
|
||||
{
|
||||
return sprite ? sprite.texture : null;
|
||||
if (Mathf.Approximately(m_Scale, 0)) return;
|
||||
|
||||
var parent = GetComponentInParent<UIParticle>();
|
||||
if (m_IgnoreParent || !parent)
|
||||
scale3D = m_Scale * transform.localScale;
|
||||
else
|
||||
scale3D = transform.localScale;
|
||||
m_Scale = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user