Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Generating emitters on scene programatically
#1
Hello,

I have been playing around with ObiFluids for a game I am making. I am having some trouble being able to programatically create emitters actors on the scene. I followed the procedure found here: (http://obi.virtualmethodstudio.com/tutor...ctors.html)

Using the procedure in that link I am running a co-routine inside my Update function to create an emitter at certain points in time (checking for previous co-routine to finish before starting next)

The only additional step I added to the procedure in the link is:
Array.Resize<ObiParticleRenderer>(ref Camera.main.GetComponent<ObiFluidRenderer>().particleRenderers, Camera.main.GetComponent<ObiFluidRenderer>().particleRenderers.Length+1);
Camera.main.GetComponent<ObiFluidRenderer>().particleRenderers[Camera.main.GetComponent<ObiFluidRenderer>().particleRenderers.Length-1] = emitterCreated.GetComponent<ObiParticleRenderer>();

to add the particle renderer to the camera.

The emitter is created on the scene yet no fluid are emitted.

I get the following error: 
NullReferenceException: Object reference not set to an instance of an object
Obi.ObiActor.PushDataToSolver (Obi.ParticleData data) (at Assets/Obi/Scripts/Actors/ObiActor.cs:385)
Obi.ObiActor.AddToSolver (System.Object info) (at Assets/Obi/Scripts/Actors/ObiActor.cs:278)
Obi.ObiEmitter.AddToSolver (System.Object info) (at Assets/Obi/Scripts/Actors/ObiEmitter.cs:125)
Obi.ObiActor.Start () (at Assets/Obi/Scripts/Actors/ObiActor.cs:150)

I am reusing the same solver for all the emitters created. 

I can post full code but it is basically the one from the link.

Any help is appreciated.
Reply
#2
(29-10-2018, 08:02 AM)ddematheu Wrote: Hello,

I have been playing around with ObiFluids for a game I am making. I am having some trouble being able to programatically create emitters actors on the scene. I followed the procedure found here: (http://obi.virtualmethodstudio.com/tutor...ctors.html)

Using the procedure in that link I am running a co-routine inside my Update function to create an emitter at certain points in time (checking for previous co-routine to finish before starting next)

The only additional step I added to the procedure in the link is:
Array.Resize<ObiParticleRenderer>(ref Camera.main.GetComponent<ObiFluidRenderer>().particleRenderers, Camera.main.GetComponent<ObiFluidRenderer>().particleRenderers.Length+1);
Camera.main.GetComponent<ObiFluidRenderer>().particleRenderers[Camera.main.GetComponent<ObiFluidRenderer>().particleRenderers.Length-1] = emitterCreated.GetComponent<ObiParticleRenderer>();

to add the particle renderer to the camera.

The emitter is created on the scene yet no fluid are emitted.

I get the following error: 
NullReferenceException: Object reference not set to an instance of an object
Obi.ObiActor.PushDataToSolver (Obi.ParticleData data) (at Assets/Obi/Scripts/Actors/ObiActor.cs:385)
Obi.ObiActor.AddToSolver (System.Object info) (at Assets/Obi/Scripts/Actors/ObiActor.cs:278)
Obi.ObiEmitter.AddToSolver (System.Object info) (at Assets/Obi/Scripts/Actors/ObiEmitter.cs:125)
Obi.ObiActor.Start () (at Assets/Obi/Scripts/Actors/ObiActor.cs:150)

I am reusing the same solver for all the emitters created. 

I can post full code but it is basically the one from the link.

Any help is appreciated.

Hi there,

That's a bug, thanks for reporting it.

In ObiActor line 385, add the following check:
&& restPositions != null
So that it looks like:
Code:
if ((data & ParticleData.REST_POSITIONS) != 0 && restPositions != null && i < restPositions.Length)

Here's the runtime emitter creation code we tested, with the previous change it works properly. Note that you still should add these lines:

Array.Resize<ObiParticleRenderer>(ref Camera.main.GetComponent<ObiFluidRenderer>().particleRenderers, Camera.main.GetComponent<ObiFluidRenderer>().particleRenderers.Length+1);
Camera.main.GetComponent<ObiFluidRenderer>().particleRenderers[Camera.main.GetComponent<ObiFluidRenderer>().particleRenderers.Length-1] = emitterCreated.GetComponent<ObiParticleRenderer>();

if you want to use a fluid renderer, instead of the default particle renderer.

Code:
public class CreateEmitter : MonoBehaviour
{
    private ObiEmitter emitter;
    public ObiSolver solver;
    public ObiParticleRenderer renderer;

    public void MakeEmitter()
    {
        GameObject emitterObject = new GameObject("emt",typeof(ObiEmitter),
                                                        typeof(ObiParticleRenderer));

        renderer = emitterObject.GetComponent<ObiParticleRenderer>();
        renderer.shader = Shader.Find("Obi/Particles");

        emitter = emitterObject.GetComponent<ObiEmitter>();
        emitter.Solver = solver;
        emitter.AddToSolver(null);
    }

    public void Update(){
        if (Input.GetKeyDown(KeyCode.Space)){
            MakeEmitter();
        }
    }
}
Reply