SHOW:
|
|
- or go back to the newest paste.
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 | } |