Unity 编辑器下用时间轴控制播放粒子

在Unity编辑器的Scene视图进行控制播放粒子ParticleSystem,可以借助方法Simulate

先看效果

在这里插入图片描述

代码

两个脚本: EditParticleSystem.csEditParticleSystemInspector.cs
其中EditParticleSystemInspector.cs放在Editor目录中
然后粒子物体挂EditParticleSystem脚本即可

// EditParticleSystem.cs
using UnityEngine;

public class EditParticleSystem : MonoBehavIoUr
{
}
// EditParticleSystemInspector.cs 
using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(EditParticleSystem))]
public class EditParticleSystemInspector : Editor
{
    /// <summary>
    /// 滑动杆的当前时间
    /// </summary>
    private float m_CurTime;
    
    /// <summary>
    /// 当前是否是预览播放状态
    /// </summary>
    private bool m_Playing;

    /// <summary>
    /// 当前运行时间
    /// </summary>
    private float m_RunningTime;
    
    /// <summary>
    /// 上一次系统时间
    /// </summary>
    private double m_PrevIoUsTime;

    /// <summary>
    /// 滑动杆总长度
    /// </summary>
    private const float kDuration = 30f;

    private ParticleSystem m_ParticleSystem;

    private EditParticleSystem editAnimator { get { return target as EditParticleSystem; } }

    private ParticleSystem particleSystem
    {
        get { return m_ParticleSystem ?? (m_ParticleSystem = editAnimator.GetComponentInChildren<ParticleSystem>()); }
    }

    void OnEnable()
    {
        m_PrevIoUsTime = EditorApplication.timeSinceStartup;
        EditorApplication.update += inspectorUpdate;
    }

    void Ondisable()
    {
        EditorApplication.update -= inspectorUpdate;
    }

    public override void OnInspectorGUI()
    {
        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("Play"))
        {
            play();
        }
        if (GUILayout.Button("Stop"))
        {
            stop();
        }
        EditorGUILayout.EndHorizontal();
        m_CurTime = EditorGUILayout.Slider("Time:", m_CurTime, 0f, kDuration);
        manualUpdate();
    }

    /// <summary>
    /// 进行预览播放
    /// </summary>
    private void play()
    {
        if (Application.isPlaying || particleSystem == null)
        {
            return;
        }

        m_RunningTime = 0f;
        m_Playing = true;
    }

    /// <summary>
    /// 停止预览播放
    /// </summary>
    private void stop()
    {
        if (Application.isPlaying || particleSystem == null)
        {
            return;
        }

        m_Playing = false;
        m_CurTime = 0f;
    }

    /// <summary>
    /// 预览播放状态下的更新
    /// </summary>
    private void update()
    {
        if (Application.isPlaying || particleSystem == null)
        {
            return;
        }

        if (m_RunningTime >= kDuration)
        {
            m_Playing = false;
            return;
        }

        particleSystem.Simulate(m_RunningTime, true);
        SceneView.RepaintAll();
        Repaint();

        m_CurTime = m_RunningTime;
    }

    /// <summary>
    /// 非预览播放状态下,通过滑杆来播放当前动画帧
    /// </summary>
    private void manualUpdate()
    {
        if (particleSystem && !m_Playing)
        {
            particleSystem.Simulate(m_CurTime, true);
            SceneView.RepaintAll();
        }
    }

    private void inspectorUpdate()
    {
        var delta = EditorApplication.timeSinceStartup - m_PrevIoUsTime;
        m_PrevIoUsTime = EditorApplication.timeSinceStartup;

        if (!Application.isPlaying && m_Playing)
        {
            m_RunningTime = Mathf.Clamp(m_RunningTime + (float)delta, kDuration);
            update();
        }
    }
}

相关文章

前言 本文记录unity3D开发环境的搭建 unity安装 unity有中文...
前言 有时候我们希望公告牌跟随镜头旋转永远平行面向屏幕,同...
前言 经过一段时间的学习与实际开发,unity3D也勉强算是强行...
前言 在unity中我们常用的获取鼠标点击的方法有: 1、在3D场...
前言 在之前的例子中,我们都没有用到unity的精髓,例如地形...
这篇文章将为大家详细讲解有关Unity3D中如何通过Animator动画...