Update mesh for waves (solved)

I am trying to make a nice ocean for a little project yet I cannot for the life of me figure out how to update the mesh. I have tried some suggestions on other threads but nothing worked so I figured I would ask directly. The script is in C# and goes like so.


     using UnityEngine;
     using System.Collections;
     public class Wavegen : MonoBehaviour
     {
         float scale = 1f;
         float speed = 1.0f;
         float noiseStrength = 1f;
         float noiseWalk = 1f;
     
         private Vector3[] baseHeight;
      
         void Update () {
         Mesh mesh = GetComponent<MeshFilter>().mesh;
         MeshCollider collider = GetComponent<MeshCollider>();
         if (baseHeight == null)
             baseHeight = mesh.vertices;
   
         Vector3[] vertices = new Vector3[baseHeight.Length];
         for (int i=0;i<vertices.Length;i++)
         {
             Vector3 vertex = baseHeight*;*
 <em>vertex.y += Mathf.Sin(Time.time * speed+ baseHeight<em>.x + baseHeight<em>.y + baseHeight_.z) * scale;_</em></em></em>
 <em><em><em><em>vertex.y += Mathf.PerlinNoise(baseHeight<em>.x + noiseWalk, baseHeight_.y + Mathf.Sin(Time.time * 0.1f)    ) * noiseStrength;_</em></em></em></em></em>
 <em><em><em><em><em>_vertices *= vertex;*_</em></em></em></em></em>
 <em><em><em><em><em>_*}*_</em></em></em></em></em>
 <em><em><em><em><em>_*mesh.vertices = vertices;*_</em></em></em></em></em>
 <em><em><em><em><em>_*mesh.RecalculateNormals();		*_</em></em></em></em></em>
 <em><em><em><em><em>_*collider.sharedMesh = null;*_</em></em></em></em></em>
 <em><em><em><em><em>_*collider.sharedMesh = mesh;*_</em></em></em></em></em>
 <em><em><em><em><em>_*}*_</em></em></em></em></em>
 <em><em><em><em><em>_*}*_</em></em></em></em></em>
<em><em><em><em><em>_*```*_</em></em></em></em></em>
<em><em><em><em><em>_*Is there a way to add the mesh to this and also do I have to delete the mesh that appears when you create the object? (PS sorry bout the formatting errors I don't know what is making it do that) Edit: updated the script with a few lines but they seem to do nothing.*_</em></em></em></em></em>

For me your script works without problems. I created a Plane object throught GameObject/Create Other/Plane, attached your script to that object and pressed Play. I can see the wave motion.

Edit: if you want not just a visual change, but also change in the collider, you need to add those lines to the end of your Update method.

MeshCollider collider = GetComponent<MeshCollider>();
// this =null is necessary, because it forces collision mesh to be recalculated,
// if you don't do thing then Unity thinks that it's the same mesh and doesn't recalculate it
collider.sharedMesh = null;
collider.sharedMesh = mesh;

Note that you need to attach Rigidbody component to other objects if you want them to be affected by physics and change in this collider.

Note that updating Mesh data in runtime is considered a slow operation. Updating collider in runtime is very slow. It might be ok for PC if your mesh is not too complex.

First, if you have a non-flat plane mesh, you need to find the surface vertices, like this:

List<Vector3> waveVertices = new List<Vector3>();
     for(int i = 0; i < GetComponent<MeshFilter>().sharedMesh.vertices.Length - 1; i++) {
          Vector3 vertex = GetComponent<MeshFilter>().sharedMesh.vertices*;*
  • Vector3 nextVertex = GetComponent().sharedMesh.vertices[i + 1];*
  • if(vertex.y > nextVertex.y) {*
  •     waveVertices.Add(vertex);*
    
  • }*
    }
    Then, you basically just take the vertex postions and move them upwards or downwards, and assign them back to the mesh’s vertices array. Add some fancy Math.PI or whatever computing for bell-shaped wave motions if you want, as you did in your example.

float min = 0f;
float max = 1f;
float waveSpeed = 5f;
int waveDir = 0;

void Update() {
if(waveVertices.Count > 0) {

Mesh mesh = GetComponent().mesh;
Vector3[] vertices = mesh.vertices;

lvl = vertices[waveVertices[0]].y;

if(waveDir == 1 && vertices[waveVertices[0]].y >= max) {
waveDir = 0;
}
if(waveDir == 0 && vertices[waveVertices[0]].y <= min) {
waveDir = 1;
}

foreach(int i in waveVertices) {
if(waveDir == 0) {
vertices -= Vector3.up * Time.deltaTime * waveSpeed;
* }*
* else {*
vertices += Vector3.up * Time.deltaTime * waveSpeed;
* }*
}
mesh.vertices = vertices;
mesh.RecalculateBounds();
* }*
}