Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Why are fluid particles jumping around when simulating in local space?
#1
Hi there,

Do you know why the fluid particles are moving when i am moving the solver transform through the editor and simulate in local space is checked with 0 velocity?

The solver object also has several obi colliders attached to it.

Reply
#2
(06-08-2019, 08:37 AM)bobby Wrote: Hi there,

Do you know why the fluid particles are moving when i am moving the solver transform through the editor and simulate in local space is checked with 0 velocity?

The solver object also has several obi colliders attached to it.


Hi,

The collider position when you drag them around is updated in Update(), but the simulation takes place in FixedUpdate() which takes place earlier in the frame. So this means colliders move after the solver has finished the simulation for the current frame, pushing the particles around the next frame. Try moving the solver in FixedUpdate (note that this should be done in your own code, as you cannot modify Unity's translate gizmos behavior), and setting the update order to AfterFixedUpdate.
Reply
#3
(06-08-2019, 08:49 AM)josemendez Wrote: Hi,

The collider position when you drag them around is updated in Update(), but the simulation takes place in FixedUpdate() which takes place earlier in the frame. So this means colliders move after the solver has finished the simulation for the current frame, pushing the particles around the next frame. Try moving the solver in FixedUpdate (note that this should be done in your own code, as you cannot modify Unity's translate gizmos behavior), and setting the update order to AfterFixedUpdate.

Thank you for the quick response, I will try that.
Reply
#4
(06-08-2019, 09:20 AM)bobby Wrote: Thank you for the quick response, I will try that.

Hi there, it didn't work.

The particles are still jumping around. I changed the update mode to "After Fixed Update" and wrote a script to update the transform inside FixedUpdate:

    private void FixedUpdate()
    {

        if (Input.GetMouseButtonDown(0))
        {
            startMousePos = Input.mousePosition;
        }
        else if (Input.GetMouseButton(0))
        {
            var dir = (Input.mousePosition - startMousePos) / Screen.dpi / 10;

            transform.position += new Vector3(dir.x, 0, dir.y);
        }
    }

(06-08-2019, 10:57 AM)bobby Wrote: Hi there, it didn't work.

The particles are still jumping around. I changed the update mode to "After Fixed Update" and wrote a script to update the transform inside FixedUpdate:

    private void FixedUpdate()
    {

        if (Input.GetMouseButtonDown(0))
        {
            startMousePos = Input.mousePosition;
        }
        else if (Input.GetMouseButton(0))
        {
            var dir = (Input.mousePosition - startMousePos) / Screen.dpi / 10;

            transform.position += new Vector3(dir.x, 0, dir.y);
        }
    }

Interesting. I set the update mode to Late Update and it works now.
Reply
#5
(06-08-2019, 10:57 AM)bobby Wrote: Hi there, it didn't work.

The particles are still jumping around. I changed the update mode to "After Fixed Update" and wrote a script to update the transform inside FixedUpdate:

    private void FixedUpdate()
    {

        if (Input.GetMouseButtonDown(0))
        {
            startMousePos = Input.mousePosition;
        }
        else if (Input.GetMouseButton(0))
        {
            var dir = (Input.mousePosition - startMousePos) / Screen.dpi / 10;

            transform.position += new Vector3(dir.x, 0, dir.y);
        }
    }


Interesting. I set the update mode to Late Update and it works now.

LateUpdate should not be used unless it is completely unavoidable, as it does not use a fixed timestep (although it tries to, by applying a low-pass filter on the render timestep) and so the results are highly unphysical. As a rule of thumb physics should always be updated in FixedUpdate. A better alternative would be to subscribe to the start of the solver's frame, and perform the movement there. Here's a sample script, that should be attached to the solver:

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

[RequireComponent(typeof(ObiSolver))]
public class Mover : MonoBehaviour
{
   ObiSolver solver;
   public float speed = 1;

   void Awake()
   {
       solver = GetComponent<ObiSolver>();
       solver.OnFrameBegin += Move;
   }

    private void OnDestroy()
    {
       solver.OnFrameEnd -= Move;
    }

    void Move(object sender, EventArgs eventArgs)
   {
       transform.Translate(Vector3.left * Time.deltaTime * speed);
   }
}
Reply