Advertisement
Staggart

Stylized Water 2 - Rigidbody-based buoyancy

Dec 29th, 2021
1,382
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.95 KB | None | 0 0
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5.  
  6. namespace StylizedWater2
  7. {
  8.     public class FloatingRigidbody : MonoBehaviour
  9.     {
  10.         public new Rigidbody rigidbody;
  11.  
  12.         [Space]
  13.  
  14.         [Tooltip("This reference is required to grab the wave distance and height values")]
  15.         public WaterObject waterObject;
  16.         [Tooltip("Automatically find the Water Object below of above the Transform's position. This is slower than assigning a specific Water Object directly.")]
  17.         public bool autoFind = true;
  18.        
  19.         public Material waterMaterial;
  20.  
  21.         public enum WaterLevelSource
  22.         {
  23.             FixedValue,
  24.             WaterObject
  25.         }
  26.         [Tooltip("Configure what should be used to set the base water level. Relative wave height is added to this value")]
  27.         public WaterLevelSource waterLevelSource = WaterLevelSource.WaterObject;
  28.         public float waterLevel;
  29.  
  30.         [Space]
  31.        
  32.         [Range(0.01f, 1f)]
  33.         public float buoyancy = 0.5f;
  34.         [Range(0.01f, 0.99f)]
  35.         public float drag = 0.99f;
  36.         [Range(0f, 1f)]
  37.         public float horizontalForce = 0f;
  38.        
  39.         private float m_waterLevel = 0f;
  40.  
  41.         public Mesh buoyancyShape;
  42.         public List<Vector3> samples;
  43.  
  44.         private void Reset()
  45.         {
  46.             rigidbody = this.GetComponent<Rigidbody>();
  47.             waterObject = WaterObject.Find(this.transform.position, true);
  48.  
  49.             if (waterObject)
  50.             {
  51.                 waterMaterial = waterObject.material;
  52.             }
  53.             samples.Add(Vector3.zero);
  54.         }
  55.  
  56.         private void FixedUpdate()
  57.         {
  58.             if(autoFind) waterObject = WaterObject.Find(transform.position, false);
  59.            
  60.             if (waterObject) waterMaterial = waterObject.material;
  61.            
  62.             if (!rigidbody || !waterMaterial) return;
  63.            
  64.             m_waterLevel = waterObject && waterLevelSource == WaterLevelSource.WaterObject? waterObject.transform.position.y : waterLevel;
  65.  
  66.             for (int i = 0; i < samples.Count; i++)
  67.             {
  68.                 Vector3 samplePos = transform.TransformPoint(samples[i]);
  69.                 Vector3 waveNormal = Vector3.zero;
  70.                 float waveHeight = Buoyancy.SampleWaves(samplePos, waterMaterial, m_waterLevel, 1f, false, out waveNormal);
  71.  
  72.                 float depth = waveHeight - samplePos.y;
  73.  
  74.                 if (depth > 0)
  75.                 {
  76.                     samplePos.y = waveHeight;
  77.                     rigidbody.AddForceAtPosition(Vector3.Lerp(Vector3.up, waveNormal, horizontalForce) * ((Mathf.Abs(Physics.gravity.y)) * buoyancy * rigidbody.mass), samplePos, ForceMode.Acceleration);
  78.  
  79.                     rigidbody.AddForce(-rigidbody.velocity * (drag * Time.fixedDeltaTime), ForceMode.VelocityChange);
  80.  
  81.                     rigidbody.AddTorque(-rigidbody.angularVelocity * (0.5f * Time.fixedDeltaTime), ForceMode.Impulse);
  82.                 }
  83.             }
  84.  
  85.         }
  86.  
  87.         [ContextMenu("CreatePointsFromBuoyancyShape")]
  88.         public void CreatePointsFromBuoyancyShape()
  89.         {
  90.             if (!buoyancyShape) return;
  91.  
  92.             Vector3[] vertices = buoyancyShape.vertices;
  93.  
  94.             samples.Clear();
  95.             for (int i = 0; i < vertices.Length; i++)
  96.             {
  97.                 samples.Add(vertices[i]);
  98.             }
  99.         }
  100.  
  101.         private void OnDrawGizmosSelected()
  102.         {
  103.             if (!waterMaterial) return;
  104.  
  105.             for (int i = 0; i < samples.Count; i++)
  106.             {
  107.                 Vector3 samplePos = transform.TransformPoint(samples[i]);
  108.                 float waveHeight = StylizedWater2.Buoyancy.SampleWaves(samplePos, waterMaterial, m_waterLevel, 0f, false, out _);
  109.  
  110.                 Vector3 wavePos = samplePos;
  111.                 wavePos.y = waveHeight;
  112.  
  113.                 Gizmos.DrawLine(samplePos, wavePos);
  114.             }
  115.         }
  116.     }
  117. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement