Skip to content

Commit

Permalink
feat: UIParticle for trail is no longer needed
Browse files Browse the repository at this point in the history
  • Loading branch information
mob-sakai committed Aug 20, 2020
1 parent 9cff6cf commit 466e43c
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 139 deletions.
129 changes: 53 additions & 76 deletions Packages/UIParticle/Scripts/UIParticle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ public class UIParticle : MaskableGraphic
[Tooltip("The ParticleSystem rendered by CanvasRenderer")] [SerializeField]
ParticleSystem m_ParticleSystem;

[Tooltip("The UIParticle to render trail effect")] [SerializeField]
internal UIParticle m_TrailParticle;

[HideInInspector] [SerializeField] bool m_IsTrail = false;

[Tooltip("Ignore canvas scaler")] [SerializeField]
Expand All @@ -43,7 +40,7 @@ public class UIParticle : MaskableGraphic
private ParticleSystemRenderer _renderer;
private int _cachedSharedMaterialId;
private int _cachedTrailMaterialId;
private bool _cachedSpritesModeAndHasTrail;
private bool _cachedSpritesMode;

//################################
// Public/Protected Members.
Expand Down Expand Up @@ -97,21 +94,6 @@ public Vector3 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; }
Expand Down Expand Up @@ -141,32 +123,31 @@ 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 = trailModule.enabled ? 2 : 1;

// Regenerate main material.
var mainMat = _renderer.sharedMaterial;
var hasAnimatableProperties = 0 < m_AnimatableProperties.Length;
var tex = GetTextureForSprite(cachedParticleSystem);
if (hasAnimatableProperties || tex)
{
canvasRenderer.materialCount = 1;
canvasRenderer.SetMaterial(GetModifiedMaterial(_renderer.sharedMaterial, 0), 0);
mainMat = new Material(mainMat);
if (tex)
{
mainMat.mainTexture = tex;
}
}

canvasRenderer.SetMaterial(GetModifiedMaterial(mainMat, 0), 0);

// Trail material
if (trailModule.enabled)
canvasRenderer.SetMaterial(GetModifiedMaterial(_renderer.trailMaterial, 1), 1);
}

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);
if (!baseMaterial || 1 < index || !isActiveAndEnabled) return baseMaterial;

var baseMat = baseMaterial;
if (m_ShouldRecalculateStencil)
Expand Down Expand Up @@ -196,11 +177,41 @@ private Material GetModifiedMaterial(Material baseMaterial, int index)
return baseMat;
}


private static Texture2D GetTextureForSprite(ParticleSystem particle)
{
if (!particle) return null;

// Get sprite's texture.
var tsaModule = particle.textureSheetAnimation;
if (!tsaModule.enabled || tsaModule.mode != ParticleSystemAnimationMode.Sprites) return null;

for (var i = 0; i < tsaModule.spriteCount; i++)
{
var sprite = tsaModule.GetSprite(i);
if (!sprite) continue;

return sprite.GetActualTexture();
}

return null;
}

/// <summary>
/// This function is called when the object becomes enabled and active.
/// </summary>
protected override void OnEnable()
{
if (m_IsTrail)
{
gameObject.SetActive(false);
if (Application.isPlaying)
Destroy(gameObject);
else
DestroyImmediate(gameObject);
return;
}

UpdateVersionIfNeeded();

_tracker.Add(this, rectTransform, DrivenTransformProperties.Scale);
Expand Down Expand Up @@ -282,49 +293,15 @@ private static bool HasMaterialChanged(Material material, ref int current)
return current != old;
}

internal void UpdateTrailParticle()
{
// 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.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
trans.localScale = Vector3.one;
trans.SetParent(transform, false);

m_TrailParticle._renderer = _renderer;
m_TrailParticle.m_ParticleSystem = m_ParticleSystem;
m_TrailParticle.m_IsTrail = true;
}

m_TrailParticle.gameObject.hideFlags = HideFlags.DontSave;
}
else if (m_TrailParticle)
{
// Destroy a UIParticle for trail particle.
#if UNITY_EDITOR
if (!Application.isPlaying)
DestroyImmediate(m_TrailParticle.gameObject);
else
#endif
Destroy(m_TrailParticle.gameObject);

m_TrailParticle = null;
}
}

internal void CheckMaterials()
{
if (!_renderer) return;

var matChanged = HasMaterialChanged(_renderer.sharedMaterial, ref _cachedSharedMaterialId);
var matChanged2 = HasMaterialChanged(_renderer.trailMaterial, ref _cachedTrailMaterialId);
var modeChanged = _cachedSpritesModeAndHasTrail != isSpritesModeAndHasTrail;
_cachedSpritesModeAndHasTrail = isSpritesModeAndHasTrail;
var isSpritesMode = textureSheetAnimationModule.enabled && textureSheetAnimationModule.mode == ParticleSystemAnimationMode.Sprites;
var modeChanged = _cachedSpritesMode != isSpritesMode;
_cachedSpritesMode = isSpritesMode;

if (matChanged || matChanged2 || modeChanged)
SetMaterialDirty();
Expand Down
71 changes: 8 additions & 63 deletions Packages/UIParticle/Scripts/UIParticleUpdater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,6 @@ private static void Refresh(UIParticle particle)

if (!particle.isValid) return;

Profiler.BeginSample("Update trail particle");
particle.UpdateTrailParticle();
Profiler.EndSample();

Profiler.BeginSample("Check materials");
particle.CheckMaterials();
Profiler.EndSample();
Expand All @@ -80,8 +76,8 @@ private static void Refresh(UIParticle particle)
Profiler.EndSample();
}

Profiler.BeginSample("Set mesh and texture to CanvasRenderer");
UpdateMeshAndTexture(particle);
Profiler.BeginSample("Set mesh to CanvasRenderer");
particle.canvasRenderer.SetMesh(particle.bakedMesh);
Profiler.EndSample();

Profiler.BeginSample("Update Animatable Material Properties");
Expand All @@ -91,8 +87,6 @@ private static void Refresh(UIParticle particle)

private static void ModifyScale(UIParticle particle)
{
if (particle.isTrailParticle) return;

var modifiedScale = particle.m_Scale3D;

// Ignore Canvas scaling.
Expand All @@ -113,44 +107,9 @@ private static void ModifyScale(UIParticle particle)
tr.localScale = modifiedScale;
}

private static void UpdateMeshAndTexture(UIParticle particle)
{
// Update mesh.
particle.canvasRenderer.SetMesh(particle.bakedMesh);

// Non sprite mode: external texture is not used.
if (!particle.isSpritesMode || particle.isTrailParticle)
{
particle.canvasRenderer.SetTexture(null);
return;
}

// Sprite mode: get sprite's texture.
Texture tex = null;
Profiler.BeginSample("Check TextureSheetAnimation module");
var tsaModule = particle.cachedParticleSystem.textureSheetAnimation;
if (tsaModule.enabled && tsaModule.mode == ParticleSystemAnimationMode.Sprites)
{
var count = tsaModule.spriteCount;
for (var i = 0; i < count; i++)
{
var sprite = tsaModule.GetSprite(i);
if (!sprite) continue;

tex = sprite.GetActualTexture();
break;
}
}

Profiler.EndSample();

particle.canvasRenderer.SetTexture(tex);
}

private static Matrix4x4 GetScaledMatrix(UIParticle particle)
{
var transform = particle.transform;
var tr = particle.isTrailParticle ? transform.parent : transform;
var main = particle.mainModule;
var space = main.simulationSpace;
if (space == ParticleSystemSimulationSpace.Custom && !main.customSimulationSpace)
Expand All @@ -160,9 +119,9 @@ private static Matrix4x4 GetScaledMatrix(UIParticle particle)
{
case ParticleSystemSimulationSpace.Local:
var canvasTr = particle.canvas.rootCanvas.transform;
return Matrix4x4.Rotate(tr.localRotation).inverse
return Matrix4x4.Rotate(transform.localRotation).inverse
* Matrix4x4.Rotate(canvasTr.localRotation).inverse
* Matrix4x4.Scale(tr.localScale).inverse
* Matrix4x4.Scale(transform.localScale).inverse
* Matrix4x4.Scale(canvasTr.localScale).inverse;
case ParticleSystemSimulationSpace.World:
return transform.worldToLocalMatrix;
Expand Down Expand Up @@ -190,25 +149,11 @@ private static void BakeMesh(UIParticle particle, Matrix4x4 scaledMatrix)
var trail = particle.trailModule;

Profiler.BeginSample("Bake mesh");
if (!particle.isSpritesMode) // Non sprite mode: bake main particle and trail particle.
{
if (CanBakeMesh(renderer))
renderer.BakeMesh(MeshHelper.GetTemporaryMesh(), cam, true);

if (trail.enabled)
renderer.BakeTrailsMesh(MeshHelper.GetTemporaryMesh(), cam, true);
}
else if (particle.isTrailParticle) // Sprite mode (trail): bake trail particle.
{
if (trail.enabled)
renderer.BakeTrailsMesh(MeshHelper.GetTemporaryMesh(), cam, true);
}
else // Sprite mode (main): bake main particle.
{
if (CanBakeMesh(renderer))
renderer.BakeMesh(MeshHelper.GetTemporaryMesh(), cam, true);
}
if (CanBakeMesh(renderer))
renderer.BakeMesh(MeshHelper.GetTemporaryMesh(), cam, true);

if (trail.enabled)
renderer.BakeTrailsMesh(MeshHelper.GetTemporaryMesh(), cam, true);
Profiler.EndSample();

Profiler.BeginSample("Apply matrix to position");
Expand Down

0 comments on commit 466e43c

Please sign in to comment.