Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Liquid-to-Liquid Collision
#1
I am developing a chemical experiment environment using VR.
My plan is below.
When user mixes liquid A and liquid B, after that, its mixed liquid is displayed as a percentage; 70% or more is "perfect", 40% or more is "successful", and under 39% is "Failed" respectively.
Also, if liquid A is mixed with liquid C, an explosion is happened and "Failed" is displayed.

However, I made, installed and runed the scripts, nothing happened on VR. I think the reason why I cannot get the collision between particles.
However, I am not sure how to modify the script.
If you know the solution. Could you assist me?

Reference: Obi Fluid's sample "Maze", "Obi Manual" http://obi.virtualmethodstudio.com/tutor...rials.html Assets I'm using: SteamVR Plugin, SAColliderBuilder, Obi Fluid Version of Unity: Unity 2019.4

I am looking forward to hearing your answer.

Sincerely yours,


Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using Obi;

[RequireComponent(typeof(ObiEmitter))]
public class Chemicalreaction : MonoBehaviour
{
    [System.Serializable]
    public class ScoreChangeEvent : UnityEvent<int, int> { }

    public List<ParticleCollisionEvent> collisionEvents;

    public ObiSolver solver;
    public ObiEmitter emitterA;
    public ObiEmitter emitterB;
    public ObiEmitter emitterC;
    public ObiCollider finishLine;

    public Text completionLabel;
    public Text mixLabel;
    public Text finishLabel;
    public Text Gameover;

    HashSet<int> finishedParticles = new HashSet<int>();
    HashSet<int> coloredParticles = new HashSet<int>();

    void Start()
    {
        solver.OnParticleCollision += Solver_OnParticleCollision;

        collisionEvents = new List<ParticleCollisionEvent>();
    }

    private void OnDestory()
    {
        solver.OnParticleCollision -= Solver_OnParticleCollision;

    }


    private void Solver_OnParticleCollision(ObiSolver s, Obi.ObiSolver.ObiCollisionEventArgs e)
    {
        var world = ObiColliderWorld.GetInstance();
        foreach (Oni.Contact contact in e.contacts)
        {
            ObiSolver.ParticleInActor pa = solver.particleToActor[contact.particle];
            if (contact.distance < 0.01f)
            {
                var col = world.colliderHandles[contact.other].owner;
                if (emitterB.GetComponent<ObiEmitter>() == pa.actor)
                {
                    if (coloredParticles.Add(contact.particle))
                        UpdateScore(finishedParticles.Count, coloredParticles.Count);
                }
                else if (emitterC.GetComponent<ObiEmitter>() == pa.actor)
                {
                    if (coloredParticles.Add(contact.particle))
                        Gameover.text = "Failed";
                }
                else if (finishLine == col)
                {
                    if (finishedParticles.Add(contact.particle))
                        UpdateScore(finishedParticles.Count, coloredParticles.Count);
                }
            }
        }
    }

    public void UpdateScore(int finishedParticles, int coloredParticles)
    {
        int completion = Mathf.CeilToInt(finishedParticles / 600.0f * 100);
        int mix = Mathf.CeilToInt(coloredParticles / 600.0f * 100);

        completionLabel.text = completion + "% Completed";
        mixLabel.text = mix + "% Mixed";

        if (completion > 50)
        {
            if (mix > 70)
            {
                finishLabel.text = "Perfect!";
            }
            else if (mix > 40)
            {
                finishLabel.text = "Successful";
            }
            else
            {
                finishLabel.text = "Failed";
            }
            finishLabel.gameObject.SetActive(true);
        }

    }
}
Reply
#2
You misunderstood how fluid works: Fluid particles do not collide with each other. Only solid particles (granulars) do.

Fluid particles interact with each other trough density constraints, and can exchange property values via diffusion.

Take a look at the FluidMaze sample scene measures tints fluids and measures its "purity": when a particle collides with a solid block, the blocks' color is transferred to the solver.userData array. This data is diffused across neighboring particles during simulation.
Reply
#3
(14-01-2021, 04:41 PM)josemendez Wrote: You misunderstood how fluid works: Fluid particles do not collide with each other. Only solid particles (granulars) do.

Fluid particles interact with each other trough density constraints, and can exchange property values via diffusion.

Take a look at the FluidMaze sample scene measures tints fluids and measures its "purity": when a particle collides with a solid block, the blocks' color is transferred to the solver.userData array. This data is diffused across neighboring particles during simulation.
Thanks for the reply.
Does this mean that something like the plan I am working on is impossible?
Also, for example, is it feasible to put a solid in a liquid, and when it comes in contact with the liquid, the liquid will change color and the solid will gradually decrease in size?
(I'm using a translation site. Sorry if this is hard to understand.)
Reply
#4
(15-01-2021, 03:02 PM)gotou Wrote: Does this mean that something like the plan I am working on is impossible?

if I understood it correctly, it is completely possible to do what you want. You just need to use diffusion instead of relying on collisions between particles (which won't happen for fluids).

(15-01-2021, 03:02 PM)gotou Wrote: Also, for example, is it feasible to put a solid in a liquid, and when it comes in contact with the liquid, the liquid will change color and the solid will gradually decrease in size?

This is exactly what the FluidMaze sample scene does (minus the solid gradually decreasing in size, which can be done just by scaling it). Check its components to see how it's done.
Reply