using UnityEngine;
using UnityEditor;
[ExecuteInEditMode]
public class MyWindow : EditorWindow
{
private GameObject _curEffect;
private float _curValue = 0;
private float _preTime;
private bool _isRun;
private float _totalTime = 3.0f;
private ParticleSystem[] _psList = null;
[MenuItem("Window/My Window")]
static void Init()
{
MyWindow window = (MyWindow)EditorWindow.GetWindow(typeof(MyWindow));
window.Show();
}
void OnEnable()
{
_preTime = Time.realtimeSinceStartup;
EditorApplication.update += EditorUpdate;
}
void Disable()
{
EditorApplication.update -= EditorUpdate;
}
void OnGUI()
{
GameObject obj = EditorGUILayout.ObjectField("object", _curEffect, typeof(GameObject)) as GameObject;
if (obj != _curEffect)
{
_curEffect = obj;
if (_curEffect != null)
{
_psList = _curEffect.GetComponentsInChildren(true);
}
else
{
_psList = null;
}
}
float value = EditorGUILayout.Slider("value", _curValue, 0, _totalTime);
if (value != _curValue)
{
_curValue = value;
foreach (ParticleSystem ps in _psList)
{
ps.Simulate(0, false, true);
ps.time = 0;
ps.Play();
}
for (float i = 0.0f; i < _curValue; i += 0.02f)
{
SimsimulateParticlesForDeltaTime(0.02f);
}
}
if (GUILayout.Button("播放"))
{
if (_psList != null)
{
foreach (ParticleSystem ps in _psList)
{
ps.time = 0;
ps.Play();
}
}
_preTime = Time.realtimeSinceStartup;
_isRun = true;
_curValue = 0;
}
}
/*
// 有问题,用curTime用模拟就有问题
void SimsimulateParticlesForTotoleTime(float curTime)
{
if (_curEffect != null)
{
ParticleSystem[] psList = _curEffect.GetComponentsInChildren(true);
foreach (ParticleSystem ps in psList)
{
ps.Play();
ps.time = 0;
ps.Simulate(curTime, false, true);
}
}
}
*/
// DeltaTime,去模拟不会有问题
void SimsimulateParticlesForDeltaTime(float deltaTime)
{
if (_psList != null)
{
foreach (ParticleSystem ps in _psList)
{
ps.Simulate(deltaTime, false, false);
}
}
}
void EditorUpdate()
{
if (_isRun)
{
float deltaTime = Time.realtimeSinceStartup - _preTime;
_preTime = Time.realtimeSinceStartup;
_curValue += deltaTime;
if (_curValue >= _totalTime)
{
_curValue = 0;
_isRun = false;
Debug.Log("Finish");
}
SimsimulateParticlesForDeltaTime(deltaTime);
//SimsimulateParticlesForTotoleTime(_curValue);
}
SceneView.RepaintAll();
GameViewRepaint(Camera.main);
}
private void GameViewRepaint(Camera camera)
{
if (camera)
{
Rect cameraRect = new Rect(0, 0, UnityEngine.Screen.width, UnityEngine.Screen.height);
Rect cameraOriginalRect = camera.pixelRect;
camera.pixelRect = cameraRect;
camera.Render();
camera.pixelRect = cameraOriginalRect;
}
}
}
The function documentation states:
function Simulate (deltaTime : float) : void
That is, the function parameter is a time delta, a step in time. It is not a certain moment in time.
Physical simulations work based on discrete steps in time. And the stability of many simulations (or rather the error within a simulation) is directly related to the size of a time step you take.
In your code, you're taking increasingly large steps in time. While single particles might put up with that for a while, given a sufficiently large step they might start to become unstable.
Most likely your problem will be resolved by taking a number of fixed time steps of a relatively small size.
public float initTime;
public ParticleEmitter partEmitter;
// Use this for initialization
public float deltaTime = 0.1f;
void Start () {
for (float i = 0.0f; i < initTime; i += deltaTime) {
partEmitter.Simulate(deltaTime);
}
}
I have taken your 0.1f here (a tenth of a second), but this might have to be even somewhat lower.
ParticleSystem.Simulate 的第1个参数,传入的是DeltaTime。