Search Unity

Physics Water 2D Tool - GPU based ripple water, realistic buoyancy, water flow & animation

Discussion in 'Tools In Progress' started by Nicrom, Feb 23, 2015.

  1. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Update on the next version. Water2D Tool will have the option to create a 2.5D water that will have all the properties of the 2D water.



     
    Last edited: Aug 6, 2015
    Too-Nerd-To-Die likes this.
  2. Too-Nerd-To-Die

    Too-Nerd-To-Die

    Joined:
    Apr 28, 2014
    Posts:
    44
    very interesting, in the middle with the touch of a rigidbody would be possible to make waves starting from the point of contact?

    to reproduce the same effect 2.5D I used a water2D in front and one behind to the bottom with decorative settings and in the middle a quad with texture and a shader that move the offset in the X axis.

    http://puu.sh/jrRp1/2b6b621143.jpg
     
    Nicrom likes this.
  3. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Nice.
    At the moment the waves are generated only at the white line, but waves at the point of contact with the water are something I want to implement. Also the horizontal and vertical water are 2 separate sub-meshes as a result each will have it's own material assigned to it.
     
    Last edited: Aug 6, 2015
    Too-Nerd-To-Die likes this.
  4. BTStone

    BTStone

    Joined:
    Mar 10, 2012
    Posts:
    1,422
    When will 1.2 hit the store and what features have you planed for the future of this asset? :)
     
  5. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    I hope to finish the 1.2 version in about a week or 2. There is at least one feature that will not be included in 1.2, but I intend to add it in the future. I hope to eventually bring this tool to a point where you will be able to create a 2D water that resembles the one found in "Limbo" as for the 2.5D water I want it to be something like in the games "The Cave" and "Rayman Legends".
     
    Last edited: Aug 7, 2015
    BTStone, MinhDao and Too-Nerd-To-Die like this.
  6. MinhDao

    MinhDao

    Joined:
    Oct 28, 2013
    Posts:
    155
    Very interesting. It's exactly what i finding. Keep it up
     
    Nicrom likes this.
  7. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Finally started working with water shaders. It's a water feature I wanted to add for a long time.

     
  8. MinhDao

    MinhDao

    Joined:
    Oct 28, 2013
    Posts:
    155
    Cool, it's really amazing. Do you test it on mobile?
     
    Nicrom likes this.
  9. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    I did not test the version I am currently working, on any mobile device yet. I posted some test result for the version 1.0 in a previous post on this forum thread.
     
    Too-Nerd-To-Die and MinhDao like this.
  10. jeffweber

    jeffweber

    Joined:
    Dec 17, 2009
    Posts:
    616
    That does look really nice!
     
    Too-Nerd-To-Die and Nicrom like this.
  11. Too-Nerd-To-Die

    Too-Nerd-To-Die

    Joined:
    Apr 28, 2014
    Posts:
    44
    The new updates are great, it is scheduled for release them?
    If you need help with testing, I can help as well.
     
  12. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    I plan to finish this update by the end of the next week, but won't submit it immediately for review. I want to improve the visual appearance of the demo scenes with better art for the 2D examples as well as create new demo scenes for the 2.5D water.

    I will post a new reply here when all the features are implemented, so those that don't want to wait for the 1.2v to be available on the Asset Store can send me their invoice number and I will send the 1.2v by email to them.
     
    Too-Nerd-To-Die likes this.
  13. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Added the option to dynamically change or animate the amplitude and phase of a sine wave.

     
  14. jeffweber

    jeffweber

    Joined:
    Dec 17, 2009
    Posts:
    616
    Hey Nicrom.

    This looks good, but it would be nice if waves could be less uniform.

    I think my needs are probably not the norm, but what I'd like is the ability to "wiggle" one end of the water up and down at some frequency and let the wave propagate along the water until it hits the far end of the water and "bounces back".

    Imagine a rope with one end attached to a wall and a person holding the other end. If the person moves his arm up and down at different speeds and too different heights he can create waves of varying speeds and size.

    This is the control I need for my current game. Not sure this is possible with your current API and not sure how useful this would be to others. One possibility I thought of is to add this functionality myself after you release your latest version.

    I have this working with my own water/wave system, but my system is not very optimized at the moment and I'd prefer to use a system that is continuously updated and supported so I can spend my time on other things in my game. :)

    Let me know what you think. Is this something I could implement myself? All I really need is the ability to move the end point of the water up and down and have the wave's spring system do the rest.

    On a side note: One other difference between my wave algo and yours is I don't use a spring system for the surface. I use a mathematical algorithm so simulate the waves. It's a side-view version of this: http://freespace.virgin.net/hugo.elias/graphics/x_water.htm

    -Jeff
     
  15. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Before, when the "Sine Waves" option was selected, the velocity of every surface vertex was influenced by a sine function, now I added a new option that limits the ability of the sine function to change the velocity only for the first surface vertex or the last. Additionally you will be able to control the velocity of the first or last surface vertex using a public field that can be animated using the animator or by script. The result can be seen below.


    I will take a look at this article and see if I can add and option that controls the velocity of the first or last vertex in a way that is more random.
     
    Too-Nerd-To-Die likes this.
  16. jeffweber

    jeffweber

    Joined:
    Dec 17, 2009
    Posts:
    616
    Cool. This looks much closer to what I need. Especially if I can control the end points myself.

    The article I linked to just shows a different way to model waves without relying on a spring dampener system. I find it a bit simpler to implement, but not sure it's better or worse than the spring-dampener system you and most other 2D water systems use. Just thought it might interest you.

    Here is the code I use to update my waves using this system. The _resultWave, _previousWave, and CurrentWave are simple arrays of floats that track the height of the wave at each point along the surface. The CurrentWave array is used to set the vertex points of the water mesh. (Note this is just the wave making code, not the more complicated buoyancy code)

    Code (CSharp):
    1.         private void UpdateWater()
    2.         {
    3.             if (_resultWave.Length != _waterMesh.segments + 1) return;
    4.            
    5.             for (int i = 1; i < _waterMesh.segments - 1; i++)
    6.             {
    7.                 _resultWave[i] = (CurrentWave[i - 1] + CurrentWave[i + 1]) - _previousWave[i];
    8.                 _resultWave[i] = _resultWave[i] - _resultWave[i] * waveDampening;
    9.             }
    10.  
    11.             CurrentWave.CopyTo(_previousWave, 0);
    12.             _resultWave.CopyTo(CurrentWave, 0);
    13.  
    14.             _vertices = _waterMesh.Mesh.vertices;
    15.             for (int i = 0; i < _waterMesh.segments + 1; i++)
    16.             {
    17.                 _vertices[i].y = CurrentWave[i];
    18.                 _waterPolygon[i].x = _vertices[i].x + _waterWorldPosition.x;
    19.                 _waterPolygon[i].y = _vertices[i].y + _waterWorldPosition.y;
    20.             }
    21.             _waterMesh.Mesh.vertices = _vertices;
    22.         }
    To make a wave I simply modify the height of any given item in the "CurrentWave" array and it will propagate fairly realistically across the water.

    As I said I only show you this in case you are interested. Not suggesting you implement this. :) What you have looks great.

    When might I be able to get my hands on this version?

    -Jeff
     
    Nicrom and Too-Nerd-To-Die like this.
  17. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Thanks for the code snippet, I will take a look at it and maybe add it as an alternative option to the springs.
     
  18. jeffweber

    jeffweber

    Joined:
    Dec 17, 2009
    Posts:
    616
    Hey Nicrom,

    Was looking at your code and saw this in a few places:

    Code (CSharp):
    1. floatingObjects2D[cIndex].GetComponent<Collider2D>().bounds.min.y
    I was under the impression calling GetComponent should not be called every loop due to performance issues.

    Is GetComponent required in this instance since "floatingObjects2D" is already an array of Collider2D's?

    Code (CSharp):
    1. private List<Collider2D> floatingObjects2D;
    Seems redundant but I'm not able to dig in and take a look right now as I'm at work and don't have access to Unity. Just thought I'd point it out incase it's something that could improve performance.

    I also see it being used here:

    Code (CSharp):
    1. boxColl2D = floatingObjects2D[cIndex].GetComponent<BoxCollider2D>();
    Seems here you should be able to just compare types or something instead of doing a GetComponent.... again, not sure if I'm missing something but thought I'd point it out just in case.

    -Jeff
     
  19. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    This is part of the new Unity5 API. Before I was using
    Code (CSharp):
    1. floatingObjects2D[cIndex].bounds.min.y
    but Unity updated the code to
    Code (CSharp):
    1. floatingObjects2D[cIndex].GetComponent<Collider2D>().bounds.min.y
     
    Last edited: Aug 20, 2015
  20. jeffweber

    jeffweber

    Joined:
    Dec 17, 2009
    Posts:
    616
    Hmm. Ok, was not aware of that. I wonder if the perf. is similar. Hope so.
     
  21. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Created a Demo Scene for the 2.5D Water. To interact with the levers press CTRL. WebGL Demo Scene

    NOTE: With the releace of the 1.2 version the price will be changed from 10$ to 15$.

     
    Last edited: Aug 29, 2015
    Too-Nerd-To-Die likes this.
  22. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Just submitted version 1.2 for review. Check the updated WebGL or Web Player demo scenes to see the new features. You can click and drag the objects in all the demo scenes, except the "2D Water" and "2.5D Water" scenes. To interact with the levers press CTRL.
     
    Too-Nerd-To-Die likes this.
  23. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Destroying objects that are in the water.
    If you tried to destroy an object that is in the water you most likely got lots of errors after the object is destroyed. This is happening because Water2D Tool keeps an internal list of all the colliders that enter the water trigger collider. When you destroy an object, the reference is not removed, as a result this reference points to a null object and Unity generates an error when some code tries to access this collider.

    Bellow are 2 options you can use in cases when you need the objects to be destroyed.

    First Option
    For example, lets say you want to destroy objects that are below a certain water level. Create a empty object, add a collider to it and make it a trigger collider. Then add Destroyer script to it.

    Code (CSharp):
    1. public class Destroyer : MonoBehaviour
    2. {
    3.     void OnTriggerEnter2D(Collider2D other)
    4.     {
    5.         DestroyObject destroy = other.GetComponent<DestroyObject>();
    6.         destroy.DestroyThisObject();
    7.     }
    8. }
    Create a new script Called DestroyObject and add it to the object you want to be destroyed.
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class DestroyObject : MonoBehaviour
    5. {
    6.     // Makes sure the object is destroyed after a certain number of frames.
    7.     private int destroyAfter = 0;
    8.     // The Rigidbody2D of the object.
    9.     private Rigidbody2D objectRigidbody;
    10.  
    11.     // Should this object be destroyed?
    12.     public bool destroyObject = false;
    13.  
    14.     void Start()
    15.     {
    16.         objectRigidbody = GetComponent<Rigidbody2D>();
    17.     }
    18.  
    19.     void FixedUpdate()
    20.     {
    21.         if (destroyObject)
    22.         {
    23.             if (destroyAfter < 3)
    24.                 destroyAfter++;
    25.  
    26.             // The object is destroyed after a few frames to make sure it's collider
    27.             // reference was removed from the Water2D_Simulation lists.
    28.             if (destroyAfter > 2)
    29.             {
    30.                 Destroy(gameObject);
    31.             }
    32.         }
    33.     }
    34.  
    35.     // Initiates the object destruction.
    36.     public void DestroyThisObject()
    37.     {
    38.         destroyObject = true;
    39.         // This will make sure the object is not affected by the gravity.
    40.         objectRigidbody.isKinematic = true;
    41.  
    42.         // The object is moved some distance so it does not appear in the camera view.
    43.         transform.Translate(Vector3.up * 20);
    44.     }
    45. }
    46.  
    When the object enters the trigger collider of the object that has the Destroyer script, the DestroyThisObject() method will be called and the object will be moved away from the camera view and destroyed after a few frames. It is destroyed a few frames later to make sure it's collider reference is removed from the Water2D_Simulation lists by the OnTriggerExit2D method from the Water2D_Simulation scrip.

    Second Option
    In the Destroyer script place this code.
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using Water2DTool;
    4.  
    5. public class Destroyer : MonoBehaviour
    6. {
    7.     public Water2D_Simulation water2D_Sim;
    8.  
    9.     void OnTriggerEnter2D(Collider2D other)
    10.     {
    11.         water2D_Sim.RemoveCollider2DFromList(other);
    12.  
    13.         Destroy(other.gameObject);
    14.     }
    15. }
    This script has a public variable where you place a reference to the water object.
    Next add the method RemoveCollider2DFromList in the Water2D_Simulation script. This method has the same code as the OnTriggerExit2D method.
    Code (CSharp):
    1. public void RemoveCollider2DFromList(Collider2D other)
    2.         {
    3.             if (floatingObjects2D.Contains(other))
    4.             {
    5.                 if (other.tag == "Player")
    6.                     onTriggerPlayerDetected = false;
    7.  
    8.                 floatingObjects2D.Remove(other);
    9.  
    10.                 if (tempObj2D.Contains(other))
    11.                     tempObj2D.Remove(other);
    12.             }
    13.         }
    When an object enters the trigger of the object that has the Destroyer script, the RemoveCollider2DFromList() method will be called and all the references of this object will be removed. Then the object is destroyed.

    I would recommend you to use the first option. I am not sure how Unity works internally, or how it handles multi threads, but if the RemoveCollider2DFromList() is called while the code from the Water2D_Simulation script is executed, it will most likely generate an error.
     
    Last edited: Sep 11, 2015
    Too-Nerd-To-Die likes this.
  24. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Water2D Tool version 1.2 is live now on Unity Asset Store.
     
    Last edited: Sep 11, 2015
    Too-Nerd-To-Die likes this.
  25. David_Don_13

    David_Don_13

    Joined:
    Apr 14, 2015
    Posts:
    1
    Hi Nicrom,

    Congrats on making such a fantastic looking plugin. I'm very interested in purchasing this but first I've a couple of q's:

    - Have you tested this on mobile yet?
    - What are the draw calls for simulation like?
    - Can you simulate pouring water into more water?
    - Can water levels be raised dynamically through code?

    Please get back to me when you get a moment and well done again!
     
    Nicrom likes this.
  26. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Hi. Thanks.
    1. In the first page of this thread there is a post I made with the results I got on a Sony Xperia J and and a Galaxy S4. S4 - 60 fps with occasional drops to 58 fps.
      Xperia J - between 10 to 20 fps.
    2. A single draw call if the Standard shader or the Unlit transparent shader is used, 2 draw calls if you use the new water shader that comes with version 1.2.
    3. Well you can create a particle system and just animate the water.
    4. Yes. If you look at the demo scenes there are a couple of animation examples. Also there is a video tutorial that showcases how the water is animated. The link to the demo scenes and video tutorials are on the first page of this thread.
     
    Last edited: Sep 30, 2015
  27. giorgos_gs

    giorgos_gs

    Joined:
    Apr 23, 2014
    Posts:
    623
    can I use the 2.5d water to create a beach with waves in a 2d adventure game somehow?
     
  28. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    I'm not sure it would work well. If you are using an orthographic camera, even if you enable the 2.5D water, you won't see a difference between the 2D and 2.5D water.
     
  29. VectorNector

    VectorNector

    Joined:
    May 22, 2013
    Posts:
    62
    I'm trying to achieve this but I can't seem to get my cube to float on the 2D with 2D collider. It has box collider and a rigidbody attached to it. Gravity is enabled too. What am I doing wrong?
     
  30. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    2D and 3D colliders do not interact with each other. So if you created a water object with a 2D collider, the objects that you want to float in the water must have a 2D collider too. The same thing applies to 3D colliders.
     
    Last edited: Nov 8, 2015
  31. zenGarden

    zenGarden

    Joined:
    Mar 30, 2013
    Posts:
    4,538
    Can we have multiple water areas in some 2.5D level ? Can we only activate some the water systems that are visible when the camera is near ?

    When your asset will be on sales :D ?
     
  32. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Can you be a little more specific on what you mean by water areas?

    I haven't encountered problems with disabling and enabling a water object. One way you could do this is to make the water object a child of an object that has a trigger collider attached to it and a script that checks if the player entered it's collider. When the player is detected just enable the water object. This is just an example as I am sure there are better ways to do it.

    Not sure when a sale could take place. It all depends on the Asset Store team. It may be in the near future, but at the same time it may never be on a sale.
     
  33. zenGarden

    zenGarden

    Joined:
    Mar 30, 2013
    Posts:
    4,538
    Can we put in a level multiple water objects , like Mario game you have water areas and no water at all on some other parts of a same level.
    Can we have multiple water volumes per level like this one you posted ?


    I'll see when i will need it i will just buy it.
     
    Nicrom likes this.
  34. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    There is no limit to how many water objects you can have in a scene. If you look at the WebGL demo scenes, you will see that many have more than one water object.
     
    zenGarden likes this.
  35. immeasurability

    immeasurability

    Joined:
    Apr 22, 2014
    Posts:
    125
  36. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Where you resizing the water using the 4 handles, while in Play Mode? If so, while in play mode you are not supposed to use the 4 handles. If you want it's size to change you have to animate the water. Here is a video on how to do it


    The shader that comes with the water doesn't have reflections, only refractions (this is what makes the objects in the water look distorted). I tested the shader on a Galaxy S4 and it works without problems.
     
    zenGarden likes this.
  37. zenGarden

    zenGarden

    Joined:
    Mar 30, 2013
    Posts:
    4,538
    I think the actual water asset is to have some fast render for all mobiles, without expensive gpu effects like reflections or shore effects.
     
  38. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    I terms of performance, I tried to optimize the tool as much as possible so that it works on different devices. There are a couple of options that allow the user to get a better performance: like decreasing the number of triangles the mesh has or using the Linear Buoyancy. While the water shaders with reflections and refractions are nice, on mobile devices, especially on the middle and low end devices is better to use a simple transparent shader.
     
    Too-Nerd-To-Die and zenGarden like this.
  39. Zyblade

    Zyblade

    Joined:
    Jul 1, 2014
    Posts:
    141
    Thanks for adding the 2.5D water feature!
    What are the z-segments for? It doesn't seem to change the spring behavior. Is it possible to implement an additional z-loop to make the vertices wave independent to the z-axis? So if you add z-segments the water will also wave in the z-direction too. This would need to have more colliders in that direction of course. z-segments.count x collider lines parallel.
     
    Nicrom likes this.
  40. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Enable the Show Mesh toggle to see what the Z Segments field does. It basically determines the number of rows of quads that the horizontal mesh has (look in the Water2D_Guide PDF file to know which is the horizontal and vertical mesh). Yes, at the moment the Z Segments do not effect the springs in any way.

    You mean circle waves that propagate away from a point on the horizontal mesh, like in a 3D water (something like the RealWater asset)? If so, that is something I want to implement in a future update.
     
    Last edited: Nov 27, 2015
    Too-Nerd-To-Die likes this.
  41. zenGarden

    zenGarden

    Joined:
    Mar 30, 2013
    Posts:
    4,538
    Will it be optionnal ? some games won't need it.
     
  42. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Yes, it will be optional. Like with the buoyancy and other water options, you will be able to select the one that fits your game.
     
  43. trueicecold

    trueicecold

    Joined:
    Aug 26, 2014
    Posts:
    5
    Hey Nircom,

    Might be programmatic rather than your plugin, but is there a way to get an indication when an object is floating on water rather than submerged? I want to run some code if an item is floating for X seconds.

    Thanks and congrats on this amazing plugin!
     
  44. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    I'm glad you like it.

    In the Water2D_Simulation script there is a field called "waterLineCurrentGlobalPos". This field represents the global position of the water line on the Y axis. Compare the top most point of the colliders bounding box to this field. Something like this.

    Code (CSharp):
    1. if(objectCollider.bounds.max.y > waterObjectReference.waterLineCurrentGlobalPos)
    2. {
    3.      // The object is floating or is above the water line
    4. }
    5. else
    6. {
    7.      // The object is completely submerged in the water
    8. }
    9.  
     
  45. Zyblade

    Zyblade

    Joined:
    Jul 1, 2014
    Posts:
    141
    Yes, that'd be great. So there's no advantage to split the z-segments yet. At least I coudln't see it. I already looked through the code and everything, so I know how it's working. But it might easier for you implementing that feature since it's your asset. Looking forward to this feature ;) Searched really long for a proper 2.5D water as yours.
     
  46. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    The Z Segments field is part of an experimental feature that I did not add in the last update. Now that I think about it, I should have just removed it so it does not confuse someone.

    The idea of implementing the 2.5D water came to me after playing Rayman Legends and The Cave, although I have to do a little more work till I get their quality.
     
    Last edited: Nov 27, 2015
  47. trueicecold

    trueicecold

    Joined:
    Aug 26, 2014
    Posts:
    5
    Thanks Nircom, it worked perfectly after tweaking it a bit :)
     
    Nicrom likes this.
  48. immeasurability

    immeasurability

    Joined:
    Apr 22, 2014
    Posts:
    125
    ok, now i have a one moment!
    if i have small collider 1x0.2f units? and wont they to swim, not go down, need set mass of small 0.1f

    how i can change parameter of water for collider 1x0.2f on mass 20 dont go down?
     
  49. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Your question is a little bit confusing. I can assume that English is not your native language.

    You can't have 2 objects of the same size, but different masses swim at the surface of the water. The one with bigger mass will go down depending on how big the mass difference between this two objects is. The Physics Based Buoyancy uses real life physics. So the behaviour of the objects in the water is close to behaviour of real life objects.

    Is the object with the big mass the player or just and object you want to float in the water?
     
    Last edited: Dec 17, 2015
  50. immeasurability

    immeasurability

    Joined:
    Apr 22, 2014
    Posts:
    125
    yes, sorry for my english

    i want collider 1x0.2f units and mass 20 dont go down, he need to swim