BoatPhysics not working

Hi, I currently am having an issue with a tutorial posted on Make a realistic boat in Unity with C# - Add waves and an endless ocean | Habrador with the endless ocean part. When I left the three scripts from the tutorial fully unedited, unity would freeze forcing me to quit and relaunch. But now I have fixed that error, and incountered a new one that is (“IndexOutOfRangeException: Array index is out of range.
WaterSquare.GenerateMesh () (at Assets/Scripts/WaterSquare.cs:130)
WaterSquare…ctor (UnityEngine.GameObject waterSquareObj, Single no, Single spacing) (at Assets/Scripts/WaterSquare.cs:56)
EndlessWaterSquare.AddWaterPlane (Single xCoord, Single zCoord, Single yPos, Single squareWidth, Single spacing) (at Assets/Scripts/EndlessWaterSquare.cs:211)
EndlessWaterSquare.CreateEndlessSea () (at Assets/Scripts/EndlessWaterSquare.cs:171)
EndlessWaterSquare.Start () (at Assets/Scripts/EndlessWaterSquare.cs:36)”)

Here are my slightly edited Scripts:
WaterSquare.cs
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

//Generates a plane with a specific resolution and transforms the plane to make waves
public class WaterSquare
{
    public Transform squareTransform;
    
    //Add the wave mesh to the MeshFilter
	public MeshFilter terrainMeshFilter;

	//The total size in m
	private float size = 5;
	//Resolution = Width of one square
	public float spacing = 3;
	//The total number of vertices we need to generate based on size and spacing
	private int width = 18;

    //For the thread to update the water
    //The local center position of this square to fake transformpoint in a thread
    public Vector3 centerPos;
    //The latest vertices that belong to this square
    public Vector3[] vertices;

    public WaterSquare(GameObject waterSquareObj, float no, float spacing)
    {
        this.squareTransform = waterSquareObj.transform;

        size = 5;
        this.spacing = spacing;

        this.terrainMeshFilter = squareTransform.GetComponent<MeshFilter>();


        //Calculate the data we need to generate the water mesh   
        width = (int)(size / spacing);
        //Because each square is 2 vertices, so we need one more
        width += 1;

        //Center the sea
        float offset = -((width - 1) * spacing) / 2;

        Vector3 newPos = new Vector3(offset, squareTransform.position.y, offset);

        squareTransform.position += newPos;

        //Save the center position of the square
        this.centerPos = waterSquareObj.transform.localPosition;


        //Generate the sea
        //To calculate the time it took to generate the terrain
        float startTime = System.Environment.TickCount;

        GenerateMesh();
        
        //Calculate the time it took to generate the terrain in seconds
        float timeToGenerateSea = (System.Environment.TickCount - startTime) / 1000f;

        Debug.Log("Sea was generated in " + timeToGenerateSea.ToString() + " seconds");


        //Save the vertices so we can update them in a thread
        this.vertices = terrainMeshFilter.mesh.vertices;
    }

    //If we are updating the square from outside of a thread 
	public void MoveSea(Vector3 oceanPos, float timeSinceStart)
    {
        Vector3[] vertices = terrainMeshFilter.mesh.vertices;

        for (int i = 0; i < vertices.Length; i++)
        {
			Vector3 vertex = vertices*;*

//From local to global
//Vector3 vertexGlobal = squareTransform.TransformPoint(vertex);

Vector3 vertexGlobal = vertex + centerPos + oceanPos;

//Unnecessary because no rotation nor scale
//Vector3 vertexGlobalTest2 = squareTransform.rotation * Vector3.Scale(vertex, squareTransform.localScale) + squareTransform.position;

//Debug
if (i == 0)
{
//Debug.Log(vertexGlobal + " " + vertexGlobalTest);
}

//Get the water height at this coordinate
vertex.y = WaterController.current.GetWaveYPos(vertexGlobal, timeSinceStart);

//From global to local - not needed if we use the saved local x,z position
//vertices = transform.InverseTransformPoint(vertex);

//Don’t need to go from global to local because the y pos is always at 0
vertices = vertex;
}

* terrainMeshFilter.mesh.vertices = vertices;*

terrainMeshFilter.mesh.RecalculateNormals();
* }*

//Generate the water mesh
public void GenerateMesh()
{
//Vertices
List<Vector3[]> verts = new List<Vector3[]>();
* //Triangles*
* List tris = new List();*
* //Texturing*
* //List uvs = new List();*

* for (int z = 0; z < 18; z++)*
{

* verts.Add(new Vector3[z]);*

* for (int x = 0; x < 1; x++)*
{
* Vector3 current_point = new Vector3();*

* //Get the corrdinates of the vertice*
current_point.x = x * spacing;
current_point.z = z * spacing;
* current_point.y = squareTransform.position.y;*

* verts[z] = current_point;*

* //uvs.Add(new Vector2(x,z));*

* //Don’t generate a triangle the first coordinate on each row*
* //Because that’s just one point*
* if (x <= 0 || z <= 0)*
{
* continue;*
* }*

* //Each square consists of 2 triangles*

* //The triangle south-west of the vertice*
_ tris.Add(x + z * width);
tris.Add(x + (z-1) * width);
tris.Add((x-1) + (z-1) * width);_

* //The triangle west-south of the vertice*
_ tris.Add(x + z * width);
tris.Add((x-1) + (z-1) * width);
tris.Add((x-1) + z * width);
* }
}*_

* //Unfold the 2d array of verticies into a 1d array.*
Vector3 unfolded_verts = new Vector3[width * width];

int i = 0;
* foreach (Vector3[] v in verts)*
{
* //Copies all the elements of the current 1D-array to the specified 1D-array*
v.CopyTo(unfolded_verts, i * width);

i++;
* }*

* //Generate the mesh object*
* Mesh newMesh = new Mesh();*
newMesh.vertices = unfolded_verts;
//newMesh.uv = uvs.ToArray();
newMesh.triangles = tris.ToArray();

//Ensure the bounding volume is correct
newMesh.RecalculateBounds();
//Update the normals to reflect the change
newMesh.RecalculateNormals();

* //Add the generated mesh to this GameObject*
* terrainMeshFilter.mesh.Clear();*
* terrainMeshFilter.mesh = newMesh;*
* terrainMeshFilter.mesh.name = “Water Mesh”;*

Debug.Log(terrainMeshFilter.mesh.vertices.Length);
* }*

}
EndlessWaterSquare.cs using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
//Creates an endless water system with squares
public class EndlessWaterSquare : MonoBehaviour
{
//The object the water will follow
public GameObject boatObj;
* //One water square*
public GameObject waterSqrObj;
//Water square data
private float squareWidth = 3f;
private float innerSquareResolution =9f;
private float outerSquareResolution = 2f;
//The list with all water mesh squares == the entire ocean we can see
List waterSquares = new List();
//Stuff needed for the thread
//The timer that keeps track of seconds since start to update the water because we cant use Time.time in a thread
float secondsSinceStart;
//The position of the boat
Vector3 boatPos;
//The position of the ocean has to be updated in the thread because it follows the boat
//Is not the same as pos of boat because it moves with the same resolution as the smallest water square resolution
Vector3 oceanPos;
//Has the thread finished updating the water so we can add the stuff from the thread to the main thread
bool hasThreadUpdatedWater;
void Start()
* {*
//Create the sea
CreateEndlessSea();
//Init the time
secondsSinceStart = Time.time;
//Update the water in the thread
ThreadPool.QueueUserWorkItem(new WaitCallback(UpdateWaterWithThreadPooling));
//Start the coroutine
StartCoroutine(UpdateWater());
}
void Update()
{
//UpdateWaterNoThread();
//Update these as often as possible because we don’t know when the thread will run because of pooling
//and we always need the latest version
//Update the time since start to get correct wave height which depends on time since start
secondsSinceStart = Time.time;
//Update the position of the boat to see if we should move the water
boatPos = boatObj.transform.position;
}
//Update the water with no thread to compare
void UpdateWaterNoThread()
{
//Update the position of the boat
boatPos = boatObj.transform.position;
//Move the water to the boat
MoveWaterToBoat();
//Add the new position of the ocean to this transform
transform.position = oceanPos;
//Update the vertices
for (int i = 0; i < 5; i++)
{
waterSquares*.MoveSea(oceanPos, Time.time);*
}
}

//The loop that gives the updated vertices from the thread to the meshes
//which we can’t do in its own thread
* IEnumerator UpdateWater()*
* {*
while (true)
{
//Has the thread finished updating the water?
if (hasThreadUpdatedWater)
{
//Move the water to the boat
transform.position = oceanPos;
//Add the updated vertices to the water meshes
for (int i = 0; i < 5; i++)
{
waterSquares_.terrainMeshFilter.mesh.vertices = waterSquares*.vertices;_
_waterSquares.terrainMeshFilter.mesh.RecalculateNormals();
}
//Stop looping until we have updated the water in the thread*

hasThreadUpdatedWater = false;
//Update the water in the thread
ThreadPool.QueueUserWorkItem(new WaitCallback(UpdateWaterWithThreadPooling));
}
//Don’t need to update the water every frame
yield return new WaitForSeconds(Time.deltaTime * 3f);
}
}
//The thread that updates the water vertices
void UpdateWaterWithThreadPooling(object state)
{
//Move the water to the boat
MoveWaterToBoat();
//Loop through all water squares
for (int i = 0; i < 5; i++)
{
//The local center pos of this square
Vector3 centerPos = waterSquares*.centerPos;*
//All the vertices this square consists of
Vector3[] vertices = waterSquares*.vertices;*
//Update the vertices in this square
for (int j = 0; j < 5; j++)
{
//The local position of the vertex
Vector3 vertexPos = vertices[j];
//Can’t use transformpoint in a thread, so to find the global position of the vertex
//we just add the position of the ocean and the square because rotation and scale is always 0 and 1
Vector3 vertexPosGlobal = vertexPos + centerPos + oceanPos;
//Get the water height
vertexPos.y = WaterController.current.GetWaveYPos(vertexPosGlobal, secondsSinceStart);
//Save the new y coordinate, but x and z are still in local position
vertices[j] = vertexPos;
}
}
hasThreadUpdatedWater = true;
Debug.Log(“Thread finished”);
}
//Move the endless water to the boat’s position in steps that’s the same as the water’s resolution
void MoveWaterToBoat()
{
//Round to nearest resolution
float x = innerSquareResolution * (int)Mathf.Round(boatPos.x / innerSquareResolution);
float z = innerSquareResolution * (int)Mathf.Round(boatPos.z / innerSquareResolution);
//Should we move the water?
if (oceanPos.x != x || oceanPos.z != z)
{
Debug.Log(“Moved sea”);
oceanPos = new Vector3(x, oceanPos.y, z);
}
}
//Init the endless sea by creating all squares
void CreateEndlessSea()
{
//The center piece
AddWaterPlane(0f, 0f, 0f, squareWidth, innerSquareResolution);
//The 8 squares around the center square
for (int x = -1; x <= 1; x += 1)
{
for (int z = -1; z <= 1; z += 1)
{
//Ignore the center pos
if (x == 0 && z == 0)
{
continue;
}
//The y-Pos should be lower than the square with high resolution to avoid an ugly seam
float yPos = -0.5f;
AddWaterPlane(x * squareWidth, z * squareWidth, yPos, squareWidth, outerSquareResolution);
}
}
}
//Add one water plane
void AddWaterPlane(float xCoord, float zCoord, float yPos, float squareWidth, float spacing)
{
GameObject waterPlane = Instantiate(waterSqrObj, transform.position, transform.rotation) as GameObject;
waterPlane.SetActive(true);
//Change its position
Vector3 centerPos = transform.position;
centerPos.x += xCoord;
centerPos.y = yPos;
centerPos.z += zCoord;
waterPlane.transform.position = centerPos;
//Parent it
waterPlane.transform.parent = transform;
//Give it moving water properties and set its width and resolution to generate the water mesh
WaterSquare newWaterSquare = new WaterSquare(waterPlane, squareWidth, spacing);
waterSquares.Add(newWaterSquare);
}
}`
The last script was left unedited
Im pretty sure I know the cause to these errors, but cant fix them.
BTW: I’m running an expiremental build on Linux : 5.6.0xb8_

If you need me to specify more information, I would be more than happy to