Compare commits
14 Commits
a499f0c046
...
174af4bf7b
Author | SHA1 | Date |
---|---|---|
|
174af4bf7b | |
|
65770cadda | |
|
12b5aacf1d | |
|
fa8d7fa312 | |
|
dc82e4074d | |
|
924550b0fc | |
|
c4e4fce26f | |
|
ab427e9b6a | |
|
5a21298c02 | |
|
60932e92c1 | |
|
c75ca8663f | |
|
52f2ef1f24 | |
|
e92b514624 | |
|
a4bcf93022 |
|
@ -27,7 +27,7 @@ namespace Coffee.UIExtensions
|
||||||
Auto,
|
Auto,
|
||||||
Primary,
|
Primary,
|
||||||
PrimarySimulator,
|
PrimarySimulator,
|
||||||
Reprica,
|
Replica,
|
||||||
}
|
}
|
||||||
|
|
||||||
[HideInInspector][SerializeField] internal bool m_IsTrail = false;
|
[HideInInspector][SerializeField] internal bool m_IsTrail = false;
|
||||||
|
@ -44,7 +44,7 @@ namespace Coffee.UIExtensions
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private List<ParticleSystem> m_Particles = new List<ParticleSystem>();
|
private List<ParticleSystem> m_Particles = new List<ParticleSystem>();
|
||||||
|
|
||||||
[Tooltip("Mesh sharing.None: disable mesh sharing.\nAuto: automatically select Primary/Reprica.\nPrimary: provides particle simulation results to the same group.\nPrimary Simulator: Primary, but do not render the particle (simulation only).\nReprica: render simulation results provided by the primary.")]
|
[Tooltip("Mesh sharing.None: disable mesh sharing.\nAuto: automatically select Primary/Replica.\nPrimary: provides particle simulation results to the same group.\nPrimary Simulator: Primary, but do not render the particle (simulation only).\nReplica: render simulation results provided by the primary.")]
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private MeshSharing m_MeshSharing = MeshSharing.None;
|
private MeshSharing m_MeshSharing = MeshSharing.None;
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ namespace Coffee.UIExtensions
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
[Tooltip("The particles will be emitted at the ParticleSystem position.\nMove the UIParticle/ParticleSystem to move the particle.")]
|
[Tooltip("The particles will be emitted at the ParticleSystem position.\nMove the UIParticle/ParticleSystem to move the particle.")]
|
||||||
private bool m_AbsoluteMode = false;
|
private bool m_AbsoluteMode = true;
|
||||||
|
|
||||||
private List<UIParticleRenderer> m_Renderers = new List<UIParticleRenderer>();
|
private List<UIParticleRenderer> m_Renderers = new List<UIParticleRenderer>();
|
||||||
|
|
||||||
|
@ -80,10 +80,10 @@ namespace Coffee.UIExtensions
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Mesh sharing.None: disable mesh sharing.
|
/// Mesh sharing.None: disable mesh sharing.
|
||||||
/// Auto: automatically select Primary/Reprica.
|
/// Auto: automatically select Primary/Replica.
|
||||||
/// Primary: provides particle simulation results to the same group.
|
/// Primary: provides particle simulation results to the same group.
|
||||||
/// Primary Simulator: Primary, but do not render the particle (simulation only).
|
/// Primary Simulator: Primary, but do not render the particle (simulation only).
|
||||||
/// Reprica: render simulation results provided by the primary.
|
/// Replica: render simulation results provided by the primary.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public MeshSharing meshSharing
|
public MeshSharing meshSharing
|
||||||
{
|
{
|
||||||
|
@ -145,7 +145,7 @@ namespace Coffee.UIExtensions
|
||||||
|
|
||||||
internal bool canRender
|
internal bool canRender
|
||||||
{
|
{
|
||||||
get { return m_MeshSharing == MeshSharing.None || m_MeshSharing == MeshSharing.Auto || m_MeshSharing == MeshSharing.Primary || m_MeshSharing == MeshSharing.Reprica; }
|
get { return m_MeshSharing == MeshSharing.None || m_MeshSharing == MeshSharing.Auto || m_MeshSharing == MeshSharing.Primary || m_MeshSharing == MeshSharing.Replica; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -286,7 +286,22 @@ namespace Coffee.UIExtensions
|
||||||
|
|
||||||
public void RefreshParticles(List<ParticleSystem> particles)
|
public void RefreshParticles(List<ParticleSystem> particles)
|
||||||
{
|
{
|
||||||
GetComponentsInChildren(m_Renderers);
|
// #246: Nullptr exceptions when using nested UIParticle components in hierarchy
|
||||||
|
m_Renderers.Clear();
|
||||||
|
foreach (Transform child in transform)
|
||||||
|
{
|
||||||
|
var uiParticleRenderer = child.GetComponent<UIParticleRenderer>();
|
||||||
|
|
||||||
|
if (uiParticleRenderer != null)
|
||||||
|
{
|
||||||
|
m_Renderers.Add(uiParticleRenderer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < m_Renderers.Count; i++)
|
||||||
|
{
|
||||||
|
m_Renderers[i].Reset(i);
|
||||||
|
}
|
||||||
|
|
||||||
var j = 0;
|
var j = 0;
|
||||||
for (var i = 0; i < particles.Count; i++)
|
for (var i = 0; i < particles.Count; i++)
|
||||||
|
@ -298,11 +313,6 @@ namespace Coffee.UIExtensions
|
||||||
GetRenderer(j++).Set(this, particles[i], true);
|
GetRenderer(j++).Set(this, particles[i], true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; j < m_Renderers.Count; j++)
|
|
||||||
{
|
|
||||||
GetRenderer(j).Clear(j);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void UpdateTransformScale()
|
internal void UpdateTransformScale()
|
||||||
|
@ -323,9 +333,13 @@ namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
if (!isActiveAndEnabled) return;
|
if (!isActiveAndEnabled) return;
|
||||||
|
|
||||||
if (m_Renderers.Any(x => !x))
|
foreach (var rend in m_Renderers)
|
||||||
{
|
{
|
||||||
RefreshParticles(particles);
|
if (!rend)
|
||||||
|
{
|
||||||
|
RefreshParticles(particles);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var bakeCamera = GetBakeCamera();
|
var bakeCamera = GetBakeCamera();
|
||||||
|
@ -386,7 +400,7 @@ namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
_tracker.Clear();
|
_tracker.Clear();
|
||||||
UIParticleUpdater.Unregister(this);
|
UIParticleUpdater.Unregister(this);
|
||||||
m_Renderers.ForEach(r => r.Clear());
|
m_Renderers.ForEach(r => r.Reset());
|
||||||
UnregisterDirtyMaterialCallback(UpdateRendererMaterial);
|
UnregisterDirtyMaterialCallback(UpdateRendererMaterial);
|
||||||
|
|
||||||
base.OnDisable();
|
base.OnDisable();
|
||||||
|
@ -437,9 +451,12 @@ namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
if (!canvas) return Camera.main;
|
if (!canvas) return Camera.main;
|
||||||
|
|
||||||
// World camera.
|
// Render mode is not ScreenSpaceOverlay, use world camera.
|
||||||
var root = canvas.rootCanvas;
|
var root = canvas.rootCanvas;
|
||||||
if (root.renderMode != RenderMode.ScreenSpaceOverlay) return root.worldCamera ? root.worldCamera : Camera.main;
|
if (root.renderMode != RenderMode.ScreenSpaceOverlay)
|
||||||
|
{
|
||||||
|
return root.worldCamera ? root.worldCamera : Camera.main;
|
||||||
|
}
|
||||||
|
|
||||||
// Create ortho-camera.
|
// Create ortho-camera.
|
||||||
if (!_orthoCamera)
|
if (!_orthoCamera)
|
||||||
|
|
|
@ -36,6 +36,12 @@ namespace Coffee.UIExtensions
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private UnityEvent m_OnAttracted;
|
private UnityEvent m_OnAttracted;
|
||||||
|
|
||||||
|
public float destinationRadius
|
||||||
|
{
|
||||||
|
get { return m_DestinationRadius; }
|
||||||
|
set { m_DestinationRadius = Mathf.Clamp(value, 0.1f, 10f); }
|
||||||
|
}
|
||||||
|
|
||||||
public float delay
|
public float delay
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -72,22 +78,31 @@ namespace Coffee.UIExtensions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public UnityEvent onAttracted
|
||||||
|
{
|
||||||
|
get { return m_OnAttracted; }
|
||||||
|
set { m_OnAttracted = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public ParticleSystem particleSystem
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_ParticleSystem;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
m_ParticleSystem = value;
|
||||||
|
if (!ApplyParticleSystem()) return;
|
||||||
|
enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private UIParticle _uiParticle;
|
private UIParticle _uiParticle;
|
||||||
|
|
||||||
private void OnEnable()
|
private void OnEnable()
|
||||||
{
|
{
|
||||||
if (m_ParticleSystem == null)
|
if (!ApplyParticleSystem()) return;
|
||||||
{
|
|
||||||
Debug.LogError("No particle system attached to particle attractor script", this);
|
|
||||||
enabled = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_uiParticle = m_ParticleSystem.GetComponentInParent<UIParticle>();
|
|
||||||
if (_uiParticle && !_uiParticle.particles.Contains(m_ParticleSystem))
|
|
||||||
{
|
|
||||||
_uiParticle = null;
|
|
||||||
}
|
|
||||||
UIParticleUpdater.Register(this);
|
UIParticleUpdater.Register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,29 +169,32 @@ namespace Coffee.UIExtensions
|
||||||
var psPos = m_ParticleSystem.transform.position;
|
var psPos = m_ParticleSystem.transform.position;
|
||||||
var attractorPos = transform.position;
|
var attractorPos = transform.position;
|
||||||
var dstPos = attractorPos;
|
var dstPos = attractorPos;
|
||||||
if (m_ParticleSystem.main.simulationSpace == ParticleSystemSimulationSpace.Local)
|
var isLocalSpace = m_ParticleSystem.main.simulationSpace == ParticleSystemSimulationSpace.Local;
|
||||||
|
|
||||||
|
if (isLocalSpace)
|
||||||
{
|
{
|
||||||
dstPos = m_ParticleSystem.transform.InverseTransformPoint(dstPos);
|
dstPos = m_ParticleSystem.transform.InverseTransformPoint(dstPos);
|
||||||
if (isUI)
|
|
||||||
{
|
|
||||||
dstPos = dstPos.GetScaled(_uiParticle.transform.localScale, _uiParticle.scale3D.Inverse());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (isUI)
|
||||||
{
|
{
|
||||||
#if UNITY_EDITOR
|
dstPos = dstPos.GetScaled(_uiParticle.transform.localScale, _uiParticle.scale3D.Inverse());
|
||||||
if (!Application.isPlaying && isUI)
|
|
||||||
|
// Relative mode
|
||||||
|
if (!_uiParticle.absoluteMode)
|
||||||
{
|
{
|
||||||
var diff = dstPos - psPos;
|
var diff = _uiParticle.transform.position - psPos;
|
||||||
diff = diff.GetScaled(_uiParticle.transform.localScale, _uiParticle.scale3D.Inverse());
|
diff.Scale(_uiParticle.scale3D - _uiParticle.transform.localScale);
|
||||||
return psPos + diff;
|
diff.Scale(_uiParticle.scale3D.Inverse());
|
||||||
|
dstPos += diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
if (!Application.isPlaying && !isLocalSpace)
|
||||||
|
{
|
||||||
|
dstPos += psPos - psPos.GetScaled(_uiParticle.transform.localScale, _uiParticle.scale3D.Inverse());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (isUI)
|
|
||||||
{
|
|
||||||
dstPos.Scale(_uiParticle.transform.localScale);
|
|
||||||
dstPos.Scale(_uiParticle.scale3D.Inverse());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return dstPos;
|
return dstPos;
|
||||||
}
|
}
|
||||||
|
@ -200,5 +218,22 @@ namespace Coffee.UIExtensions
|
||||||
return Vector3.MoveTowards(current, target, speed);
|
return Vector3.MoveTowards(current, target, speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool ApplyParticleSystem()
|
||||||
|
{
|
||||||
|
if (m_ParticleSystem == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("No particle system attached to particle attractor script", this);
|
||||||
|
enabled = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_uiParticle = m_ParticleSystem.GetComponentInParent<UIParticle>();
|
||||||
|
if (_uiParticle && !_uiParticle.particles.Contains(m_ParticleSystem))
|
||||||
|
{
|
||||||
|
_uiParticle = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -112,7 +112,12 @@ namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
_currentMaterialForRendering = null;
|
_currentMaterialForRendering = null;
|
||||||
|
|
||||||
if (!IsActive()) return baseMaterial;
|
if (!IsActive() || !_parent)
|
||||||
|
{
|
||||||
|
ModifiedMaterial.Remove(_modifiedMaterial);
|
||||||
|
_modifiedMaterial = null;
|
||||||
|
return baseMaterial;
|
||||||
|
}
|
||||||
|
|
||||||
var modifiedMaterial = base.GetModifiedMaterial(baseMaterial);
|
var modifiedMaterial = base.GetModifiedMaterial(baseMaterial);
|
||||||
|
|
||||||
|
@ -134,7 +139,7 @@ namespace Coffee.UIExtensions
|
||||||
return modifiedMaterial;
|
return modifiedMaterial;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Clear(int index = -1)
|
public void Reset(int index = -1)
|
||||||
{
|
{
|
||||||
if (_renderer)
|
if (_renderer)
|
||||||
{
|
{
|
||||||
|
@ -157,6 +162,12 @@ namespace Coffee.UIExtensions
|
||||||
_lastBounds = new Bounds();
|
_lastBounds = new Bounds();
|
||||||
enabled = false;
|
enabled = false;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ModifiedMaterial.Remove(_modifiedMaterial);
|
||||||
|
_modifiedMaterial = null;
|
||||||
|
_currentMaterialForRendering = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Set(UIParticle parent, ParticleSystem particleSystem, bool isTrail)
|
public void Set(UIParticle parent, ParticleSystem particleSystem, bool isTrail)
|
||||||
|
@ -167,15 +178,18 @@ namespace Coffee.UIExtensions
|
||||||
gameObject.layer = parent.gameObject.layer;
|
gameObject.layer = parent.gameObject.layer;
|
||||||
|
|
||||||
_particleSystem = particleSystem;
|
_particleSystem = particleSystem;
|
||||||
|
_prewarm = _particleSystem.main.prewarm;
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
if (Application.isPlaying)
|
if (Application.isPlaying)
|
||||||
#endif
|
#endif
|
||||||
if (_particleSystem.isPlaying)
|
|
||||||
{
|
{
|
||||||
_particleSystem.Clear();
|
if (_particleSystem.isPlaying || _prewarm)
|
||||||
_particleSystem.Pause();
|
{
|
||||||
|
_particleSystem.Clear();
|
||||||
|
_particleSystem.Pause();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_prewarm = _particleSystem.main.prewarm;
|
|
||||||
|
|
||||||
_renderer = particleSystem.GetComponent<ParticleSystemRenderer>();
|
_renderer = particleSystem.GetComponent<ParticleSystemRenderer>();
|
||||||
_renderer.enabled = false;
|
_renderer.enabled = false;
|
||||||
|
@ -208,7 +222,7 @@ namespace Coffee.UIExtensions
|
||||||
// No particle to render: Clear mesh.
|
// No particle to render: Clear mesh.
|
||||||
if (
|
if (
|
||||||
!isActiveAndEnabled || !_particleSystem || !_parent || !canvasRenderer || !canvas || !bakeCamera
|
!isActiveAndEnabled || !_particleSystem || !_parent || !canvasRenderer || !canvas || !bakeCamera
|
||||||
|| _parent.meshSharing == UIParticle.MeshSharing.Reprica
|
|| _parent.meshSharing == UIParticle.MeshSharing.Replica
|
||||||
|| !transform.lossyScale.GetScaled(_parent.scale3D).IsVisible() // Scale is not visible.
|
|| !transform.lossyScale.GetScaled(_parent.scale3D).IsVisible() // Scale is not visible.
|
||||||
|| (!_particleSystem.IsAlive() && !_particleSystem.isPlaying) // No particle.
|
|| (!_particleSystem.IsAlive() && !_particleSystem.isPlaying) // No particle.
|
||||||
|| (_isTrail && !_particleSystem.trails.enabled) // Trail, but it is not enabled.
|
|| (_isTrail && !_particleSystem.trails.enabled) // Trail, but it is not enabled.
|
||||||
|
@ -264,7 +278,7 @@ namespace Coffee.UIExtensions
|
||||||
|
|
||||||
// Bake mesh.
|
// Bake mesh.
|
||||||
Profiler.BeginSample("[UIParticleRenderer] Bake Mesh");
|
Profiler.BeginSample("[UIParticleRenderer] Bake Mesh");
|
||||||
if (_isTrail && _parent.canSimulate)
|
if (_isTrail && _parent.canSimulate && 0 < s_CombineInstances[0].mesh.vertices.Length)
|
||||||
{
|
{
|
||||||
_renderer.BakeTrailsMesh(s_CombineInstances[0].mesh, bakeCamera, true);
|
_renderer.BakeTrailsMesh(s_CombineInstances[0].mesh, bakeCamera, true);
|
||||||
}
|
}
|
||||||
|
@ -276,6 +290,18 @@ namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
s_CombineInstances[0].mesh.Clear(false);
|
s_CombineInstances[0].mesh.Clear(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Too many vertices to render.
|
||||||
|
if (65535 <= s_CombineInstances[0].mesh.vertexCount)
|
||||||
|
{
|
||||||
|
s_CombineInstances[0].mesh.Clear(false);
|
||||||
|
UnityEngine.Debug.LogErrorFormat(this,
|
||||||
|
"Too many vertices to render. index={0}, isTrail={1}, vertexCount={2}(>=65535)",
|
||||||
|
_index,
|
||||||
|
_isTrail,
|
||||||
|
s_CombineInstances[0].mesh.vertexCount
|
||||||
|
);
|
||||||
|
}
|
||||||
Profiler.EndSample();
|
Profiler.EndSample();
|
||||||
|
|
||||||
// Combine mesh to transform. ([ParticleSystem local ->] world -> renderer local)
|
// Combine mesh to transform. ([ParticleSystem local ->] world -> renderer local)
|
||||||
|
@ -507,7 +533,9 @@ namespace Coffee.UIExtensions
|
||||||
_prewarm = false;
|
_prewarm = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emitted particles found.
|
// (COMMENT OUT) #231: Sub Emitters option is not work in editor playing
|
||||||
|
/*
|
||||||
|
// Emitted particles found.
|
||||||
if (_prevParticleCount != _particleSystem.particleCount)
|
if (_prevParticleCount != _particleSystem.particleCount)
|
||||||
{
|
{
|
||||||
var size = _particleSystem.particleCount;
|
var size = _particleSystem.particleCount;
|
||||||
|
@ -522,6 +550,7 @@ namespace Coffee.UIExtensions
|
||||||
|
|
||||||
_particleSystem.SetParticles(particles, size);
|
_particleSystem.SetParticles(particles, size);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// get world position.
|
// get world position.
|
||||||
var psTransform = _particleSystem.transform;
|
var psTransform = _particleSystem.transform;
|
||||||
|
|
Loading…
Reference in New Issue