DynamicDonut

Unity Boat Script by MTIPUL

Jul 29th, 2017
54
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  /**********************************************************************\
  2.     1. Create a "Water" layer, and a water plane with collision
  3.     2. Create your boat prefab
  4.         2A. Add a rigidbody. Here are my settings:
  5.             mass = 1500
  6.             drag = 1
  7.             angular drag = 0.3
  8.             use gravity = true
  9.  
  10.         2B. Add this script. Defaults should work w/rigidbody settings
  11.         2C. Create 4 contact points, these will contact the water
  12.             plane and apply upward force. Assign them to contactPoints
  13.             array.
  14.     3. Improve the script
  15.         3A. Ex: You can make the noise based on a wind direction.
  16.         3B. Cache things you'll need later, like the rigidbody
  17.  \**********************************************************************/
  18. using UnityEngine;
  19.  
  20. public class ShipController : MonoBehaviour
  21. {
  22.     public bool isPlayerControlled = true;
  23.     public float forwardForce = 150;
  24.     public float turnForce = 20;
  25.  
  26.     public Transform[] contactPoints;
  27.     public float contactPointDistance = 2f;
  28.     public float contactFloatForce = 4f;
  29.     public Vector3 centerOfMassOffset = Vector3.zero;
  30.     public float waveNoiseStrength = 0.95f;
  31.     public float waveNoiseFrequency = 0.24f;
  32.     public float waveNoiseScale = 0.24f;
  33.  
  34.     void Update ()
  35.     {
  36.         if (isPlayerControlled)
  37.         {
  38.             // oh god please do a better job than me, like moving this to FixedUpdate
  39.             if (Input.GetKey(KeyCode.UpArrow))
  40.             {
  41.                 Vector3 forwardForce = transform.forward;
  42.                 forwardForce.y = 0;
  43.                 forwardForce.Normalize();
  44.  
  45.                 GetComponent<Rigidbody>().AddForce(forwardForce * this.forwardForce * Time.deltaTime, ForceMode.Acceleration);
  46.             }
  47.             if (Input.GetKey(KeyCode.LeftArrow))
  48.             {
  49.                 GetComponent<Rigidbody>().AddRelativeTorque(new Vector3(0, -turnForce * Time.deltaTime, 0), ForceMode.Acceleration);
  50.             }
  51.             if (Input.GetKey(KeyCode.RightArrow))
  52.             {
  53.                 GetComponent<Rigidbody>().AddRelativeTorque(new Vector3(0, turnForce * Time.deltaTime, 0), ForceMode.Acceleration);
  54.             }
  55.         }
  56.     }
  57.  
  58.     private void FixedUpdate()
  59.     {
  60.         GetComponent<Rigidbody>().centerOfMass = centerOfMassOffset;
  61.  
  62.         for (int i = 0; i < contactPoints.Length; i++)
  63.         {
  64.             ApplyForceToContactPoint(contactPoints[i].position, contactFloatForce, contactPointDistance);
  65.         }
  66.     }
  67.  
  68.     void ApplyForceToContactPoint(Vector3 point, float forceScale, float distance)
  69.     {
  70.         RaycastHit hit;
  71.         Vector3 force = Vector3.zero;
  72.         if (point.y <= 0)
  73.         {
  74.             force = Vector3.up * forceScale;
  75.         }
  76.         else if (Physics.Raycast(new Ray(point, Vector3.up * -distance), out hit, distance, 1 << LayerMask.NameToLayer("Water")))
  77.         {
  78.             force = Vector3.up * (1f - (hit.distance / distance)) * forceScale;
  79.         }
  80.  
  81.         float perlinOffsetX = Time.fixedTime * waveNoiseFrequency;
  82.         Vector3 noiseForce = Vector3.up * Mathf.PerlinNoise((point.x * waveNoiseScale) + perlinOffsetX, (point.z * waveNoiseScale) + perlinOffsetX) * waveNoiseStrength;
  83.         force += noiseForce;
  84.        
  85.         Debug.DrawLine(point, point + force, Color.yellow);
  86.         Debug.DrawLine(point, point + noiseForce, Color.red);
  87.         GetComponent<Rigidbody>().AddForceAtPosition(force, point, ForceMode.Acceleration);
  88.     }
  89.  
  90.     private void OnDrawGizmos()
  91.     {
  92.         if (contactPoints != null)
  93.         {
  94.             for (int i = 0; i < contactPoints.Length; i++)
  95.             {
  96.                 Gizmos.color = Color.white;
  97.                 Gizmos.DrawWireSphere(contactPoints[i].position, 0.2f);
  98.                 Gizmos.color = Color.blue;
  99.                 Gizmos.DrawLine(contactPoints[i].position, contactPoints[i].position - Vector3.up * contactPointDistance);
  100.             }
  101.         }
  102.  
  103.         Gizmos.DrawWireSphere(transform.position + centerOfMassOffset, 0.5f);
  104.     }
  105. }
Add Comment
Please, Sign In to add comment