Created
          December 17, 2023 11:00 
        
      - 
      
 - 
        
Save tvogt/b4456a87c8384cc19a5409cb4b083b44 to your computer and use it in GitHub Desktop.  
    A very simple buoyancy script for Unity and the Poseidon water system - easily adapted to other water systems, all you need is a method to get the water height (including waves) at a world-space position.
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | using System.Collections; | |
| using System.Collections.Generic; | |
| using UnityEngine; | |
| using Pinwheel.Poseidon; | |
| /* | |
| Simple Buoyancy Script for Poseidon water system | |
| to adapt to any other water system, just edit the GetWaterHeight() method to whatever your water system uses to get the wave/water height of a given point | |
| the container should sit at the center of the ship for best effect | |
| */ | |
| [ExecuteInEditMode] | |
| public class AdvancedBuoyController : MonoBehaviour { | |
| private PWater water; | |
| public bool applyRipple; | |
| [SerializeField] float front; | |
| [SerializeField] float back; | |
| [SerializeField] float sides; | |
| [SerializeField] Transform container; | |
| [SerializeField] float heightOffset = 0f; | |
| [SerializeField, Range(0f,20f)] float floatDynamic = 10f; | |
| [SerializeField, Range(0f,20f)] float pitchDynamic = 5f; | |
| [SerializeField, Range(0f,20f)] float rollDynamic = 2.5f; | |
| void Start() { | |
| water = GameObject.FindFirstObjectByType<PWater>(); | |
| } | |
| public void Update() { | |
| if (water == null) return; | |
| float frontHeight = GetWaterHeight(transform.position + transform.forward * front); | |
| float backHeight = GetWaterHeight(transform.position - transform.forward * back); | |
| float rightHeight = GetWaterHeight(transform.position + transform.right * sides); | |
| float leftHeight = GetWaterHeight(transform.position - transform.right * sides); | |
| float pitch = backHeight - frontHeight; | |
| float roll = rightHeight - leftHeight; | |
| float minHeight = Mathf.Min(frontHeight, backHeight, rightHeight, leftHeight); | |
| float lowAvgHeight = (frontHeight + backHeight + rightHeight + leftHeight + minHeight) / 5f; | |
| lowAvgHeight += heightOffset; | |
| container.position = Vector3.Lerp(container.position, new Vector3(container.position.x, lowAvgHeight, container.position.z), floatDynamic * Time.deltaTime); | |
| container.localEulerAngles = new Vector3( | |
| Mathf.LerpAngle(container.localEulerAngles.x, pitch * pitchDynamic, Time.deltaTime), | |
| 0f, | |
| Mathf.LerpAngle(container.localEulerAngles.z, roll * rollDynamic, Time.deltaTime) | |
| ); | |
| } | |
| float GetWaterHeight(Vector3 pos) { | |
| Vector3 myPos = water.transform.InverseTransformPoint(pos); | |
| myPos = water.GetLocalVertexPosition(myPos, applyRipple); | |
| return water.transform.TransformPoint(myPos).y; | |
| } | |
| void OnDrawGizmos() { | |
| Gizmos.color = Color.yellow; | |
| Gizmos.DrawSphere(transform.position + transform.forward * front, 0.5f); | |
| Gizmos.DrawSphere(transform.position - transform.forward * back, 0.5f); | |
| Gizmos.DrawSphere(transform.position + transform.right * sides, 0.5f); | |
| Gizmos.DrawSphere(transform.position - transform.right * sides, 0.5f); | |
| } | |
| } | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment