我正在尝试实施一个火焰喷射器。我已经为火焰设置了粒子系统。它是汇集的对象。它不是火焰投掷者的孩子。当我按下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。但是那部分没有执行,因为在粒子停止后它很快被检查并且它仍然会被播放。我希望这个粒子系统一旦停止播放就会被禁用
答案 0 :(得分:4)
似乎粒子系统在局部空间中渲染,这就是它与对象一起旋转的原因。
将Simulation Space
更改为World
。
对于另一个问题,如果禁用游戏对象,则已经发射的粒子将消失。如果你延迟停用它们(使用Invoke或类似的),那么在那个延迟中可以发出新的粒子。
处理此问题的最佳方法是停止发射,而不是停用游戏对象。您可以在检查员或代码中执行此操作。 myParticles.emission.enabled
答案 1 :(得分: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();
}
}
这可以帮助您在播放,暂停和完全停止粒子系统发射粒子方面发挥作用。 希望我能帮忙。