Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help Modifying Emitter
#1
Hi,

Current emitter kills particles by lifespan. I want emitter to kill by position (For example, if a particle's Y position is below -5).

I managed to kill by that, but now emitter isn't working properly after when a particle is killed. How can I fix this?

Here's my CustomEmitter:

Code:
namespace Obi
{
  [AddComponentMenu("Physics/Obi/Obi Emitter", 850)]
  [ExecuteInEditMode]
  public class CustomObiEmitter : ObiActor
  {
     .
      .
      .

     [SerializeField] private float[] _posYs;
     
     public override void LoadBlueprint(ObiSolver solver)
     {
        .

        _posYs = new float[particleCount];
        for (var i = 0; i < _posYs.Length; ++i)
           _posYs[i] = 1;
       
        .
     }

      .
      .
      .

     protected override void SwapWithFirstInactiveParticle(int index)
     {
        .
        _posYs.Swap(index, activeParticleCount);
     }


     public bool EmitParticle(float offset, float deltaTime)
     {
        .
       
        _posYs[activeParticleCount] = 1;
       
        .
         .
         .
     }


     public override void BeginStep(float stepTime)
     {
         .
         .
         .
       
        for (int i = activeParticleCount - 1; i >= 0; --i)
        {
           _posYs[i] = m_Solver.positions[i].y;

           if (_posYs[i] <= -5)
           {
              KillParticle(i);
           }
        }

        .
         .
         .
       
       
     }
  }
}
Reply
#2
(14-02-2020, 01:59 PM)ilterbilguven Wrote: Hi,

Current emitter kills particles by lifespan. I want emitter to kill by position (For example, if a particle's Y position is below -5).

I managed to kill by that, but now emitter isn't working properly after when a particle is killed. How can I fix this?

Here's my CustomEmitter:

Code:
namespace Obi
{
  [AddComponentMenu("Physics/Obi/Obi Emitter", 850)]
  [ExecuteInEditMode]
  public class CustomObiEmitter : ObiActor
  {
     .
     .
     .

     [SerializeField] private float[] _posYs;
     
     public override void LoadBlueprint(ObiSolver solver)
     {
        .

        _posYs = new float[particleCount];
        for (var i = 0; i < _posYs.Length; ++i)
           _posYs[i] = 1;
       
        .
     }

     .
     .
     .

     protected override void SwapWithFirstInactiveParticle(int index)
     {
        .
        _posYs.Swap(index, activeParticleCount);
     }


     public bool EmitParticle(float offset, float deltaTime)
     {
        .
       
        _posYs[activeParticleCount] = 1;
       
        .
        .
        .
     }


     public override void BeginStep(float stepTime)
     {
        .
        .
        .
       
        for (int i = activeParticleCount - 1; i >= 0; --i)
        {
           _posYs[i] = m_Solver.positions[i].y;

           if (_posYs[i] <= -5)
           {
              KillParticle(i);
           }
        }

        .
        .
        .
       
       
     }
  }
}

Why not simply setting the particle's life to zero when it meets the condition you want (y < -5) instead of modifying the emitter class itself? Huh
Reply
#3
(14-02-2020, 02:59 PM)josemendez Wrote: Why not simply setting the particle's life to zero when it meets the condition you want (y < -5) instead of modifying the emitter class itself?   Huh

Well, that's simple too. I want to keep that as a time-based emitter, mine is position-based.

Anyway, your solution shows same result. To illustrate: I have 2000+ particles. At the beginning (e.g after 50th particle), if a particle hits the condition, emitter stops working properly.
Reply