Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**********************************************************************\
- 1. Create a "Water" layer, and a water plane with collision
- 2. Create your boat prefab
- 2A. Add a rigidbody. Here are my settings:
- mass = 1500
- drag = 1
- angular drag = 0.3
- use gravity = true
- 2B. Add this script. Defaults should work w/rigidbody settings
- 2C. Create 4 contact points, these will contact the water
- plane and apply upward force. Assign them to contactPoints
- array.
- 3. Improve the script
- 3A. Ex: You can make the noise based on a wind direction.
- 3B. Cache things you'll need later, like the rigidbody
- \**********************************************************************/
- using UnityEngine;
- public class ShipController : MonoBehaviour
- {
- public bool isPlayerControlled = true;
- public float forwardForce = 150;
- public float turnForce = 20;
- public Transform[] contactPoints;
- public float contactPointDistance = 2f;
- public float contactFloatForce = 4f;
- public Vector3 centerOfMassOffset = Vector3.zero;
- public float waveNoiseStrength = 0.95f;
- public float waveNoiseFrequency = 0.24f;
- public float waveNoiseScale = 0.24f;
- void Update ()
- {
- if (isPlayerControlled)
- {
- // oh god please do a better job than me, like moving this to FixedUpdate
- if (Input.GetKey(KeyCode.UpArrow))
- {
- Vector3 forwardForce = transform.forward;
- forwardForce.y = 0;
- forwardForce.Normalize();
- GetComponent<Rigidbody>().AddForce(forwardForce * this.forwardForce * Time.deltaTime, ForceMode.Acceleration);
- }
- if (Input.GetKey(KeyCode.LeftArrow))
- {
- GetComponent<Rigidbody>().AddRelativeTorque(new Vector3(0, -turnForce * Time.deltaTime, 0), ForceMode.Acceleration);
- }
- if (Input.GetKey(KeyCode.RightArrow))
- {
- GetComponent<Rigidbody>().AddRelativeTorque(new Vector3(0, turnForce * Time.deltaTime, 0), ForceMode.Acceleration);
- }
- }
- }
- private void FixedUpdate()
- {
- GetComponent<Rigidbody>().centerOfMass = centerOfMassOffset;
- for (int i = 0; i < contactPoints.Length; i++)
- {
- ApplyForceToContactPoint(contactPoints[i].position, contactFloatForce, contactPointDistance);
- }
- }
- void ApplyForceToContactPoint(Vector3 point, float forceScale, float distance)
- {
- RaycastHit hit;
- Vector3 force = Vector3.zero;
- if (point.y <= 0)
- {
- force = Vector3.up * forceScale;
- }
- else if (Physics.Raycast(new Ray(point, Vector3.up * -distance), out hit, distance, 1 << LayerMask.NameToLayer("Water")))
- {
- force = Vector3.up * (1f - (hit.distance / distance)) * forceScale;
- }
- float perlinOffsetX = Time.fixedTime * waveNoiseFrequency;
- Vector3 noiseForce = Vector3.up * Mathf.PerlinNoise((point.x * waveNoiseScale) + perlinOffsetX, (point.z * waveNoiseScale) + perlinOffsetX) * waveNoiseStrength;
- force += noiseForce;
- Debug.DrawLine(point, point + force, Color.yellow);
- Debug.DrawLine(point, point + noiseForce, Color.red);
- GetComponent<Rigidbody>().AddForceAtPosition(force, point, ForceMode.Acceleration);
- }
- private void OnDrawGizmos()
- {
- if (contactPoints != null)
- {
- for (int i = 0; i < contactPoints.Length; i++)
- {
- Gizmos.color = Color.white;
- Gizmos.DrawWireSphere(contactPoints[i].position, 0.2f);
- Gizmos.color = Color.blue;
- Gizmos.DrawLine(contactPoints[i].position, contactPoints[i].position - Vector3.up * contactPointDistance);
- }
- }
- Gizmos.DrawWireSphere(transform.position + centerOfMassOffset, 0.5f);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement