Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

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. overthere

    overthere

    Joined:
    Jun 28, 2013
    Posts:
    110
    Excellent, I'd happily buy an upgrade / separate asset if you can pull that off!
     
    Nicrom likes this.
  2. petersvp

    petersvp

    Joined:
    Dec 20, 2013
    Posts:
    63
    Hello. I bought your awesome asset, and, of course, fell into the various internal issues with the package. Some of them I can fix myself, Others I will ask you to fix because they are being common.

    First issue. Using your tool with Water4. It really, really looks amazing with Water4 shader from Standard assets, but, your code breaks badly, as well - not every shader have mainTexture!

    Nevermind, here's the diff:

    Code (CSharp):
    1. --- C:/Users/peter/AppData/Local/Temp/Water2D_Tool.cs-rev756.svn001.tmp.cs    пон юли 10 21:23:03 2017
    2. +++ C:/Users/peter/AppData/Local/Temp/Water2D_Tool.cs-rev757.svn001.tmp.cs    пон юли 10 23:15:59 2017
    3. @@ -321,2 +321,7 @@ namespace Water2DTool
    4. -            unitsPerUV.x = GetComponent<Renderer>().sharedMaterial.mainTexture.width / pixelsPerUnit;
    5. -            unitsPerUV.y = GetComponent<Renderer>().sharedMaterial.mainTexture.height / pixelsPerUnit;
    6. +            var mainTex = GetComponent<Renderer>().sharedMaterial.mainTexture;
    7. +            if (mainTex != null)
    8. +            {
    9. +                unitsPerUV.x = mainTex.width / pixelsPerUnit;
    10. +                unitsPerUV.y = mainTex.height / pixelsPerUnit;
    11. +            }
    12. +            else unitsPerUV = new Vector2(32, 32);
    13. @@ -371,2 +376,7 @@ namespace Water2DTool
    14. -            unitsPerUV2.x = mat[1].mainTexture.width / pixelsPerUnit;
    15. -            unitsPerUV2.y = mat[1].mainTexture.height / pixelsPerUnit;
    16. +            var mainTex = mat[1].mainTexture;
    17. +            if (mainTex != null)
    18. +            {
    19. +                unitsPerUV2.x = mainTex.width / pixelsPerUnit;
    20. +                unitsPerUV2.y = mainTex.height / pixelsPerUnit;
    21. +            }
    22. +            else unitsPerUV2 = new Vector2(32, 32);
    23. @@ -373,0 +384 @@ namespace Water2DTool
    24. +
    25.  
    As for second issue, it is CRITICAL for me. You are failing to properly manage your GameObjects in Edit Mode (if you never heard of InstanceID, it's your best two cents to detect Instantiations and duplications)

    Single Ctrl+D breaks and links together two water volumes (their meshes). Even through this bug can help me replicate waves as feature, it's a bug. You also fail to detect being prefab'd. This is extremely serious workflow PITA for a game where I will need A LOT of small water pools and templates thus using prefabs is a must.

    I don't have the time to fix this bug now, but if I fix it, I will provide a diff, but I will give you useful clue:

    Every object has its own InstanceID. When Instantiate() is called, the new object have new autogenerated instance ID. When you hit CTRL+D in editor, you get cloned object with new Instance ID. To detect Clone, you just need to keep track of your old instance id. You add a [SerializeField] int instance_id = 0; In OnEnable() you check this vs GetInstanceId(). If your remembered id is 0, you are fresh new object. You get and save your id immediately. If saved ID and your ID match, then you were just part of a Scene Start / Playmode start / Scene load. If GetInstanceId() returns different thing than your last id and your last is not 0, this is the case when you had just been Instantiated :p Here, just drop your old mesh, and regenerate new one. However, keep in mind: do not DELETE your old mesh, just abandon it - because it's used by the instantiated source. And, if you do proper reinit in OnEnable(), then your water pools will survive assembly reload during Play Mode as well - a phase very useful for bunch of small code fixes during play mode, like, if you implement sometyhing complex and keep play mode running and this thing can serialize itself, OnEnable will be called when assemblies are reloaded, and you can reinit your stuff there.

    Code (CSharp):
    1. [SerializeField] int instanceID = 0;
    2. ...
    3. if (instanceID == 0) // im fresh new, remember my id
    4. {
    5.      instanceID = GetInstanceID();
    6.      return;
    7. }
    8. if (instanceID != GetInstanceID()) // I had been instantiated or cloned.
    9. {
    10.       instanceID = GetInstanceID();
    11.       AbandonMyOldMeshAndMakeNewOne(); //Do whatever you need to set up the duplicate
    12. }
    13.      
    14.  
    Thanks for your excellent asset (well, nothing is excellent but my waters look extremely sexy now with water4 and badly linked together due to being duplicated - editing the yellow water edits the blue water too)

    water4.jpg
     
    Last edited: Jul 12, 2017
  3. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Hi. Sorry for the late reply, different time zone.

    I'll sent to your email 2 scripts that contain the fixes to some of your problems.

    I am aware of the problems with water object duplicates as well as water prefabs. The fix for this problem will be available in the next update. For the moment I added a new button in the water object inspector that will create a new water mesh instance for the duplicate object.

    Thanks for the info about the InstanceID :).
     
    overthere likes this.
  4. petersvp

    petersvp

    Joined:
    Dec 20, 2013
    Posts:
    63
    BTW keep in mind that InstanceID is itself is unstable. It is nonserialized, the only guarantee is that it's unique per object, and it resets after scene load and quit / enter in Play Mode. So in these events your reinit scripts will fire anyways but I find this sort-a benefical while others don't like it... and if you just abandon your mesh - i think, some other issues may arise. Can you send me the code snippet how to rebuild the mesh manually (or just a diff with this new button feature against current version in Assset Store?)
     
  5. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Add this method in the Water2D_Tool script

    Code (CSharp):
    1. public void AddNewWaterMeshInstance()
    2. {
    3.     mesh = null;
    4.     GetComponent<MeshFilter>().sharedMesh = null;
    5.     mesh = GetComponent<MeshFilter>().sharedMesh = GetMesh();
    6.     RecreateWaterMesh();
    7. }
    and in the Water2D_ToolEditor script on line 100, bellow the "Center Position" button add

    Code (CSharp):
    1. if (GUILayout.Button("New Water Mesh"))
    2.     water2D.AddNewWaterMeshInstance();

    As for the errors that are generated when a shader does not have a mainTexture, those can be fixed very easy.

    In the Water2D_Tool script, change the following lines of code:
    In the WaterMesh() method change
    Code (CSharp):
    1. unitsPerUV.x = GetComponent<Renderer>().sharedMaterial.mainTexture.width / pixelsPerUnit;
    2. unitsPerUV.y = GetComponent<Renderer>().sharedMaterial.mainTexture.height / pixelsPerUnit;
    to
    Code (CSharp):
    1. if (GetComponent<Renderer>().sharedMaterial.mainTexture != null)
    2. {
    3.     unitsPerUV.x = GetComponent<Renderer>().sharedMaterial.mainTexture.width / pixelsPerUnit;
    4.     unitsPerUV.y = GetComponent<Renderer>().sharedMaterial.mainTexture.height / pixelsPerUnit;
    5. }
    6. else
    7. {
    8.     unitsPerUV.x = 512;
    9.     unitsPerUV.y = 512;
    10. }

    In the AddHorisontalMesh() method change:
    Code (CSharp):
    1. unitsPerUV2.x = mat[1].mainTexture.width / pixelsPerUnit;
    2. unitsPerUV2.y = mat[1].mainTexture.height / pixelsPerUnit;
    to
    Code (CSharp):
    1. if (GetComponent<Renderer>().sharedMaterial.mainTexture != null)
    2. {
    3.     unitsPerUV2.x = mat[1].mainTexture.width / pixelsPerUnit;
    4.     unitsPerUV2.y = mat[1].mainTexture.height / pixelsPerUnit;
    5. }
    6. else
    7. {
    8.     unitsPerUV2.x = 512;
    9.     unitsPerUV2.y = 512;
    10. }
     
    Last edited: Jul 12, 2017
    overthere likes this.
  6. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    I know about this. This was the main reason why I did not address the problem with prefabs and dublicates so far. The problem that I encountered is that some times a new mesh instance was generated when there was no need for one as a result, in Play Mode, the surface waves generated by objects where not visible
     
  7. petersvp

    petersvp

    Joined:
    Dec 20, 2013
    Posts:
    63
    Stetekeeping during Edit mode correctly is hard as hell, usually introduced by the [mis]design of unity's serializer, but it is possible. I dropped you huge mail about this topic, but if your code can survive assembly reload properly during Play mode, then it will survive almost anything in Edit Mode as well.
     
  8. Lars-Steenhoff

    Lars-Steenhoff

    Joined:
    Aug 7, 2007
    Posts:
    3,521
    I would like to have the water only collide with a collider that has a tag or layer, not with all objects, can you tell me how I can do that?

    Thanks
     
  9. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Hi.

    Open the Water2D_Simulation script and at the bottom of the script, place this line of code at the beginning of the methods OnTriggerEnter2D() and OnTriggerEnter().

    Code (CSharp):
    1.  
    2. bool skipCollider = true;
    3.  
    4. if (other.tag == "Player")
    5.     skipCollider = false;
    6.  
    7. if (other.tag == "MyTag")
    8.     skipCollider = false;
    9.  
    10. if (skipCollider)
    11.     return;
    12.  
    This will make sure only the objects that have the tag "Player" or "MyTag" can interact with the water.
     
    Last edited: Jul 31, 2017
  10. Lars-Steenhoff

    Lars-Steenhoff

    Joined:
    Aug 7, 2007
    Posts:
    3,521
    Thanks, Actually it may be good if describe what I want to achieve:

    I have a player controller that need to only generate waves on the water on enter collision and on exit collision.
    I don't want to have it affect the rigid body of the player. because I have an other physics simulation for the player.
     
  11. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Is the method I described above, good for your game? If not, I can try to add a drop down menu in the water object inspector, where you could specify which layers should be ignored.
     
  12. petersvp

    petersvp

    Joined:
    Dec 20, 2013
    Posts:
    63
    The code snipped above: both checks are mutually exclusive and the code will always return, no string will pass below the code.

    Code (CSharp):
    1. if (other.tag != "Player")
    2.     return;
    3. if (other.tag != "MyTag")
    4.     return;
    Maybe you've meant == instead of != ?
     
  13. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    :) Sorry about that. It should work now.
    Code (CSharp):
    1. bool skipCollider = true;
    2.  
    3. if (other.tag == "Player")
    4.     skipCollider = false;
    5.  
    6. if (other.tag == "MyTag")
    7.     skipCollider = false;
    8.  
    9. if (skipCollider)
    10.     return;
    Anyway this method is not very efficient. Ill try to add the feature I mentioned above.
     
    Last edited: Jul 31, 2017
  14. Lars-Steenhoff

    Lars-Steenhoff

    Joined:
    Aug 7, 2007
    Posts:
    3,521
    Yes I please if you can add that feature of ignore tags. thanks

    and if you can also add a feature that it only generates waves on contact. and not affect the player, so basically he just ignores the water physics and only created splashes on impact/exit.
     
  15. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Water 2D Tool v1.5 Alpha
    Hi. Water 2D tool hasn't received any new features for some time. The last couple of updates were mainly bug fixes or to ensure compatibility with newer versions of unity. This will change with the next update. Here is a small demo of one of the shaders that will be part of Water 2D Tool v2.0.

     
    Last edited: Oct 26, 2019
  16. evilmaster

    evilmaster

    Joined:
    May 10, 2014
    Posts:
    4
    Looks great! Loving the look of the shaders!
    Did you get any use out of the code I e-mailed you? :)
     
    Nicrom likes this.
  17. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Yes, thanks for sending it to me. I'm going to integrate it in the next update. You saved me a little time :).
     
    evilmaster likes this.
  18. overthere

    overthere

    Joined:
    Jun 28, 2013
    Posts:
    110
    Excellent job! Really looking forward to the update! :)
     
    Nicrom likes this.
  19. hasanrakib

    hasanrakib

    Joined:
    Jan 6, 2016
    Posts:
    4
    when i create a prefab, i get a type mismatch in the 'new water 2d mesh filter' component. i am trying to create a prefab of the water and spawn them while the game is playing. any Ideas ?

    thanks.
     
  20. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Hi. The current of Water 2D Tool doesn't work well with prefabs created from water 2d objects.
    This will be fixed in the next update. Have you tried the temporary fix I wrote about in post 255.?
     
  21. hasanrakib

    hasanrakib

    Joined:
    Jan 6, 2016
    Posts:
    4
    Yes. I tried that. Now if i drag the prefab into the hierarchy, it works but if i instantiate with a script it does not.
     
  22. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Are you calling the method AddNewWaterMeshInstance() after the water object is instantiated?
     
  23. hasanrakib

    hasanrakib

    Joined:
    Jan 6, 2016
    Posts:
    4
    Sorry for replying late and pardon my ignorance but where should i call the AddNewWaterMeshInstance(). I am kind of new at this and still learning.
     
  24. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Don't worry, nobody knows everything from the start. I assume you have a script from which you instantiate new water objects. In that case add the bellow lines to your code.
    Code (CSharp):
    1. // waterObject variable is the new water object that you instantiated at run time.
    2. Water2D_Tool water2D = waterObject.GetComponent<Water2D_Tool>();
    3. water2D.AddNewWaterMeshInstance();
    Also you have to add
    Code (CSharp):
    1. using Water2DTool;
    at the top of the script from which you want to call Water 2D Tool methods. Without it you will get an error.
    if you have more questions you can write directly to my email johnq002@gmail.com
     
  25. hasanrakib

    hasanrakib

    Joined:
    Jan 6, 2016
    Posts:
    4
    Thanks. I will Give it a try and let you know.
     
  26. alinagd

    alinagd

    Joined:
    Jul 8, 2017
    Posts:
    1
    Hi,
    This works well on desktop but in slow motion when playing on tablet or phone. Any way to fix this?
     
  27. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Hi.

    There are a few things you can do to improve the performance on mobile devices: set the buoyancy to linear, reduce the number of triangles the mesh has (by changing the value of the field Segments To Units).
     
    alinagd likes this.
  28. BACALL

    BACALL

    Joined:
    Feb 21, 2017
    Posts:
    87
    I need this in my life!! When is it coming? So excited

    Edit: Is it also going to reflect 2D environments, or create ripples from 2D physics?
     
  29. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Its going a little slower than I anticipated, but I'm working on it. I hope to finish the work on the ripple water in about a week. There are a few more features I need to work on, so I cant say for sure when Water 2D Tool 2.0 will be done.

    By 2D environment you mean sprites, if so than yes. At the moment the ripple shader works only with 3D colliders, but I'll try to and 2D colliders support too.
     
    overthere likes this.
  30. BACALL

    BACALL

    Joined:
    Feb 21, 2017
    Posts:
    87
    Thank you, yes that is what I meant. Looking forward!

    Do you have an estimated release date on 2.0? This or next year?
     
  31. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    I hope to finish 2.0 this year.
     
    overthere likes this.
  32. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Progress Update
    Hi. Initially I had planed by now to finish the work on the new ripple shader , but it didn't quite go as I planed. I had troubles implementing some features. In particular making the shader work with transparent objects took some amount of time. I experimented with sorting layers and render queue of the objects, tried to find to a shader that is similar to the cutout shader, but produces a better result. Nothing came out of it. Searching the internet for similar cases didn't end up helping me too. If you worked with transparent objects before, than you know what a headache they are sometimes.

    So finally made a little progress is solving this problem. Here is the result.

     
    Last edited: Nov 19, 2017
    overthere and Zehru like this.
  33. Almakos

    Almakos

    Joined:
    Dec 13, 2013
    Posts:
    179
    Hey Nicrom,
    this looks awesome.
    May I ask if this new 2.5D feature supports waves?
    As in constant sea-like waves?
    Thank you!
     
  34. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Hi. Currently it doesn't. I created this shader with the idea to simulate calm lake like water with reflection, refraction. I'll add sea like waves to my to do list and see if I can add this feature in the future.
     
  35. jeffweber

    jeffweber

    Joined:
    Dec 17, 2009
    Posts:
    616
    Wow,

    That's looking pretty amazing! Impressed!
     
    Nicrom likes this.
  36. Almakos

    Almakos

    Joined:
    Dec 13, 2013
    Posts:
    179
    Thank you for your quick reply.

    In one of your previous videos I've seen like you are adding continuous fading waves at the left side of screen.
    I just need something like that but don't want waves to fade =)
    I am not looking for realistic waves, just as long as water is not perfectly still.
    Very glad I found your asset will wait for this update to go live though (which might take time with all the asset store review delays).

    Thank you.
     
  37. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Which video are you taking about.?
     
  38. Almakos

    Almakos

    Joined:
    Dec 13, 2013
    Posts:
    179
  39. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    In that one the position of the left most vertex is changed by an animator animation and because the spring simulation is enabled waves are generated. This is not the best solution for generating waves that propagate over a long distance.
    Do you want to achieve something like this when you are talking about sea-like waves.?


     
  40. Almakos

    Almakos

    Joined:
    Dec 13, 2013
    Posts:
    179
    yes, something like that.
    Not too dramatic.
    Before in my game I've been simply moving sprites up and down in a wave-like pattern:

    But now I want to re-make my game as 2.5D
    And want water to be more interesting
     
  41. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Since the game you are working on is for mobile devices, using the new water ripple shader is not the best idea. You could try a more simplified shader like the one in the 2.5D Water demo scene. If you have any more questions you can message me directly on my email address johnq002@gmail.com
     
    Almakos likes this.
  42. overthere

    overthere

    Joined:
    Jun 28, 2013
    Posts:
    110
    Looking great, can't wait for this to come out :)
     
    Nicrom likes this.
  43. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Thnaks :). I am working now on a WebGL demo that showcases some of the features of the ripple shader. When its done I'll post a link here.
     
    overthere likes this.
  44. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Water 2D Tool is on Sale 30% OFF.

    Hi. Water 2D Tool is now part of the Asset Store Mega Sale. You can buy it with a 30% discount.

    WebGL Demo
    PC Demo


    Finally managed to put together a demo build of the new ripple shader. If you go the Water 2D Tool WebGL Demo, you will see a couple of new scenes there. There will be 3 versions of the ripple shader. An unlit as well as a lit version with refraction and realtime reflections. The third is a simplified shader that only suports cubmap reflections and has no distortions. The performance in WebGL at the moment isn't very good so I also made a PC Build which you can download and test. Let me know how is the average FPS on your systems. Also in the WebGL Demo only the unlit shader with refraction and reflection as well as the simplified version are shown. For some reason the lit shader doesn't work in WebGL.

    On another topic. The work on the new ripple shader is taking more time than I expected. As a result I decided that when I finish working on it, I'll publish it to the Asset store as part of Water 2D Tool version 1.5 and not version 2.0 as I initially planed.
     
    Last edited: Dec 30, 2017
  45. sergioem

    sergioem

    Joined:
    Oct 3, 2016
    Posts:
    8
    Just FYI, I don't know what is the problem, but since yesterday I cannot buy your asset. It never loads the price/buy button. See screenshot.

    Note: I tried on two accounts, several browsers and even incognito.
     

    Attached Files:

  46. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    Hi. I'm not sure there is anything I can do. This is most likely related to the Asset store. In my browser the price and the button Add to Chart are showing. You could try to contact the Unity Asset Store team on their email assetstore@unity3d.com or if you want I can do that for you.
     
    sergioschiavo likes this.
  47. sergioschiavo

    sergioschiavo

    Joined:
    Feb 11, 2014
    Posts:
    28
    Thanks. I have used the "old store" and it works there. Not cool Unity! :p

    I am trying to achieve something a bit more organic, with a bit of natural movement and more deformation (under water). Like this


    Is this something that will be possible to do with the new water ripple shader?
     
  48. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    The new ripple shader will allow you to create a water that is very similar to the one found in Ori and the Blind Forest. Have you looked at the WebGL or PC Demo scenes. By deformation you mean the ripples generated by the waterfall?
     
    sergioschiavo likes this.
  49. sergioschiavo

    sergioschiavo

    Joined:
    Feb 11, 2014
    Posts:
    28
    I have seen the PC Demo scenes, and yes it's almost what I need. However if you see in the video, there are some constant natural ripples (not only caused by the waterfall), while in the PC Demo scene the water is completely still if there is nothing moving on it. The idea is to simulate a kind of natural place where there is wind deformation.

     
  50. Nicrom

    Nicrom

    Joined:
    Nov 17, 2013
    Posts:
    421
    I think I understand what you mean. It's not possible in the current version. I'll look into it and see if I can come up with something similar.
     
    Last edited: Dec 1, 2017