You've already forked ParticleEffectForUGUI
mirror of
https://github.com/mob-sakai/ParticleEffectForUGUI.git
synced 2026-05-14 20:20:06 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4dfcb9075e | ||
|
|
7916056868 | ||
|
|
b87a0a02af | ||
|
|
3052cab41b | ||
|
|
a439248e1a |
@@ -1,3 +1,10 @@
|
|||||||
|
# [4.9.0](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.8.1...v4.9.0) (2024-07-18)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* ParticleAttractor supports multiple ParticleSystems ([3834780](https://github.com/mob-sakai/ParticleEffectForUGUI/commit/3834780fdb43443fe6e1ef89df54d26a24d62a91))
|
||||||
|
|
||||||
## [4.8.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.8.0...v4.8.1) (2024-06-27)
|
## [4.8.1](https://github.com/mob-sakai/ParticleEffectForUGUI/compare/v4.8.0...v4.8.1) (2024-06-27)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
86
README.md
86
README.md
@@ -1,28 +1,60 @@
|
|||||||
# <img alt="UIParticleIcon" src="https://github.com/mob-sakai/ParticleEffectForUGUI/assets/12690315/d76e105e-a840-4f61-a1f6-8cf311c0812d" width="26"/> Particle Effect For UGUI (UI Particle)
|
# <img alt="UIParticleIcon" src="https://github.com/mob-sakai/ParticleEffectForUGUI/assets/12690315/d76e105e-a840-4f61-a1f6-8cf311c0812d" width="26"/> Particle Effect For UGUI (UI Particle) <!-- omit in toc -->
|
||||||
|
|
||||||
This package provides a component to render particle effects for uGUI in Unity 2018.2 or later.
|
|
||||||
The particle rendering is maskable and sortable, without the need for an extra Camera, RenderTexture, or Canvas.
|
|
||||||
|
|
||||||
[](https://openupm.com/packages/com.coffee.ui-particle/)
|
[](https://openupm.com/packages/com.coffee.ui-particle/)
|
||||||
[](https://github.com/mob-sakai/ParticleEffectForUGUI/releases)
|
[](https://github.com/mob-sakai/ParticleEffectForUGUI/releases)
|
||||||
[](https://github.com/mob-sakai/ParticleEffectForUGUI/blob/main/LICENSE.txt)
|
[](https://github.com/mob-sakai/ParticleEffectForUGUI/blob/main/LICENSE.md)
|
||||||

|

|
||||||
|

|
||||||
|

|
||||||

|

|
||||||
[](http://makeapullrequest.com)
|
[](http://makeapullrequest.com)
|
||||||
|
[](https://github.com/mob-sakai/ParticleEffectForUGUI/subscription)
|
||||||
[](https://twitter.com/intent/follow?screen_name=mob_sakai)
|
[](https://twitter.com/intent/follow?screen_name=mob_sakai)
|
||||||
|
|
||||||
<< [📝 Description](#-description) | [🎮 Demo](#-demo) | [⚙ Installation](#-installation) | [🚀 Usage](#-usage) | [🛠 Development Note](#-development-note) | [🤝 Contributing](#-contributing) >>
|
<< [📝 Description](#-description-) | [📌 Key Features](#-key-features) | [🎮 Demo](#-demo) | [⚙ Installation](#-installation) | [🚀 Usage](#-usage) | [🛠 Development Note](#-development-note) | [🤝 Contributing](#-contributing) >>
|
||||||
|
|
||||||
|
## 📝 Description <!-- omit in toc -->
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
This package uses the new APIs `MeshBake/MeshTrailBake` (introduced in Unity 2018.2) to render particles through `CanvasRenderer`.
|
||||||
|
You can render, mask, and sort your `ParticleSystems` for UI without the need for an additional `Camera`, `RenderTexture`, or `Canvas`.
|
||||||
|
|
||||||
|
- [📌 Key Features](#-key-features)
|
||||||
|
- [🎮 Demo](#-demo)
|
||||||
|
- [⚙ Installation](#-installation)
|
||||||
|
- [Install via OpenUPM](#install-via-openupm)
|
||||||
|
- [Install via UPM (with Package Manager UI)](#install-via-upm-with-package-manager-ui)
|
||||||
|
- [Install via UPM (Manually)](#install-via-upm-manually)
|
||||||
|
- [Install as Embedded Package](#install-as-embedded-package)
|
||||||
|
- [🚀 Usage](#-usage)
|
||||||
|
- [Component: UIParticle](#component-uiparticle)
|
||||||
|
- [Basic Usage](#basic-usage)
|
||||||
|
- [Usage with Your Existing ParticleSystem Prefab](#usage-with-your-existing-particlesystem-prefab)
|
||||||
|
- [Usage with `Mask` or `RectMask2D` Component](#usage-with-mask-or-rectmask2d-component)
|
||||||
|
- [Usage with Script](#usage-with-script)
|
||||||
|
- [Component: UIParticleAttractor](#component-uiparticleattractor)
|
||||||
|
- [🛠 Development Note](#-development-note)
|
||||||
|
- [Compares the Baking mesh approach with the conventional approach](#compares-the-baking-mesh-approach-with-the-conventional-approach)
|
||||||
|
- [Performance test results](#performance-test-results)
|
||||||
|
- [🔍 FAQ: Why Are My UIParticles Not Displayed Correctly?](#-faq-why-are-my-uiparticles-not-displayed-correctly)
|
||||||
|
- [Shader Limitation](#shader-limitation)
|
||||||
|
- [Built-in shaders are not supported](#built-in-shaders-are-not-supported)
|
||||||
|
- [(Unity 2018 or 2019) UV.zw components will be discarded](#unity-2018-or-2019-uvzw-components-will-be-discarded)
|
||||||
|
- [(Unity 2018 or 2019) Custom vertex streams](#unity-2018-or-2019-custom-vertex-streams)
|
||||||
|
- [Overheads](#overheads)
|
||||||
|
- [How to Make a Custom Shader to Support `Mask` and `RectMask2D` Component](#how-to-make-a-custom-shader-to-support-mask-and-rectmask2d-component)
|
||||||
|
- [🤝 Contributing](#-contributing)
|
||||||
|
- [Issues](#issues)
|
||||||
|
- [Pull Requests](#pull-requests)
|
||||||
|
- [Support](#support)
|
||||||
|
- [License](#license)
|
||||||
|
- [Author](#author)
|
||||||
|
- [See Also](#see-also)
|
||||||
|
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
## 📝 Description
|
## 📌 Key Features
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
This package uses the new APIs `MeshBake/MeshTrailBake` (introduced in Unity 2018.2) to render particles through CanvasRenderer.
|
|
||||||
You can render, mask, and sort your ParticleSystems for UI without the need for an additional Camera, RenderTexture, or Canvas.
|
|
||||||
|
|
||||||
### Key Features
|
|
||||||
|
|
||||||
* **Easy to use:** The package is ready to use out of the box.
|
* **Easy to use:** The package is ready to use out of the box.
|
||||||
* **Sortable:** Sort particle effects and other UI elements by sibling index.
|
* **Sortable:** Sort particle effects and other UI elements by sibling index.
|
||||||
@@ -83,16 +115,16 @@ _This package requires **Unity 2018.3 or later**._
|
|||||||
```
|
```
|
||||||
- To update the package, use Package Manager UI (`Window > Package Manager`) or run the following command with `@{version}`:
|
- To update the package, use Package Manager UI (`Window > Package Manager`) or run the following command with `@{version}`:
|
||||||
```
|
```
|
||||||
openupm add com.coffee.ui-particle@4.8.0
|
openupm add com.coffee.ui-particle@4.9.0
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Install via UPM (with Package Manager UI)
|
#### Install via UPM (with Package Manager UI)
|
||||||
|
|
||||||
- Click `Window > Package Manager` to open Package Manager UI.
|
- Click `Window > Package Manager` to open Package Manager UI.
|
||||||
- Click `+ > Add package from git URL...` and input the repository URL: `https://github.com/mob-sakai/ParticleEffectForUGUI.git`
|
- Click `+ > Add package from git URL...` and input the repository URL: `https://github.com/mob-sakai/ParticleEffectForUGUI.git`
|
||||||

|

|
||||||
- To update the package, change suffix `#{version}` to the target version.
|
- To update the package, change suffix `#{version}` to the target version.
|
||||||
- e.g. `https://github.com/mob-sakai/ParticleEffectForUGUI.git#4.8.0`
|
- e.g. `https://github.com/mob-sakai/ParticleEffectForUGUI.git#4.9.0`
|
||||||
|
|
||||||
#### Install via UPM (Manually)
|
#### Install via UPM (Manually)
|
||||||
|
|
||||||
@@ -107,7 +139,7 @@ _This package requires **Unity 2018.3 or later**._
|
|||||||
```
|
```
|
||||||
|
|
||||||
- To update the package, change suffix `#{version}` to the target version.
|
- To update the package, change suffix `#{version}` to the target version.
|
||||||
- e.g. `"com.coffee.ui-particle": "https://github.com/mob-sakai/ParticleEffectForUGUI.git#4.8.0",`
|
- e.g. `"com.coffee.ui-particle": "https://github.com/mob-sakai/ParticleEffectForUGUI.git#4.9.0",`
|
||||||
|
|
||||||
#### Install as Embedded Package
|
#### Install as Embedded Package
|
||||||
|
|
||||||
@@ -121,7 +153,7 @@ _This package requires **Unity 2018.3 or later**._
|
|||||||
|
|
||||||
## 🚀 Usage
|
## 🚀 Usage
|
||||||
|
|
||||||
### UIParticle Component
|
### Component: UIParticle
|
||||||
|
|
||||||
`UIParticle` controls the ParticleSystems that are attached to its own game objects and child game objects.
|
`UIParticle` controls the ParticleSystems that are attached to its own game objects and child game objects.
|
||||||
|
|
||||||
@@ -154,7 +186,7 @@ and z-position.
|
|||||||
|
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
#### Basic Usage
|
### Basic Usage
|
||||||
|
|
||||||
1. Select `GameObject/UI/ParticleSystem` to create UIParticle with a ParticleSystem.
|
1. Select `GameObject/UI/ParticleSystem` to create UIParticle with a ParticleSystem.
|
||||||

|

|
||||||
@@ -163,7 +195,7 @@ and z-position.
|
|||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
#### With Your Existing ParticleSystem Prefab
|
### Usage with Your Existing ParticleSystem Prefab
|
||||||
|
|
||||||
1. Select `GameObject/UI/ParticleSystem (Empty)` to create UIParticle.
|
1. Select `GameObject/UI/ParticleSystem (Empty)` to create UIParticle.
|
||||||

|

|
||||||
@@ -172,7 +204,7 @@ and z-position.
|
|||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
#### With `Mask` or `RectMask2D` Component
|
### Usage with `Mask` or `RectMask2D` Component
|
||||||
|
|
||||||
If you want to mask particles, set a stencil-supported shader (such as `UI/UIAdditive`) to the material for
|
If you want to mask particles, set a stencil-supported shader (such as `UI/UIAdditive`) to the material for
|
||||||
ParticleSystem.
|
ParticleSystem.
|
||||||
@@ -184,7 +216,7 @@ section.
|
|||||||
|
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
### Script usage
|
### Usage with Script
|
||||||
|
|
||||||
```cs
|
```cs
|
||||||
// Instantiate ParticleSystem prefab with UIParticle on runtime.
|
// Instantiate ParticleSystem prefab with UIParticle on runtime.
|
||||||
@@ -203,14 +235,14 @@ uiParticle.Stop();
|
|||||||
|
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
### UIParticleAttractor component
|
### Component: UIParticleAttractor
|
||||||
|
|
||||||
`UIParticleAttractor` attracts particles generated by the specified ParticleSystem.
|
`UIParticleAttractor` attracts particles generated by the specified ParticleSystem.
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||
|
|
||||||
- **Particle System**: Attracts particles generated by the specified particle system.
|
- **Particle Systems**: Attracts particles generated by the specified ParticleSystems.
|
||||||
- **Destination Radius**: Once the particle is within the radius, the particle lifetime will become 0, and `OnAttracted`
|
- **Destination Radius**: Once the particle is within the radius, the particle lifetime will become 0, and `OnAttracted`
|
||||||
will be called.
|
will be called.
|
||||||
- **Delay Rate**: Delay to start attracting. It is a percentage of the particle's start lifetime.
|
- **Delay Rate**: Delay to start attracting. It is a percentage of the particle's start lifetime.
|
||||||
@@ -355,7 +387,7 @@ When improving performance, keep the following in mind:
|
|||||||
- Consider a single material, atlasing the sprites, and using `Sprite` mode in the `Texture Sheet Animation` module
|
- Consider a single material, atlasing the sprites, and using `Sprite` mode in the `Texture Sheet Animation` module
|
||||||
in the ParticleSystem.
|
in the ParticleSystem.
|
||||||
|
|
||||||
### How to Make a Custom Shader to Support Mask/RectMask2D Component
|
### How to Make a Custom Shader to Support `Mask` and `RectMask2D` Component
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Shader tips</summary>
|
<summary>Shader tips</summary>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Coffee.UIParticleExtensions;
|
using Coffee.UIParticleExtensions;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Events;
|
using UnityEngine.Events;
|
||||||
@@ -6,7 +7,7 @@ using UnityEngine.Events;
|
|||||||
namespace Coffee.UIExtensions
|
namespace Coffee.UIExtensions
|
||||||
{
|
{
|
||||||
[ExecuteAlways]
|
[ExecuteAlways]
|
||||||
public class UIParticleAttractor : MonoBehaviour
|
public class UIParticleAttractor : MonoBehaviour, ISerializationCallbackReceiver
|
||||||
{
|
{
|
||||||
public enum Movement
|
public enum Movement
|
||||||
{
|
{
|
||||||
@@ -22,8 +23,12 @@ namespace Coffee.UIExtensions
|
|||||||
}
|
}
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
|
[HideInInspector]
|
||||||
private ParticleSystem m_ParticleSystem;
|
private ParticleSystem m_ParticleSystem;
|
||||||
|
|
||||||
|
[SerializeField]
|
||||||
|
private List<ParticleSystem> m_ParticleSystems = new List<ParticleSystem>();
|
||||||
|
|
||||||
[Range(0.1f, 10f)]
|
[Range(0.1f, 10f)]
|
||||||
[SerializeField]
|
[SerializeField]
|
||||||
private float m_DestinationRadius = 1;
|
private float m_DestinationRadius = 1;
|
||||||
@@ -45,7 +50,7 @@ namespace Coffee.UIExtensions
|
|||||||
[SerializeField]
|
[SerializeField]
|
||||||
private UnityEvent m_OnAttracted;
|
private UnityEvent m_OnAttracted;
|
||||||
|
|
||||||
private UIParticle _uiParticle;
|
private List<UIParticle> _uiParticles = new List<UIParticle>();
|
||||||
|
|
||||||
public float destinationRadius
|
public float destinationRadius
|
||||||
{
|
{
|
||||||
@@ -84,25 +89,46 @@ namespace Coffee.UIExtensions
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The target ParticleSystem to attract.
|
/// The target ParticleSystems to attract. Use <see cref="AddParticleSystem"/> and
|
||||||
|
/// <see cref="RemoveParticleSystem"/> to modify the list.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
#if UNITY_EDITOR
|
public IReadOnlyList<ParticleSystem> particleSystems => m_ParticleSystems;
|
||||||
public new ParticleSystem particleSystem
|
|
||||||
#else
|
public void AddParticleSystem(ParticleSystem ps)
|
||||||
public ParticleSystem particleSystem
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
get => m_ParticleSystem;
|
if (m_ParticleSystems == null)
|
||||||
set
|
|
||||||
{
|
{
|
||||||
m_ParticleSystem = value;
|
m_ParticleSystems = new List<ParticleSystem>();
|
||||||
ApplyParticleSystem();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var i = m_ParticleSystems.IndexOf(ps);
|
||||||
|
if (0 <= i) return; // Already added: skip
|
||||||
|
|
||||||
|
m_ParticleSystems.Add(ps);
|
||||||
|
_uiParticles.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveParticleSystem(ParticleSystem ps)
|
||||||
|
{
|
||||||
|
if (m_ParticleSystems == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var i = m_ParticleSystems.IndexOf(ps);
|
||||||
|
if (i < 0) return; // Not found. skip
|
||||||
|
|
||||||
|
m_ParticleSystems.RemoveAt(i);
|
||||||
|
_uiParticles.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
UpgradeIfNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnEnable()
|
private void OnEnable()
|
||||||
{
|
{
|
||||||
ApplyParticleSystem();
|
|
||||||
UIParticleUpdater.Register(this);
|
UIParticleUpdater.Register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,85 +139,96 @@ namespace Coffee.UIExtensions
|
|||||||
|
|
||||||
private void OnDestroy()
|
private void OnDestroy()
|
||||||
{
|
{
|
||||||
_uiParticle = null;
|
_uiParticles = null;
|
||||||
m_ParticleSystem = null;
|
m_ParticleSystems = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Attract()
|
internal void Attract()
|
||||||
{
|
{
|
||||||
if (m_ParticleSystem == null) return;
|
// Collect UIParticle if needed (same size as m_ParticleSystems)
|
||||||
|
CollectUIParticlesIfNeeded();
|
||||||
|
|
||||||
var count = m_ParticleSystem.particleCount;
|
for (var particleIndex = 0; particleIndex < this.m_ParticleSystems.Count; particleIndex++)
|
||||||
if (count == 0) return;
|
|
||||||
|
|
||||||
var particles = ParticleSystemExtensions.GetParticleArray(count);
|
|
||||||
m_ParticleSystem.GetParticles(particles, count);
|
|
||||||
|
|
||||||
var dstPos = GetDestinationPosition();
|
|
||||||
for (var i = 0; i < count; i++)
|
|
||||||
{
|
{
|
||||||
// Attracted
|
var particleSystem = m_ParticleSystems[particleIndex];
|
||||||
var p = particles[i];
|
|
||||||
if (0f < p.remainingLifetime && Vector3.Distance(p.position, dstPos) < m_DestinationRadius)
|
|
||||||
{
|
|
||||||
p.remainingLifetime = 0f;
|
|
||||||
particles[i] = p;
|
|
||||||
|
|
||||||
if (m_OnAttracted != null)
|
// Skip: The ParticleSystem is not active
|
||||||
|
if (particleSystem == null || !particleSystem.gameObject.activeInHierarchy) continue;
|
||||||
|
|
||||||
|
// Skip: No active particles
|
||||||
|
var count = particleSystem.particleCount;
|
||||||
|
if (count == 0) continue;
|
||||||
|
|
||||||
|
var particles = ParticleSystemExtensions.GetParticleArray(count);
|
||||||
|
particleSystem.GetParticles(particles, count);
|
||||||
|
|
||||||
|
var uiParticle = _uiParticles[particleIndex];
|
||||||
|
var dstPos = this.GetDestinationPosition(uiParticle, particleSystem);
|
||||||
|
for (var i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
// Attracted
|
||||||
|
var p = particles[i];
|
||||||
|
if (0f < p.remainingLifetime && Vector3.Distance(p.position, dstPos) < this.m_DestinationRadius)
|
||||||
{
|
{
|
||||||
try
|
p.remainingLifetime = 0f;
|
||||||
|
particles[i] = p;
|
||||||
|
|
||||||
|
if (this.m_OnAttracted != null)
|
||||||
{
|
{
|
||||||
m_OnAttracted.Invoke();
|
try
|
||||||
}
|
{
|
||||||
catch (Exception e)
|
this.m_OnAttracted.Invoke();
|
||||||
{
|
}
|
||||||
Debug.LogException(e);
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
// Calc attracting time
|
||||||
|
var delayTime = p.startLifetime * this.m_DelayRate;
|
||||||
|
var duration = p.startLifetime - delayTime;
|
||||||
|
var time = Mathf.Max(0, p.startLifetime - p.remainingLifetime - delayTime);
|
||||||
|
|
||||||
|
// Delay
|
||||||
|
if (time <= 0) continue;
|
||||||
|
|
||||||
|
// Attract
|
||||||
|
p.position = this.GetAttractedPosition(p.position, dstPos, duration, time);
|
||||||
|
p.velocity *= 0.5f;
|
||||||
|
particles[i] = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calc attracting time
|
particleSystem.SetParticles(particles, count);
|
||||||
var delayTime = p.startLifetime * m_DelayRate;
|
|
||||||
var duration = p.startLifetime - delayTime;
|
|
||||||
var time = Mathf.Max(0, p.startLifetime - p.remainingLifetime - delayTime);
|
|
||||||
|
|
||||||
// Delay
|
|
||||||
if (time <= 0) continue;
|
|
||||||
|
|
||||||
// Attract
|
|
||||||
p.position = GetAttractedPosition(p.position, dstPos, duration, time);
|
|
||||||
p.velocity *= 0.5f;
|
|
||||||
particles[i] = p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ParticleSystem.SetParticles(particles, count);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Vector3 GetDestinationPosition()
|
private Vector3 GetDestinationPosition(UIParticle uiParticle, ParticleSystem particleSystem)
|
||||||
{
|
{
|
||||||
var isUI = _uiParticle && _uiParticle.enabled;
|
var isUI = uiParticle && uiParticle.enabled;
|
||||||
var psPos = m_ParticleSystem.transform.position;
|
var psPos = particleSystem.transform.position;
|
||||||
var attractorPos = transform.position;
|
var attractorPos = transform.position;
|
||||||
var dstPos = attractorPos;
|
var dstPos = attractorPos;
|
||||||
var isLocalSpace = m_ParticleSystem.IsLocalSpace();
|
var isLocalSpace = particleSystem.IsLocalSpace();
|
||||||
|
|
||||||
if (isLocalSpace)
|
if (isLocalSpace)
|
||||||
{
|
{
|
||||||
dstPos = m_ParticleSystem.transform.InverseTransformPoint(dstPos);
|
dstPos = particleSystem.transform.InverseTransformPoint(dstPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isUI)
|
if (isUI)
|
||||||
{
|
{
|
||||||
var inverseScale = _uiParticle.parentScale.Inverse();
|
var inverseScale = uiParticle.parentScale.Inverse();
|
||||||
var scale3d = _uiParticle.scale3DForCalc;
|
var scale3d = uiParticle.scale3DForCalc;
|
||||||
dstPos = dstPos.GetScaled(inverseScale, scale3d.Inverse());
|
dstPos = dstPos.GetScaled(inverseScale, scale3d.Inverse());
|
||||||
|
|
||||||
// Relative mode
|
// Relative mode
|
||||||
if (_uiParticle.positionMode == UIParticle.PositionMode.Relative)
|
if (uiParticle.positionMode == UIParticle.PositionMode.Relative)
|
||||||
{
|
{
|
||||||
var diff = _uiParticle.transform.position - psPos;
|
var diff = uiParticle.transform.position - psPos;
|
||||||
diff.Scale(scale3d - inverseScale);
|
diff.Scale(scale3d - inverseScale);
|
||||||
diff.Scale(scale3d.Inverse());
|
diff.Scale(scale3d.Inverse());
|
||||||
dstPos += diff;
|
dstPos += diff;
|
||||||
@@ -237,25 +274,59 @@ namespace Coffee.UIExtensions
|
|||||||
return Vector3.MoveTowards(current, target, speed);
|
return Vector3.MoveTowards(current, target, speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ApplyParticleSystem()
|
private void CollectUIParticlesIfNeeded()
|
||||||
{
|
{
|
||||||
_uiParticle = null;
|
if (m_ParticleSystems.Count == 0 || _uiParticles.Count != 0) return;
|
||||||
if (m_ParticleSystem == null)
|
|
||||||
{
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
if (Application.isPlaying)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
Debug.LogError("No particle system attached to particle attractor script", this);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
// Expand capacity
|
||||||
|
if (_uiParticles.Capacity < m_ParticleSystems.Capacity)
|
||||||
|
{
|
||||||
|
_uiParticles.Capacity = m_ParticleSystems.Capacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
_uiParticle = m_ParticleSystem.GetComponentInParent<UIParticle>(true);
|
// Find UIParticle that controls the ParticleSystem
|
||||||
if (_uiParticle && !_uiParticle.particles.Contains(m_ParticleSystem))
|
for (var i = 0; i < m_ParticleSystems.Count; i++)
|
||||||
{
|
{
|
||||||
_uiParticle = null;
|
var ps = m_ParticleSystems[i];
|
||||||
|
if (ps == null)
|
||||||
|
{
|
||||||
|
_uiParticles.Add(null);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var uiParticle = ps.GetComponentInParent<UIParticle>(true);
|
||||||
|
_uiParticles.Add(uiParticle.particles.Contains(ps) ? uiParticle : null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
private void OnValidate()
|
||||||
|
{
|
||||||
|
_uiParticles.Clear();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void ISerializationCallbackReceiver.OnBeforeSerialize()
|
||||||
|
{
|
||||||
|
UpgradeIfNeeded();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ISerializationCallbackReceiver.OnAfterDeserialize()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpgradeIfNeeded()
|
||||||
|
{
|
||||||
|
// Multiple ParticleSystems support: from 'm_ParticleSystem' to 'm_ParticleSystems'
|
||||||
|
if (m_ParticleSystem != null)
|
||||||
|
{
|
||||||
|
if (!m_ParticleSystems.Contains(m_ParticleSystem))
|
||||||
|
{
|
||||||
|
m_ParticleSystems.Add(m_ParticleSystem);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ParticleSystem = null;
|
||||||
|
Debug.Log($"Upgraded!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,11 @@ namespace Coffee.UIExtensions.Demo
|
|||||||
|
|
||||||
public void EnableAnimations(bool flag)
|
public void EnableAnimations(bool flag)
|
||||||
{
|
{
|
||||||
|
#if UNITY_2023_1_OR_NEWER
|
||||||
|
foreach (var animator in FindObjectsByType<Animator>(FindObjectsInactive.Include, FindObjectsSortMode.None))
|
||||||
|
#else
|
||||||
foreach (var animator in FindObjectsOfType<Animator>())
|
foreach (var animator in FindObjectsOfType<Animator>())
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
animator.enabled = flag;
|
animator.enabled = flag;
|
||||||
}
|
}
|
||||||
@@ -79,7 +83,11 @@ namespace Coffee.UIExtensions.Demo
|
|||||||
|
|
||||||
public void UIParticle_Scale(float scale)
|
public void UIParticle_Scale(float scale)
|
||||||
{
|
{
|
||||||
|
#if UNITY_2023_1_OR_NEWER
|
||||||
|
foreach (var uip in FindObjectsByType<UIParticle>(FindObjectsInactive.Include, FindObjectsSortMode.None))
|
||||||
|
#else
|
||||||
foreach (var uip in FindObjectsOfType<UIParticle>())
|
foreach (var uip in FindObjectsOfType<UIParticle>())
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
uip.scale = scale;
|
uip.scale = scale;
|
||||||
}
|
}
|
||||||
@@ -87,7 +95,11 @@ namespace Coffee.UIExtensions.Demo
|
|||||||
|
|
||||||
public void ParticleSystem_WorldSpaseSimulation(bool flag)
|
public void ParticleSystem_WorldSpaseSimulation(bool flag)
|
||||||
{
|
{
|
||||||
|
#if UNITY_2023_1_OR_NEWER
|
||||||
|
foreach (var p in FindObjectsByType<ParticleSystem>(FindObjectsInactive.Include, FindObjectsSortMode.None))
|
||||||
|
#else
|
||||||
foreach (var p in FindObjectsOfType<ParticleSystem>())
|
foreach (var p in FindObjectsOfType<ParticleSystem>())
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
var main = p.main;
|
var main = p.main;
|
||||||
main.simulationSpace = flag
|
main.simulationSpace = flag
|
||||||
@@ -123,7 +135,11 @@ namespace Coffee.UIExtensions.Demo
|
|||||||
|
|
||||||
public void ParticleSystem_SetScale(float scale)
|
public void ParticleSystem_SetScale(float scale)
|
||||||
{
|
{
|
||||||
|
#if UNITY_2023_1_OR_NEWER
|
||||||
|
foreach (var ps in FindObjectsByType<ParticleSystem>(FindObjectsInactive.Include, FindObjectsSortMode.None))
|
||||||
|
#else
|
||||||
foreach (var ps in FindObjectsOfType<ParticleSystem>())
|
foreach (var ps in FindObjectsOfType<ParticleSystem>())
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
ps.transform.localScale = new Vector3(scale, scale, scale);
|
ps.transform.localScale = new Vector3(scale, scale, scale);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,12 +42,12 @@ TextureImporter:
|
|||||||
compressionQuality: 50
|
compressionQuality: 50
|
||||||
spriteMode: 1
|
spriteMode: 1
|
||||||
spriteExtrude: 1
|
spriteExtrude: 1
|
||||||
spriteMeshType: 1
|
spriteMeshType: 0
|
||||||
alignment: 0
|
alignment: 0
|
||||||
spritePivot: {x: 0.5, y: 0.5}
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
spritePixelsToUnits: 100
|
spritePixelsToUnits: 100
|
||||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
spriteGenerateFallbackPhysicsShape: 1
|
spriteGenerateFallbackPhysicsShape: 0
|
||||||
alphaUsage: 1
|
alphaUsage: 1
|
||||||
alphaIsTransparency: 1
|
alphaIsTransparency: 1
|
||||||
spriteTessellationDetail: -1
|
spriteTessellationDetail: -1
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ TextureImporter:
|
|||||||
generateCubemap: 6
|
generateCubemap: 6
|
||||||
cubemapConvolution: 0
|
cubemapConvolution: 0
|
||||||
seamlessCubemap: 0
|
seamlessCubemap: 0
|
||||||
textureFormat: 1
|
textureFormat: 4
|
||||||
maxTextureSize: 2048
|
maxTextureSize: 2048
|
||||||
textureSettings:
|
textureSettings:
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
@@ -42,12 +42,12 @@ TextureImporter:
|
|||||||
compressionQuality: 50
|
compressionQuality: 50
|
||||||
spriteMode: 1
|
spriteMode: 1
|
||||||
spriteExtrude: 1
|
spriteExtrude: 1
|
||||||
spriteMeshType: 1
|
spriteMeshType: 0
|
||||||
alignment: 0
|
alignment: 0
|
||||||
spritePivot: {x: 0.5, y: 0.5}
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
spritePixelsToUnits: 100
|
spritePixelsToUnits: 100
|
||||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
spriteGenerateFallbackPhysicsShape: 1
|
spriteGenerateFallbackPhysicsShape: 0
|
||||||
alphaUsage: 1
|
alphaUsage: 1
|
||||||
alphaIsTransparency: 1
|
alphaIsTransparency: 1
|
||||||
spriteTessellationDetail: -1
|
spriteTessellationDetail: -1
|
||||||
|
|||||||
@@ -42,12 +42,12 @@ TextureImporter:
|
|||||||
compressionQuality: 50
|
compressionQuality: 50
|
||||||
spriteMode: 1
|
spriteMode: 1
|
||||||
spriteExtrude: 1
|
spriteExtrude: 1
|
||||||
spriteMeshType: 1
|
spriteMeshType: 0
|
||||||
alignment: 0
|
alignment: 0
|
||||||
spritePivot: {x: 0.5, y: 0.5}
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
spritePixelsToUnits: 100
|
spritePixelsToUnits: 100
|
||||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
spriteGenerateFallbackPhysicsShape: 1
|
spriteGenerateFallbackPhysicsShape: 0
|
||||||
alphaUsage: 0
|
alphaUsage: 0
|
||||||
alphaIsTransparency: 1
|
alphaIsTransparency: 1
|
||||||
spriteTessellationDetail: -1
|
spriteTessellationDetail: -1
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ TextureImporter:
|
|||||||
generateCubemap: 6
|
generateCubemap: 6
|
||||||
cubemapConvolution: 0
|
cubemapConvolution: 0
|
||||||
seamlessCubemap: 0
|
seamlessCubemap: 0
|
||||||
textureFormat: -1
|
textureFormat: 4
|
||||||
maxTextureSize: 2048
|
maxTextureSize: 2048
|
||||||
textureSettings:
|
textureSettings:
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
@@ -42,12 +42,12 @@ TextureImporter:
|
|||||||
compressionQuality: 50
|
compressionQuality: 50
|
||||||
spriteMode: 1
|
spriteMode: 1
|
||||||
spriteExtrude: 1
|
spriteExtrude: 1
|
||||||
spriteMeshType: 1
|
spriteMeshType: 0
|
||||||
alignment: 0
|
alignment: 0
|
||||||
spritePivot: {x: 0.5, y: 0.5}
|
spritePivot: {x: 0.5, y: 0.5}
|
||||||
spritePixelsToUnits: 100
|
spritePixelsToUnits: 100
|
||||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||||
spriteGenerateFallbackPhysicsShape: 1
|
spriteGenerateFallbackPhysicsShape: 0
|
||||||
alphaUsage: 1
|
alphaUsage: 1
|
||||||
alphaIsTransparency: 1
|
alphaIsTransparency: 1
|
||||||
spriteTessellationDetail: -1
|
spriteTessellationDetail: -1
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "com.coffee.ui-particle",
|
"name": "com.coffee.ui-particle",
|
||||||
"displayName": "UI Particle",
|
"displayName": "UI Particle",
|
||||||
"description": "This package provides a component to render particle effects for uGUI.\nThe particle rendering is maskable and sortable, without the need for an extra Camera, RenderTexture, or Canvas.",
|
"description": "This package provides a component to render particle effects for uGUI.\nThe particle rendering is maskable and sortable, without the need for an extra Camera, RenderTexture, or Canvas.",
|
||||||
"version": "4.8.1",
|
"version": "4.9.0",
|
||||||
"unity": "2018.2",
|
"unity": "2018.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
Reference in New Issue
Block a user