298 lines
8.5 KiB
C#
298 lines
8.5 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEditor;
|
|
using UnityEditor.Experimental.SceneManagement;
|
|
using BF;
|
|
using UnityEditor.SceneManagement;
|
|
|
|
namespace BFEditor
|
|
{
|
|
[InitializeOnLoad]
|
|
[CustomEditor(typeof(EffectHelper))]
|
|
public class EffectHelperInspector : Editor
|
|
{
|
|
EffectHelper helper;
|
|
private bool playing;
|
|
private float runningTime;
|
|
private float speed = 1.0f;
|
|
private const float millisecond = 1 / 60f;
|
|
private float maxDuration = 30f;
|
|
private bool isPause = false;
|
|
private bool isStop = true;
|
|
private ParticleSystem rootParticle;
|
|
|
|
static EffectHelperInspector()
|
|
{
|
|
PrefabStage.prefabSaving += OnPrefabSaved;
|
|
}
|
|
|
|
public static void OnPrefabSaved(GameObject go)
|
|
{
|
|
var effectHelper = go.GetComponent<EffectHelper>();
|
|
if (effectHelper != null)
|
|
{
|
|
updateEffectHelper(go, effectHelper);
|
|
}
|
|
}
|
|
|
|
private static void updateEffectHelper(GameObject go, EffectHelper effectHelper)
|
|
{
|
|
Transform t = effectHelper.transform;
|
|
float dur = getParticleSystemLength(t);
|
|
bool drity = false;
|
|
if (effectHelper.EffectDuration != dur)
|
|
{
|
|
effectHelper.EffectDuration = dur;
|
|
EditorUtility.SetDirty(effectHelper);
|
|
drity = true;
|
|
}
|
|
|
|
var animators = t.GetComponentsInChildren<Animator>(true);
|
|
int animatorCount = animators.Length;
|
|
if (effectHelper.AnimatorCount != animatorCount)
|
|
{
|
|
effectHelper.AnimatorCount = animatorCount;
|
|
EditorUtility.SetDirty(effectHelper);
|
|
drity = true;
|
|
}
|
|
|
|
var trailRenderers = t.GetComponentsInChildren<TrailRenderer>(true);
|
|
int trailRendererCount = trailRenderers.Length;
|
|
if (effectHelper.TrailRendererCount != trailRendererCount)
|
|
{
|
|
effectHelper.TrailRendererCount = trailRendererCount;
|
|
EditorUtility.SetDirty(effectHelper);
|
|
drity = true;
|
|
}
|
|
|
|
ParticleSystem rootP = t.GetComponentInChildren<ParticleSystem>(true);
|
|
if (rootP != null && effectHelper.RootParticle != rootP)
|
|
{
|
|
effectHelper.RootParticle = rootP;
|
|
EditorUtility.SetDirty(effectHelper);
|
|
drity = true;
|
|
}
|
|
|
|
if (drity)
|
|
{
|
|
var prefabStage = PrefabStageUtility.GetPrefabStage(go);
|
|
if (prefabStage != null)
|
|
{
|
|
EditorSceneManager.MarkSceneDirty(prefabStage.scene);
|
|
}
|
|
AssetDatabase.SaveAssets();
|
|
AssetDatabase.Refresh();
|
|
}
|
|
}
|
|
|
|
void OnEnable()
|
|
{
|
|
EditorApplication.update += inspectorUpdate;
|
|
helper = target as EffectHelper;
|
|
}
|
|
|
|
void OnDisable()
|
|
{
|
|
EditorApplication.update -= inspectorUpdate;
|
|
}
|
|
|
|
public override void OnInspectorGUI()
|
|
{
|
|
updateEffectHelper(helper.gameObject, helper);
|
|
|
|
Transform t = helper.gameObject.transform;
|
|
ParticleSystem rootP = t.GetComponentInChildren<ParticleSystem>(true);
|
|
if (!ReferenceEquals(rootP, helper.RootParticle))
|
|
{
|
|
helper.RootParticle = rootP;
|
|
}
|
|
this.rootParticle = helper.RootParticle;
|
|
maxDuration = getParticleSystemLength(t);
|
|
EditorGUILayout.BeginHorizontal();
|
|
if (isStop)
|
|
{
|
|
if (GUILayout.Button("Play"))
|
|
{
|
|
play();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (isPause)
|
|
{
|
|
if (GUILayout.Button("Continue"))
|
|
{
|
|
continuePlay();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (GUILayout.Button("Pause"))
|
|
{
|
|
pause();
|
|
}
|
|
}
|
|
}
|
|
if (GUILayout.Button("Stop"))
|
|
{
|
|
stop();
|
|
}
|
|
EditorGUILayout.EndHorizontal();
|
|
speed = EditorGUILayout.Slider("Speed:", speed, 1f, 0f);
|
|
|
|
showParticleInfo();
|
|
manualUpdate();
|
|
}
|
|
|
|
private void showParticleInfo()
|
|
{
|
|
GUILayout.Space(10);
|
|
GUILayout.BeginHorizontal();
|
|
GUILayout.Label("主粒子:", EditorStyles.label);
|
|
EditorGUI.BeginDisabledGroup(true);
|
|
if(helper.RootParticle == null)
|
|
{
|
|
GameObject go = (GameObject)EditorGUILayout.ObjectField("", null,
|
|
typeof(GameObject), true, GUILayout.Width(140));
|
|
}
|
|
else
|
|
{
|
|
GameObject go = (GameObject)EditorGUILayout.ObjectField("", helper.RootParticle.gameObject,
|
|
typeof(GameObject), true, GUILayout.Width(140));
|
|
}
|
|
EditorGUI.EndDisabledGroup();
|
|
GUILayout.EndHorizontal();
|
|
|
|
GUILayout.BeginHorizontal();
|
|
GUILayout.Label("粒子总持续时间: " + System.Convert.ToString(helper.EffectDuration) + "s", EditorStyles.label);
|
|
GUILayout.EndHorizontal();
|
|
|
|
GUILayout.BeginHorizontal();
|
|
GUILayout.Label("Animator数量: " + System.Convert.ToString(helper.AnimatorCount), EditorStyles.label);
|
|
GUILayout.EndHorizontal();
|
|
|
|
GUILayout.BeginHorizontal();
|
|
GUILayout.Label("拖尾数量: " + System.Convert.ToString(helper.TrailRendererCount), EditorStyles.label);
|
|
GUILayout.EndHorizontal();
|
|
|
|
GUILayout.BeginHorizontal();
|
|
var toggleResult = EditorGUILayout.Toggle("使用角度来翻转特效: ", helper.EulerAnglesFlip);
|
|
if (toggleResult != helper.EulerAnglesFlip)
|
|
{
|
|
Undo.RecordObject(helper, helper.name + "Toggle EulerAnglesFlip");
|
|
helper.EulerAnglesFlip = toggleResult;
|
|
EditorUtility.SetDirty(helper);
|
|
}
|
|
GUILayout.EndHorizontal();
|
|
}
|
|
|
|
private void manualUpdate()
|
|
{
|
|
if (this.rootParticle && !playing)
|
|
{
|
|
this.rootParticle.Simulate(millisecond * speed, true, false);
|
|
SceneView.RepaintAll();
|
|
}
|
|
}
|
|
|
|
private void play()
|
|
{
|
|
if (Application.isPlaying || this.rootParticle == null)
|
|
{
|
|
return;
|
|
}
|
|
playing = true;
|
|
isPause = false;
|
|
isStop = false;
|
|
this.rootParticle.Simulate(0, true, true);
|
|
}
|
|
private void continuePlay()
|
|
{
|
|
if (Application.isPlaying || this.rootParticle == null)
|
|
{
|
|
return;
|
|
}
|
|
playing = true;
|
|
isPause = false;
|
|
isStop = false;
|
|
}
|
|
private void stop()
|
|
{
|
|
if (Application.isPlaying || this.rootParticle == null)
|
|
{
|
|
return;
|
|
}
|
|
playing = false;
|
|
isPause = false;
|
|
isStop = true;
|
|
runningTime = 0;
|
|
this.rootParticle.Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear);
|
|
}
|
|
private void pause()
|
|
{
|
|
if (Application.isPlaying || this.rootParticle == null)
|
|
{
|
|
return;
|
|
}
|
|
playing = false;
|
|
isPause = true;
|
|
this.rootParticle.Stop(true);
|
|
}
|
|
private void inspectorUpdate()
|
|
{
|
|
if (!Application.isPlaying && playing)
|
|
{
|
|
runningTime = runningTime + millisecond * speed;
|
|
update();
|
|
}
|
|
}
|
|
|
|
private void update()
|
|
{
|
|
if (Application.isPlaying || this.rootParticle == null)
|
|
{
|
|
return;
|
|
}
|
|
if (maxDuration > 0 && runningTime >= maxDuration)
|
|
{
|
|
this.stop();
|
|
return;
|
|
}
|
|
this.rootParticle.Simulate(millisecond * speed, true, false, true);
|
|
SceneView.RepaintAll();
|
|
Repaint();
|
|
}
|
|
|
|
private static float getParticleSystemLength(Transform transform)
|
|
{
|
|
ParticleSystem[] particleSystems = transform.GetComponentsInChildren<ParticleSystem>(true);
|
|
float maxDuration = -1;
|
|
foreach (ParticleSystem ps in particleSystems)
|
|
{
|
|
if (ps.emission.enabled)
|
|
{
|
|
if (ps.main.loop)
|
|
{
|
|
continue;
|
|
}
|
|
float dunration = ps.main.duration;
|
|
if (ps.main.startDelay.mode == ParticleSystemCurveMode.TwoConstants)
|
|
{
|
|
dunration += ps.main.startDelay.constantMax;
|
|
}
|
|
else
|
|
{
|
|
dunration += ps.main.startDelay.constant;
|
|
}
|
|
if (dunration > maxDuration)
|
|
{
|
|
maxDuration = dunration;
|
|
}
|
|
}
|
|
}
|
|
return maxDuration;
|
|
}
|
|
}
|
|
}
|