I am trying to make a buoyancy script that will interact with waves. I have two scripts: one to change the mesh of a plane and create waves, and the other to deal with the buoyancy. The buoyancy script originally just took the vertices from the mesh, found the closest vertex, and based on the position of the object, calculated the buoyancy. This worked fine. My plan for the future is to add a ship building system using blocks, so now the buoyancy script sits on an empty gameobject and grabs all the colliders from its children. Now, the boat rises when there is no wave and falls when there is a wave. In other words, the timing is inverted, and I don’t know how to fix it.
Here is the wave script:
using UnityEngine;
using System.Collections;
public class PlaneWater : MonoBehaviour
{
public float scale = 0.1f;
public float speed = 1.0f;
public float noiseStrength = 1f;
public float noiseWalk = 1f;
private Vector3[] baseHeight;
public Vector3[] vertices;
void Update () {
Mesh mesh = GetComponent<MeshFilter>().mesh;
if (baseHeight == null)
baseHeight = mesh.vertices;
vertices = new Vector3[baseHeight.Length];
for (int i=0;i<vertices.Length;i++)
{
Vector3 vertex = baseHeight*;*
vertex.y += Mathf.Sin(Time.time * speed+ baseHeight.x + baseHeight.y + baseHeight_.z) * scale;
vertex.y += Mathf.PerlinNoise(baseHeight.x + noiseWalk, baseHeight.y + Mathf.Sin(Time.time * 0.1f) ) * noiseStrength;
vertices = vertex;
}
mesh.vertices = vertices;
mesh.RecalculateNormals();
}
}
And here is the buoyancy script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;_
public class Buoyancy : MonoBehaviour {
* public GameObject currentWaterTile;*
* public Vector3[] vertices;*
* public float buoyancyMultiplier;*
* public List publicCols;*
* public Material woodMat;*
* public Material underwaterMat;*
* private Rigidbody rigidbody;*
* // Use this for initialization*
* void Start () {*
* rigidbody = GetComponent();*
* publicCols = CollectColliders();*
* }*
* // Update is called once per frame*
* void Update () {*
* CalculateBuoyancy();*
* }*
* float FindCurrentVertexY(Vector2 myPos)*
* {*
* //float startTime = Time.time;*
* vertices = new Vector3[currentWaterTile.GetComponent().vertices.Length];*
* vertices = currentWaterTile.GetComponent().vertices;*
* Vector2 closestVertex = Vector2.zero;*
* int closestVertexIndex = 0;*
* for(int i = 0; i < vertices.Length; i++)*
* {*
if(Vector2.Distance(myPos, new Vector2(vertices_.x, vertices*.z)) < Vector2.Distance(myPos, closestVertex))
{
closestVertex = new Vector2(vertices.x, vertices.z);
closestVertexIndex = i;
}
}*_
* return vertices[closestVertexIndex].y;*
* }*
* void CalculateBuoyancy()*
* {*
* int totalUnderwaterParts = 0;*
* foreach(Collider col in publicCols)*
* {*
* float distanceUnderWater = FindCurrentVertexY(new Vector2(col.transform.position.x, col.transform.position.z)) - col.transform.position.y;*
* if(distanceUnderWater > 0)*
* {*
_ Vector3 movementVector = new Vector3(0, 1, 0) - Physics.gravity * buoyancyMultiplier * distanceUnderWater;
* rigidbody.AddForceAtPosition(movementVector, col.transform.position);
col.GetComponent().material = underwaterMat;
totalUnderwaterParts++;
}
else*
* {
col.GetComponent().material = woodMat;
}
}
if((float)totalUnderwaterParts >= (float)publicCols.Count / 3f)
{
ChangeRigidbodyValues(true);
}
else*
* {
ChangeRigidbodyValues(false);
}
}*_
* void ChangeRigidbodyValues(bool underwater)*
* {*
* if(underwater)*
* {*
* rigidbody.angularDrag = 3;*
* rigidbody.drag = 5;*
* }*
* if(!underwater)*
* {*
* rigidbody.angularDrag = 0.05f;*
* rigidbody.drag = 0;*
* }*
* }*
* List CollectColliders()*
* {*
* List cols = new List();*
* for(int i = 0; i < GetComponents().Length; i++)*
* {*
_ cols.Add(GetComponents());
* }
foreach(Transform child in transform)
{
for(int k = 0; k < child.GetComponents().Length; k++)
{
cols.Add(child.GetComponents()[k]);
}
}
return cols;
}
}*_
[Here’s][1] a video of the problem in action.
_*[1]: Wave Test 8/2/17 - YouTube