pull/33/head
mob-sakai 2018-06-22 19:06:13 +09:00
parent a39f20861c
commit 9ca9a2ad76
1 changed files with 143 additions and 125 deletions
Assets/Coffee/UIExtentions/UIParticle

View File

@ -4,153 +4,171 @@ using UnityEngine;
using UnityEngine.Profiling; using UnityEngine.Profiling;
using UnityEngine.UI; using UnityEngine.UI;
//[RequireComponent(typeof(ParticleSystem))]
[ExecuteInEditMode] namespace Coffee.UIExtensions
public class UIParticle : MaskableGraphic
{ {
static readonly int s_IdMainTex = Shader.PropertyToID("_MainTex"); /// <summary>
static readonly List<Vector3> s_Vertices = new List<Vector3>(); /// Render maskable and sortable particle effect ,without Camera, RenderTexture or Canvas.
/// </summary>
[SerializeField] ParticleSystem m_ParticleSystem; [ExecuteInEditMode]
[SerializeField] UIParticle m_TrailParticle; public class UIParticle : MaskableGraphic
Mesh _mesh;
ParticleSystemRenderer _renderer;
[HideInInspector] [SerializeField] bool m_IsTrail = false;
public override Texture mainTexture
{ {
get //################################
// Constant or Readonly Static Members.
//################################
static readonly int s_IdMainTex = Shader.PropertyToID("_MainTex");
static readonly List<Vector3> s_Vertices = new List<Vector3>();
//################################
// Serialize Members.
//################################
[Tooltip("The ParticleSystem rendered by CanvasRenderer")]
[SerializeField] ParticleSystem m_ParticleSystem;
[Tooltip("The UIParticle to render trail effect")]
[SerializeField] UIParticle m_TrailParticle;
[HideInInspector] [SerializeField] bool m_IsTrail = false;
//################################
// Public/Protected Members.
//################################
public override Texture mainTexture
{ {
var mat = _renderer ? _renderer.sharedMaterial : defaultGraphicMaterial; get
return mat && mat.HasProperty(s_IdMainTex) ? mat.mainTexture : s_WhiteTexture; ;
}
}
public override Material GetModifiedMaterial(Material baseMaterial)
{
return base.GetModifiedMaterial(_renderer ? _renderer.sharedMaterial : baseMaterial);
}
protected override void OnEnable()
{
m_ParticleSystem = m_ParticleSystem ? m_ParticleSystem : GetComponent<ParticleSystem>();
_renderer = m_ParticleSystem ? m_ParticleSystem.GetComponent<ParticleSystemRenderer>() : null;
_mesh = new Mesh();
_mesh.MarkDynamic();
CheckTrail();
base.OnEnable();
}
protected override void OnDisable()
{
DestroyImmediate(_mesh);
_mesh = null;
CheckTrail();
base.OnDisable();
}
void CheckTrail()
{
if (isActiveAndEnabled && !m_IsTrail && m_ParticleSystem && m_ParticleSystem.trails.enabled)
{
if (!m_TrailParticle)
{ {
m_TrailParticle = new GameObject("[UIParticle] Trail").AddComponent<UIParticle>(); var mat = _renderer ? _renderer.sharedMaterial : defaultGraphicMaterial;
var trans = m_TrailParticle.transform; return mat && mat.HasProperty(s_IdMainTex) ? mat.mainTexture : s_WhiteTexture; ;
trans.SetParent(transform);
trans.localPosition = Vector3.zero;
trans.localRotation = Quaternion.identity;
trans.localScale = Vector3.one;
m_TrailParticle._renderer = GetComponent<ParticleSystemRenderer>();
m_TrailParticle.m_ParticleSystem = GetComponent<ParticleSystem>();
m_TrailParticle.m_IsTrail = true;
} }
m_TrailParticle.enabled = true;
} }
else if (m_TrailParticle)
public override Material GetModifiedMaterial(Material baseMaterial)
{ {
m_TrailParticle.enabled = false; return base.GetModifiedMaterial(_renderer ? _renderer.sharedMaterial : baseMaterial);
} }
}
protected override void UpdateGeometry() protected override void OnEnable()
{
}
void Update()
{
Profiler.BeginSample("CheckTrail");
CheckTrail();
Profiler.EndSample();
if (m_ParticleSystem)
{ {
Profiler.BeginSample("Disable ParticleSystemRenderer"); m_ParticleSystem = m_ParticleSystem ? m_ParticleSystem : GetComponent<ParticleSystem>();
if (Application.isPlaying) _renderer = m_ParticleSystem ? m_ParticleSystem.GetComponent<ParticleSystemRenderer>() : null;
{
_renderer.enabled = false; _mesh = new Mesh();
} _mesh.MarkDynamic();
CheckTrail();
base.OnEnable();
}
protected override void OnDisable()
{
DestroyImmediate(_mesh);
_mesh = null;
CheckTrail();
base.OnDisable();
}
protected override void UpdateGeometry()
{
}
//################################
// Private Members.
//################################
Mesh _mesh;
ParticleSystemRenderer _renderer;
void Update()
{
Profiler.BeginSample("CheckTrail");
CheckTrail();
Profiler.EndSample(); Profiler.EndSample();
Profiler.BeginSample("Make Matrix"); if (m_ParticleSystem)
var cam = canvas.worldCamera ?? Camera.main;
bool useTransform = false;
Matrix4x4 matrix = default(Matrix4x4);
switch (m_ParticleSystem.main.simulationSpace)
{ {
case ParticleSystemSimulationSpace.Local: Profiler.BeginSample("Disable ParticleSystemRenderer");
matrix = if (Application.isPlaying)
Matrix4x4.Rotate(m_ParticleSystem.transform.rotation).inverse
* Matrix4x4.Scale(m_ParticleSystem.transform.lossyScale).inverse;
useTransform = true;
break;
case ParticleSystemSimulationSpace.World:
matrix = m_ParticleSystem.transform.worldToLocalMatrix;
break;
case ParticleSystemSimulationSpace.Custom:
break;
}
Profiler.EndSample();
_mesh.Clear();
if (0 < m_ParticleSystem.particleCount)
{
Profiler.BeginSample("Bake Mesh");
if (m_IsTrail)
{ {
_renderer.BakeTrailsMesh(_mesh, cam, useTransform); _renderer.enabled = false;
}
else
{
_renderer.BakeMesh(_mesh, cam, useTransform);
} }
Profiler.EndSample(); Profiler.EndSample();
// Apply matrix. Profiler.BeginSample("Make Matrix");
Profiler.BeginSample("Apply matrix to position"); var cam = canvas.worldCamera ?? Camera.main;
_mesh.GetVertices(s_Vertices); bool useTransform = false;
var count = s_Vertices.Count; Matrix4x4 matrix = default(Matrix4x4);
for (int i = 0; i < count; i++) switch (m_ParticleSystem.main.simulationSpace)
{ {
s_Vertices[i] = matrix.MultiplyPoint3x4(s_Vertices[i]); case ParticleSystemSimulationSpace.Local:
matrix =
Matrix4x4.Rotate(m_ParticleSystem.transform.rotation).inverse
* Matrix4x4.Scale(m_ParticleSystem.transform.lossyScale).inverse;
useTransform = true;
break;
case ParticleSystemSimulationSpace.World:
matrix = m_ParticleSystem.transform.worldToLocalMatrix;
break;
case ParticleSystemSimulationSpace.Custom:
break;
} }
_mesh.SetVertices(s_Vertices); Profiler.EndSample();
s_Vertices.Clear();
_mesh.Clear();
if (0 < m_ParticleSystem.particleCount)
{
Profiler.BeginSample("Bake Mesh");
if (m_IsTrail)
{
_renderer.BakeTrailsMesh(_mesh, cam, useTransform);
}
else
{
_renderer.BakeMesh(_mesh, cam, useTransform);
}
Profiler.EndSample();
// Apply matrix.
Profiler.BeginSample("Apply matrix to position");
_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);
s_Vertices.Clear();
Profiler.EndSample();
}
// Set mesh to CanvasRenderer.
Profiler.BeginSample("Set mesh to CanvasRenderer");
canvasRenderer.SetMesh(_mesh);
Profiler.EndSample(); Profiler.EndSample();
} }
}
void CheckTrail()
{
if (isActiveAndEnabled && !m_IsTrail && m_ParticleSystem && m_ParticleSystem.trails.enabled)
{
if (!m_TrailParticle)
{
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.localScale = Vector3.one;
// Set mesh to CanvasRenderer. m_TrailParticle._renderer = GetComponent<ParticleSystemRenderer>();
Profiler.BeginSample("Set mesh to CanvasRenderer"); m_TrailParticle.m_ParticleSystem = GetComponent<ParticleSystem>();
canvasRenderer.SetMesh(_mesh); m_TrailParticle.m_IsTrail = true;
Profiler.EndSample(); }
//canvasRenderer.SetColor(color); m_TrailParticle.enabled = true;
}
else if (m_TrailParticle)
{
m_TrailParticle.enabled = false;
}
} }
} }
} }