开发中经常需要对粒子特效的尺寸进行调整以适配具体应用场景,而粒子特效往往由多个粒子系统组件(Particle System
)组成,如果逐一调整尺寸会比较麻烦,粒子特效的尺寸也无法通过父节点的缩放统一修改。
因此可以写一个简单的工具类,快速对粒子特效尺寸进行整体调整,原理也很简单,遍历所有节点的粒子系统组件,并记录其原始缩放值(因为特效在设计阶段为了调整效果已经改过缩放值,默认尺寸下缩放并不一定为1),然后乘上调整的缩放系数,得到新的尺寸。
效果:
代码:
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UnityEngine
{
#if UNITY_EDITOR
[CanEditMultipleObjects, CustomEditor(typeof(ParticleScaler))]
public class ParticleScalerEditor : Editor
{
public override void OnInspectorGUI()
{
var scaler = target as ParticleScaler;
if (scaler == null) return;
base.OnInspectorGUI();
GUILayout.Space(10);
// Quick Scale
GUILayout.BeginHorizontal();
GUI.color = Color.white;
for (var i = 0.25f; i <= 16f; i *= 2)
{
var value = i;
var btenScale = GUILayout.Button("x" + i.ToString("F2"));
if (btenScale)
{
scaler.ScaleValue = value;
scaler.Adapter();
}
GUILayout.Space(5);
}
GUILayout.EndHorizontal();
// Quuck Action
GUILayout.BeginHorizontal();
GUI.color = Color.cyan;
var btnReset = GUILayout.Button("Reset");
if (btnReset)
{
scaler.Reset();
scaler.Adapter();
}
GUILayout.Space(5);
GUI.color = Color.red;
var btnRemove = GUILayout.Button("Remove");
if (btnRemove)
{
DestroyImmediate(scaler);
}
GUILayout.EndHorizontal();
}
}
#endif
[DisallowMultipleComponent]
public class ParticleScaler : MonoBehaviour
{
public Vector3 ScaleVector;
public float ScaleValue;
#if UNITY_EDITOR
public ParticleSystem[] Particles { get; protected set; }
private List<ScaleData> _scaleDatas;
private class ScaleData
{
public Transform Transform;
public Vector3 BeginScale = Vector3.one;
}
public void Awake()
{
Reset();
Load();
Adapter();
}
public void OnEnable()
{
Load();
Adapter();
}
public void Reset()
{
ScaleVector = Vector3.one;
ScaleValue = 1f;
}
public void Load()
{
if (_scaleDatas != null) return;
_scaleDatas = new List<ScaleData>();
Particles = GetComponentsInChildren<ParticleSystem>(true);
for (var i = 0; i < Particles.Length; i++)
{
var p = Particles[i];
_scaleDatas.Add(new ScaleData()
{
Transform = p.transform,
BeginScale = p.transform.localScale
});
}
}
public void Adapter()
{
if (_scaleDatas == null)
{
Load();
}
foreach (var data in _scaleDatas)
{
var scale = new Vector3(data.BeginScale.x * ScaleVector.x, data.BeginScale.y * ScaleVector.y, data.BeginScale.z * ScaleVector.z);
scale *= ScaleValue;
data.Transform.localScale = scale;
}
}
public void OnValidate()
{
Adapter();
}
#endif
}
}
以上工具类仅可用于编辑器下对粒子尺寸进行调整,编辑完后需要移除。如果需要在运行时实时调整尺寸,也可以很容易的改出一个运行时特效尺寸适配器来,原理是一样的,这儿就不贴出相应代码了。