模拟粒子系统(ParticleSystem.Simulate)

来源:互联网 发布:cortana是什么软件 编辑:程序博客网 时间:2024/05/11 04:37
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<ParticleSystem>(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<ParticleSystem>(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 initializationpublic 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。




1 0