Boat Attack使用了Universal RP的许多新图形功能,可以用于探索 Universal RP 的使用方式和技巧。
您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

135 行
4.2 KiB

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Profiling;
namespace BoatTutorial
{
public class BoatPhysics : MonoBehaviour
{
public Mesh boatHull;
//Script that's doing everything needed with the boat mesh, such as finding out which part is above the water
private ModifyBoatMesh modifyBoatMesh;
//Mesh for debugging
private Mesh underWaterMesh;
//The boats rigidbody
private Rigidbody boatRB;
//The density of the water the boat is traveling in
private float rhoWater = 1000f;
public Vector3 centerOfMass;
public float multiplier = 1f;
public bool debugMesh = false;
void Start()
{
//Get the boat's rigidbody
boatRB = gameObject.GetComponent<Rigidbody>();
boatRB.centerOfMass = centerOfMass;
//Init the script that will modify the boat mesh
modifyBoatMesh = new ModifyBoatMesh(gameObject, boatHull);
//Meshes that are below and above the water
Mesh mesh = new Mesh();
mesh.vertices = boatHull.vertices;
mesh.normals = boatHull.normals;
mesh.triangles = boatHull.triangles;
underWaterMesh = mesh;
}
void FixedUpdate()
{
Profiler.BeginSample("AddUnderwaterForces");
//boatRB.drag = 0.25f;
//Add forces to the part of the boat that's below the water
if (modifyBoatMesh.underWaterTriangleData.Count > 0)
{
AddUnderWaterForces();
}
Profiler.EndSample();
}
void Update()
{
Profiler.BeginSample("GenerateUnderwaterMesh");
//Generate the under water mesh
modifyBoatMesh.GenerateUnderwaterMesh();
Profiler.EndSample();
//Display the under water mesh
if(debugMesh)
modifyBoatMesh.DisplayMesh(underWaterMesh, "UnderWater Mesh", modifyBoatMesh.underWaterTriangleData);
}
//Add all forces that act on the squares below the water
void AddUnderWaterForces()
{
//Get all triangles
List<TriangleData> underWaterTriangleData = modifyBoatMesh.underWaterTriangleData;
for (int i = 0; i < underWaterTriangleData.Count; i++)
{
//This triangle
TriangleData triangleData = underWaterTriangleData[i];
//Calculate the buoyancy force
Vector3 buoyancyForce = BuoyancyForce(rhoWater, triangleData);
//Add the force to the boat
boatRB.AddForceAtPosition(buoyancyForce * multiplier, triangleData.center);
//boatRB.drag += triangleData.area * 0.075f;
//Debug
if(debugMesh)
{
//Normal
Debug.DrawRay(triangleData.center, triangleData.normal, Color.white);
//Buoyancy
Debug.DrawRay(triangleData.center, buoyancyForce.normalized, Color.blue);
}
}
}
//The buoyancy force so the boat can float
private Vector3 BuoyancyForce(float rho, TriangleData triangleData)
{
//Buoyancy is a hydrostatic force - it's there even if the water isn't flowing or if the boat stays still
// F_buoyancy = rho * g * V
// rho - density of the mediaum you are in
// g - gravity
// V - volume of fluid directly above the curved surface
// V = z * S * n
// z - distance to surface
// S - surface area
// n - normal to the surface
Vector3 buoyancyForce = rho * Physics.gravity.y * triangleData.distanceToSurface * triangleData.area * triangleData.normal;
//The vertical component of the hydrostatic forces don't cancel out but the horizontal do
buoyancyForce.x = 0f;
buoyancyForce.z = 0f;
return buoyancyForce;
}
void OnDrawGizmos()
{
if(underWaterMesh && debugMesh)
{
Gizmos.color = Color.red;
Gizmos.DrawMesh(underWaterMesh, transform.position, transform.rotation);
}
Gizmos.color = Color.green;
Gizmos.DrawSphere(transform.TransformPoint(centerOfMass), 0.5f);
}
}
}