View difference between Paste ID: WaztkL2S and d1UtQmtk
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
}