Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Fluid Particles interaction Script
#11
(20-11-2020, 01:53 PM)josemendez Wrote: In my case, both blue and yellow particles are killed when in contact with each other. Don't see how it could be otherwise, as diffusion is symmetric: diffusion data is averaged for every particle pair, so if two particles with different diffusion data come in close proximity, they'd both modify their diffusion data, and get removed from the emitter.



This is a compilation error, so it will happen regardless of what scene(s) in the project it is used in. The error says:


So, the compiler can't find a KillParticle() method that accepts a ObiEmitter as argument. The original script is passing an integer (solver.particleToActor[i].indexInActor), thus the only possible way to trigger this error would be to write:

Code:
emitter.KillParticle(emitter);

which ofc does not make any sense. Are you positive that the script isn't modified in any way? Another possibility is that you're using an older version of Obi that does not contain the KillParticle() method.

Obi is aimed at advanced users so it assumes you're familiar with at least basic scripting/programming. If you're not, you have a really steep learning curve ahead :/.


Yup, i was on an older verion... (The proyect i had was in an older version for some reason...) Did a new proyect to try out your code on sample scene (i had deleted the samples scenes on my proyect to save space). Thats why it worked on sample and not on my proyect.. In the new proyect (with the latest version), it dosent appear any fatal error, but it seems to not be killing any particles... Maybe because it dosent have the same names as sample scene?
   
Reply
#12
(20-11-2020, 02:31 PM)JoseCarlos S Wrote: Yup, i was on an older verion... (The proyect i had was in an older version for some reason...) Did a new proyect to try out your code on sample scene (i had deleted the samples scenes on my proyect to save space). Thats why it worked on sample and not on my proyect.. In the new proyect (with the latest version), it dosent appear any fatal error, but it seems to not be killing any particles... Maybe because it dosent have the same names as sample scene?

Object names don't play any role in this. Just make sure the diffusion data for one fluid is (1,0,0,0) and for the other one is (0,0,0,0).

Alternately, you can adapt the script to work with the diffusion data you're using.
Reply
#13
(20-11-2020, 02:45 PM)josemendez Wrote: Object names don't play any role in this. Just make sure the diffusion data for one fluid is (1,0,0,0) and for the other one is (0,0,0,0).

Alternately, you can adapt the script to work with the diffusion data you're using.

But where do i change de difusion data? On the solver? Or the emmiter?

And one last thing, im using the BURST type emmiter, the idea is to spwan ONE set of fluid on each level, how can i make BURST mode only spawn onece? and not spwan on loop each time the particle are destroyed?

Thanks!
Reply
#14
(20-11-2020, 02:53 PM)JoseCarlos S Wrote: But where do i change de difusion data? On the solver? Or the emmiter?

Neither. You change it on the blueprint:
http://obi.virtualmethodstudio.com/tutor...rials.html

Quote:Diffusion Data

There's 4 diffusion channels available. The meaning of these channels is completely up tp you: each one could be temperature, color, viscosity, or any other. The data contained in these 4 channels is smoothed out between particles over time, at a rate determined by the average diffusion property (see above).
Reply
#15
(20-11-2020, 02:53 PM)JoseCarlos S Wrote: And one last thing, im using the BURST type emmiter, the idea is to spwan ONE set of fluid on each level, how can i make BURST mode only spawn onece? and not spwan on loop each time the particle are destroyed?

Just set the emitter's speed to zero once you're done emitting.
Reply
#16
(20-11-2020, 02:57 PM)josemendez Wrote: Just set the emitter's speed to zero once you're done emitting.

Okay, ill take a look at the blueprints, about the emision, i had already tried to change speed to 0 after a 5 second delay once you hit play... but it dosent seem to work, could you write a sample script for that?

Thanks!
Reply
#17
(20-11-2020, 03:11 PM)JoseCarlos S Wrote: i had already tried to change speed to 0 after a 5 second delay once you hit play... but it dosent seem to work, could you write a sample script for that?

There's not much to it, simply:

Quote:emitter.speed = 0;
Reply
#18
(20-11-2020, 03:23 PM)josemendez Wrote: There's not much to it, simply:

I added this code (to the Kill fluid script you passed). But its seems to not be working (it dosent set the speed to 0)... any advice? Thanks!

using UnityEngine;
using Obi;

[RequireComponent(typeof(ObiSolver))]
public class KillFluidOnContact : MonoBehaviour
{
    ObiSolver solver;
    ObiEmitter emitter;
    public float targetTime = 2.0f;


    void Awake()
    {
        solver = GetComponent<ObiSolver>();
        emitter = GetComponent<ObiEmitter>();
     
    }

    private void Update()
    {
        targetTime -= Time.deltaTime;

        if (targetTime <= 0.0f)
        {
            timerEnded();
        }

    }

    void timerEnded()
    {
        emitter.speed = 0;
    }


    void LateUpdate()
    {

       
        if (!isActiveAndEnabled)
            return;

        // iterate over all particles in the solver, looking for particles
        // that have had their diffusion data altered by contact with other particles.
        for (int i = 0; i < solver.particleToActor.Length; ++i)
        {
            // if this particle is part of an actor,
            if (solver.particleToActor[i] != null)
            {
                // if the "user" (aka diffusion) data is not either (1,0,0,0) or (0,0,0,0)
                if (solver.userData[i].x < 0.9f && solver.userData[i].x > 0.1f)
                {
                    // take a reference to the emitter that the particle belongs to, and kill it.
                    var emitter = solver.particleToActor[i].actor as ObiEmitter;
                    emitter.KillParticle(solver.particleToActor[i].indexInActor);
                }
            }
        }

    }
}
Reply
#19
(22-11-2020, 04:35 PM)JoseCarlos S Wrote: I added this code (to the Kill fluid script you passed). But its seems to not be working (it dosent set the speed to 0)... any advice? Thanks!

using UnityEngine;
using Obi;

[RequireComponent(typeof(ObiSolver))]
public class KillFluidOnContact : MonoBehaviour
{
    ObiSolver solver;
    ObiEmitter emitter;
    public float targetTime = 2.0f;


    void Awake()
    {
        solver = GetComponent<ObiSolver>();
        emitter = GetComponent<ObiEmitter>();
     
    }

    private void Update()
    {
        targetTime -= Time.deltaTime;

        if (targetTime <= 0.0f)
        {
            timerEnded();
        }

    }

    void timerEnded()
    {
        emitter.speed = 0;
    }


    void LateUpdate()
    {

       
        if (!isActiveAndEnabled)
            return;

        // iterate over all particles in the solver, looking for particles
        // that have had their diffusion data altered by contact with other particles.
        for (int i = 0; i < solver.particleToActor.Length; ++i)
        {
            // if this particle is part of an actor,
            if (solver.particleToActor[i] != null)
            {
                // if the "user" (aka diffusion) data is not either (1,0,0,0) or (0,0,0,0)
                if (solver.userData[i].x < 0.9f && solver.userData[i].x > 0.1f)
                {
                    // take a reference to the emitter that the particle belongs to, and kill it.
                    var emitter = solver.particleToActor[i].actor as ObiEmitter;
                    emitter.KillParticle(solver.particleToActor[i].indexInActor);
                }
            }
        }

    }
}
Reply
#20
Hi there,

If you run this script, it will result in a NullRefException error (visible in the console), and the script will halt execution.

This is because of this line:

Code:
emitter.speed = 0;

"emitter" will always be null because you only require a component of type ObiSolver to be present:
Code:
[RequireComponent(typeof(ObiSolver))]

But then you try to retrieve a ObiEmitter component, which is more than likely to be absent. So this call to GetComponent will return null:
Code:
emitter = GetComponent<ObiEmitter>();

Easiest fix is to just make the emitter member public, then assign the emitter instance trough the inspector:

Code:
using UnityEngine;
using Obi;

[RequireComponent(typeof(ObiSolver))]
public class KillFluidOnContact : MonoBehaviour
{
    ObiSolver solver;
    public ObiEmitter emitter;
    public float targetTime = 2.0f;

    void Awake()
    {
        solver = GetComponent<ObiSolver>();
    }

    private void Update()
    {
        targetTime -= Time.deltaTime;

        if (targetTime <= 0.0f)
        {
            timerEnded();
        }

    }

    void timerEnded()
    {
        if (emitter != null)
            emitter.speed = 0;
        else Debug.LogWarning("No se ha proporcionado un emisor a este script.");
    }


    void LateUpdate()
    {

        if (!isActiveAndEnabled)
            return;

        // iterate over all particles in the solver, looking for particles
        // that have had their diffusion data altered by contact with other particles.
        for (int i = 0; i < solver.particleToActor.Length; ++i)
        {
            // if this particle is part of an actor,
            if (solver.particleToActor[i] != null)
            {
                // if the "user" (aka diffusion) data is not either (1,0,0,0) or (0,0,0,0)
                if (solver.userData[i].x < 0.9f && solver.userData[i].x > 0.1f)
                {
                    // take a reference to the emitter that the particle belongs to, and kill it.
                    var emitter = solver.particleToActor[i].actor as ObiEmitter;
                    emitter.KillParticle(solver.particleToActor[i].indexInActor);
                }
            }
        }

    }
}

This is basics of the basics, tough. You should train your programming skills a bit further Guiño.
Reply