首页 文章

一旦停止播放,就需要禁用粒子系统

提问于
浏览
0

我正在尝试实施一个火焰喷射器 . 我已经为火焰设置了粒子系统 . 它是汇集对象 . 它不是火焰投掷者的孩子 . 当我按下Fire按钮时,粒子系统启动,当按钮启动时,它停止 . 但是出现了一个问题,当玩家移动时,粒子系统不会移动 . 通过添加以下行解决了这个问题

particles.transform.position = transform.GetChild(0).position;

但是我发现了另一个问题,当旋转播放器时(这是一个2D侧面滚动游戏),粒子会立即旋转 . 因此,当玩家改变方向时,当前粒子停止并且激活并播放新粒子 . 但现在问题是每当我按下Fire按钮改变方向时,就会创建新对象 .

我的火焰喷射器的代码是使用UnityEngine;

public class FlameThrower : Gun
{
    private ParticleSystem particles;

    private int direction = 0;
    private bool isFiring = false;

    public override void Update()
    {
        if(shoot)
        {
            InitShoot();
        }
        else
        {
            StopFire();
        }
    }

    public override void InitShoot()
    {
        if(!isFiring)
        {
            SelectDirection();
            Fire();
        }

        //Check direction has changed
        if(direction != playerManager.direction)
        {
            StopFire();
        }

        if(particles != null)
        {
            particles.transform.position = transform.GetChild(0).position;
        }
    }

    public override void Fire()
    {
        isFiring = true;
        direction = playerManager.direction;

        InstantiateParticles(weapon.bulletName, transform.GetChild(0).position, rotation);
    }

    public override void SelectDirection()
    {
        if (playerManager.direction == 1)
        {
            rotation = Quaternion.Euler(transform.rotation.x, transform.rotation.y, -90);
        }
        else if (playerManager.direction == -1)
        {
            rotation = Quaternion.Euler(transform.rotation.x, transform.rotation.y, 90);
        }
    }

    public override void InstantiateParticles(string name, Vector3 position, Quaternion rotation)
    {
        GameObject bullet = ObjectPooler.instance.GetObject(name);

        while (bullet == null)
        {
            ObjectPooler.instance.CreateObject(name);
            bullet = ObjectPooler.instance.GetObject(name);
        }

        if (bullet != null)
        {
            particles = bullet.GetComponent<ParticleSystem>();
            //Set Position and rotation
            bullet.transform.position = position;
            bullet.transform.rotation = rotation;
            bullet.SetActive(true);
            particles.Play();
        }
    }

    private void StopFire()
    {
        if (particles != null)
        {
            isFiring = false;
            particles.Stop();
            if(!particles.isPlaying)
            {
                particles.gameObject.SetActive(false);
                particles = null;
            }
        }
    }
}

问题是在函数StopFire()中它检查粒子是否正在播放 . 如果它没有播放它将禁用Gameobject . 但是那部分没有执行,因为在粒子停止之后很快就会检查它并且它仍然会被播放 . 我希望这个粒子系统一停止播放就会被禁用

2 回答

  • 4

    似乎粒子系统在局部空间中渲染,这就是它与对象一起旋转的原因 .

    Simulation Space 更改为 World .

    enter image description here

    对于另一个问题,如果禁用游戏对象,则已经发射的粒子将消失 . 如果您延迟停用它们(使用Invoke或类似),那么在该延迟内可以发射新粒子 .

    处理此问题的最佳方法是停止发射,而不是停用游戏对象 . 您可以在检查员或代码中执行此操作 . myParticles.emission.enabled

    enter image description here

  • 0
    using UnityEngine;
    
    public class ParticleSystemControllerWindow : MonoBehaviour
    {
    ParticleSystem system
    {
        get
        {
            if (_CachedSystem == null)
                _CachedSystem = GetComponent<ParticleSystem>();
            return _CachedSystem;
        }
    }
    private ParticleSystem _CachedSystem;
    
    public Rect windowRect = new Rect(0, 0, 300, 120);
    
    public bool includeChildren = true;
    
    void OnGUI()
    {
        windowRect = GUI.Window("ParticleController".GetHashCode(), windowRect, DrawWindowContents, system.name);
    }
    
    void DrawWindowContents(int windowId)
    {
        if (system)
        {
            GUILayout.BeginHorizontal();
            GUILayout.Toggle(system.isPlaying, "Playing");
            GUILayout.Toggle(system.isEmitting, "Emitting");
            GUILayout.Toggle(system.isPaused, "Paused");
            GUILayout.EndHorizontal();
    
            GUILayout.BeginHorizontal();
            if (GUILayout.Button("Play"))
                system.Play(includeChildren);
            if (GUILayout.Button("Pause"))
                system.Pause(includeChildren);
            if (GUILayout.Button("Stop Emitting"))
                system.Stop(includeChildren, ParticleSystemStopBehavior.StopEmitting);
            if (GUILayout.Button("Stop & Clear"))
                system.Stop(includeChildren,  ParticleSystemStopBehavior.StopEmittingAndClear);
            GUILayout.EndHorizontal();
    
            includeChildren = GUILayout.Toggle(includeChildren, "Include Children");
    
            GUILayout.BeginHorizontal();
            GUILayout.Label("Time(" + system.time + ")");
            GUILayout.Label("Particle Count(" + system.particleCount + ")");
            GUILayout.EndHorizontal();
        }
        else
            GUILayout.Label("No particle system found");
    
        GUI.DragWindow();
    }
    }
    

    这可以帮助您在播放,暂停和完全停止粒子系统发射粒子方面发挥作用 . 希望我帮忙 .

相关问题