我试图使用ParticleSystem.Emit()
动态地发射粒子,并且无法使Emit()
在Start()
方法之外工作。
我可以在Start()
方法中直接或用单独的方法发射粒子。当尝试在Update()
、LateUpdate()
或FixedUpdate()
中执行同样的操作时,它将不再起作用。
没有报告错误。我报告了update方法中粒子的数量,以确保代码实际运行,它报告了我在Start()
方法中发射的粒子数量。
当试图在更新方法中发射粒子时,我已经尝试过:
Emit()
。Invoke()
的单独方法。我能够检查和改变粒子在Update()
中的位置,所以我不认为我有某种范围问题。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
{
public ParticleSystem aSystem;
private ParticleSystem.Particle[] aParticle;
void Start()
{
aParticle = new ParticleSystem.Particle[aSystem.main.maxParticles];
// Emit particle.
DoEmit();
Debug.Log("Particle Count: " + aSystem.particleCount);
}
void Update()
{
int numParticles = aSystem.GetParticles(aParticle);
Debug.Log("Number of particles: " + numParticles);
for (int i = 0; i < numParticles; i++)
{
if (aParticle[i].position.z > 1)
{
aParticle[i].position = new Vector3(0f,0f,0f);
}
aParticle[i].velocity = new Vector3(0f, 0f, 1f);
}
aSystem.SetParticles(aParticle);
// Emit particle.
DoEmit();
}
void DoEmit()
{
// Configure render settings for particle.
ParticleSystemRenderer aRenderer = aSystem.GetComponent<ParticleSystemRenderer>();
aRenderer.renderMode = ParticleSystemRenderMode.Mesh;
aRenderer.mesh = Resources.Load<Mesh>("vector");
// Configure rest of settings and emit.
var emitParams = new ParticleSystem.EmitParams();
emitParams.startLifetime = 120;
emitParams.position = new Vector3(0.0f, 0.0f, 0.0f);
emitParams.velocity = new Vector3(0.0f, 0.0f, 0.0f);
emitParams.startSize = 1;
aSystem.Emit(emitParams, 1);
aSystem.Play(); // Continue normal emissions
Debug.Log("DoEmit() called!");
}
}
预期结果:沿着+z方向运动的粒子流。
实际结果:一个粒子向+z方向运动。
发布于 2020-12-31 18:11:26
我需要做一些类似的事情,并且发现这个答案在团结论坛上给了我一个非常好的、可靠的解决方案,我已经多次重用和修改了这个解决方案。它是一个粒子池,你可以根据需要发射一个或多个粒子,杀死最后一个粒子,当它达到最大粒子数时再利用它。我想它能达到你想要的效果。我将在这里包含相关的脚本,以供参考(为了清晰起见,我将提供@神器-杰西五颜六色的评论)。
请注意,此脚本是为Unitation2018.x编写的,但到2020.2.1仍运行良好。
工件-杰西的完整的,功能的例子,一个相当通用的粒子池:
using UnityEngine;
[RequireComponent(typeof(ParticleSystem))]
public class ParticlePool : MonoBehaviour
{
private int lastParticleIndex = 0; // keeps track of our oldest particle (for deletion)
// these will all be inited in Initialize() on Start()
private ParticleSystem particleSys; // our object's particle system
private ParticleSystem.Particle[] particles; // our reusable array of particles
private ParticleSystem.EmitParams emitParams; // reusable emitparams
private int maxParticles = 0; // total number of particles in our scene before re-using
private void Awake()
{
Initialize(); // initialize all of our member variables
}
public void CreateParticle(Vector3 position, float size, Vector3 velocity, float angularVelocity)
{
// if we're at our particle count limit, kill our oldest particle.
int activeParticles = particleSys.GetParticles(particles);
/// this thing sucks. Read the Unity docs VERY carefully to understand...
/// basically the parameter (particles) is an out parameter which will
/// write out the existing particles in the particle system to our
/// reusable array. After that, we can directly modify the particles
/// and then when we're done, write the particles back into the
/// particle system with ParticleSystem.SetParticles( particles, count )
if (activeParticles >= maxParticles)
{
// set lifetime to -1 to kill the particle
particles[lastParticleIndex].remainingLifetime = -1;
// we need to reset start lifetime to a normal value, too or the particle will still have infinite lifetime
particles[lastParticleIndex].startLifetime = 1;
lastParticleIndex++; // keep track of oldest particle
if (lastParticleIndex >= maxParticles) lastParticleIndex = 0;
// have to re-write
particleSys.SetParticles(particles, particles.Length); // write those pesky particles back into our ParticleSystem
}
// set up params for this particle, you can use whatever you want (see unity docs for EmitParams for what's available)
emitParams.angularVelocity = angularVelocity;
emitParams.position = position;
emitParams.startSize = size;
emitParams.velocity = velocity;
emitParams.startLifetime = float.MaxValue; // float.MaxValue makes the particle's lifetime infinite
particleSys.Emit(emitParams, 1);
particleSys.Play();
}
void Initialize()
{
if (particleSys == null)
particleSys = GetComponent<ParticleSystem>();
maxParticles = particleSys.main.maxParticles;
if (particles == null || particles.Length < particleSys.main.maxParticles)
particles = new ParticleSystem.Particle[particleSys.main.maxParticles];
}
}
注:在这个例子中的粒子系统是赤裸裸的,带有渲染器。没有循环,没有开始清醒,模拟空间设置为世界。上面的脚本尊重MaxParticles。
https://stackoverflow.com/questions/57877559
复制相似问题