Creating Waves on Plane mesh

So in a recent post, we talked about generating a Quad and a Plane, which is an excellent introduction to creating meshes from code! But this time, let’s modify a mesh on a fly, by making water from a Plane with some waves! ?‍♂️

If you read my previous posts, you already know how to generate a quad or a plane from code. We will use the code from my last post to create a plane, so we don’t need to write it again.

But before we can jump into modifying mesh, the first thing that I would do is to add scrolling to water texture. ?‍?

using UnityEngine;

/// <summary>
/// Script that makes waves on a plane mesh.
/// </summary>
public class WavesScript : MonoBehaviour
{
    private MeshRenderer meshRenderer;
    private MeshFilter meshFilter;

    // Waves direction in degrees.
    [SerializeField]
    private float wavesDirection = 0f;

    // Texture scroll speed.
    [SerializeField]
    private float textureScrollSpeed = 0.5f;

    /// <summary>
    /// Unity method called on first frame.
    /// </summary>
    private void Start()
    {
        // Getting references to components.
        meshRenderer = GetComponent<MeshRenderer>();
        meshFilter = GetComponent<MeshFilter>();
    }

    /// <summary>
    /// Unity method called every frame.
    /// </summary>
    private void Update()
    {
        // Scrolling water texture
        float xSpeed = Mathf.Sin(wavesDirection * Mathf.Deg2Rad);
        float zSpeed = Mathf.Cos(wavesDirection * Mathf.Deg2Rad);
        meshRenderer.material.mainTextureOffset += new Vector2(xSpeed, zSpeed) * textureScrollSpeed * Time.deltaTime;
    }
}

It’s looking cool already!

It’s just a texture with scroll but it looks already better than empty plane!

Now let’s add some waviness to it!

using UnityEngine;

/// <summary>
/// Script that makes waves on a plane mesh.
/// </summary>
public class WavesScript : MonoBehaviour
{
    ...

    /// <summary>
    /// Unity method called every frame.
    /// </summary>
    private void Update()
    {
        ...

        // Getting references.
        var mesh = meshFilter.mesh;
        var verts = mesh.vertices;

        // Changing vertice elevation.
        for (int i = 0; i < verts.Length; i++)
        {
            float elevation = Mathf.Sin(verts[i].x + verts[i].z + Time.time);

            verts[i].y = elevation;
        }

        // Applying changes to the mesh.
        mesh.vertices = verts;
    }
}

Let’s see it again!

Its time to get surfing board! ?‍♂️

I think these waves are too big. We need to add some parameters!

using UnityEngine;

/// <summary>
/// Script that makes waves on a plane mesh.
/// </summary>
public class WavesScript : MonoBehaviour
{
    private MeshRenderer meshRenderer;
    private MeshFilter meshFilter;

    // Waves strenght
    [SerializeField]
    private float wavesStrenght = 1;

    // Waves speed.
    [SerializeField]
    private float wavesSpeed = 1f;

    // Waves direction in degrees.
    [SerializeField]
    private float wavesDirection = 0f;

    // Texture scroll speed.
    [SerializeField]
    private float textureScrollSpeed = 0.5f;

    /// <summary>
    /// Unity method called on first frame.
    /// </summary>
    private void Start()
    {
        // Getting references to components.
        meshRenderer = GetComponent<MeshRenderer>();
        meshFilter = GetComponent<MeshFilter>();
    }

    /// <summary>
    /// Unity method called every frame.
    /// </summary>
    private void Update()
    {
        // Scrolling water texture
        float xSpeed = Mathf.Sin(wavesDirection * Mathf.Deg2Rad);
        float zSpeed = Mathf.Cos(wavesDirection * Mathf.Deg2Rad);
        meshRenderer.material.mainTextureOffset += new Vector2(xSpeed, zSpeed) * textureScrollSpeed * Time.deltaTime;

        // Getting references.
        var mesh = meshFilter.mesh;
        var verts = mesh.vertices;

        // Changing vertice elevation.
        for (int i = 0; i < verts.Length; i++)
        {
            float xOffset = verts[i].x * xSpeed;
            float zOffset = verts[i].z * zSpeed;
            float elevation = Mathf.Sin(xOffset + zOffset + Time.time * wavesSpeed) * wavesStrenght;

            verts[i].y = elevation;
        }

        // Applying changes to the mesh.
        mesh.vertices = verts;
    }
}

Now we can dial it to our needs!

Now we can change direction and speed of waves!

How cool is it? ?

Within a few moments, we created a simple script that imitates waves on a mesh! Surfers will be happy. ?

What do you think about it? Have you created other effects on a mesh? Let me know in the comment section below!

If you want to get notified on future content, sign up for the newsletter!

As always, the whole project is available at my public repository. ?

And I hope to see you next time! ?

5 1 vote
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x