Exemple #1
0
        /// <summary>
        /// Get the water height at the given world position
        /// </summary>
        /// <param name="worldPos">3D world position</param>
        /// <param name="minWaveLength">Optional: ignore wave lengths below this value; with ships use the ship width for this value</param>
        /// <returns>The height of the ocean at the given world position</returns>
        public static float SampleWaterHeight(Vector3 worldPos, float minWaveLength = 0f)
        {
            float height = 0f;

            SampleHeightHelper sampler = new SampleHeightHelper();

            sampler.Init(worldPos, minWaveLength);
            sampler.Sample(ref height);

            return(height);
        }
Exemple #2
0
    void Update()
    {
        // Assume a primitive like a sphere or box.
        var r = transform.lossyScale.magnitude;

        _sampleHeightHelper.Init(transform.position, 2f * r);

        float height = 0f;

        if (_sampleHeightHelper.Sample(ref height))
        {
            var pos = transform.position;
            pos.y = height;
            transform.position = pos;
        }
    }
Exemple #3
0
    void Update()
    {
        if (OceanRenderer.Instance == null)
        {
            return;
        }

        _sampleHeightHelper.Init(transform.position, 0f);
        float h = 0f;

        _sampleHeightHelper.Sample(ref h);

        var targetPos = _targetPos.position;

        targetPos.y = Mathf.Max(targetPos.y, h + _minHeightAboveWater);

        transform.position = Vector3.Lerp(transform.position, targetPos, _lerpAlpha * OceanRenderer.Instance.DeltaTime * 60f);
        transform.LookAt(_targetLookatPos.position + _lookatOffset * Vector3.up);
    }
Exemple #4
0
    /// <summary>
    /// Align to water normal. One normal by default, but can use a separate normal based on boat length vs width. This gives
    /// varying rotations based on boat dimensions.
    /// </summary>
    void FixedUpdateOrientation(ICollProvider collProvider, Vector3 normalSideways)
    {
        Vector3 normal = normalSideways, normalLongitudinal = Vector3.up;

        if (_useBoatLength)
        {
            _sampleHeightHelperLengthwise.Init(transform.position, _boatLength, true);
            var dummy = 0f;
            if (_sampleHeightHelperLengthwise.Sample(ref dummy, ref normalLongitudinal))
            {
                var F = transform.forward;
                F.y = 0f;
                F.Normalize();
                normal -= Vector3.Dot(F, normal) * F;

                var R = transform.right;
                R.y = 0f;
                R.Normalize();
                normalLongitudinal -= Vector3.Dot(R, normalLongitudinal) * R;
            }
        }

        if (_debugDraw)
        {
            Debug.DrawLine(transform.position, transform.position + 5f * normal, Color.green);
        }
        if (_debugDraw && _useBoatLength)
        {
            Debug.DrawLine(transform.position, transform.position + 5f * normalLongitudinal, Color.yellow);
        }

        var torqueWidth = Vector3.Cross(transform.up, normal);

        _rb.AddTorque(torqueWidth * _boyancyTorque, ForceMode.Acceleration);
        if (_useBoatLength)
        {
            var torqueLength = Vector3.Cross(transform.up, normalLongitudinal);
            _rb.AddTorque(torqueLength * _boyancyTorque, ForceMode.Acceleration);
        }
    }
Exemple #5
0
    void FixedUpdate()
    {
        if (OceanRenderer.Instance == null)
        {
            return;
        }

        UnityEngine.Profiling.Profiler.BeginSample("BoatAlignNormal.FixedUpdate");

        var collProvider = OceanRenderer.Instance.CollisionProvider;
        var position     = transform.position;

        _sampleHeightHelper.Init(transform.position, _boatWidth, true);
        var height          = OceanRenderer.Instance.SeaLevel;
        var disp            = Vector3.zero;
        var normal          = Vector3.up;
        var waterSurfaceVel = Vector3.zero;

        _sampleHeightHelper.Sample(ref disp, ref normal, ref waterSurfaceVel);

        // height = base sea level + surface displacement y
        height += disp.y;

        {
            _sampleFlowHelper.Init(transform.position, _boatWidth);

            Vector2 surfaceFlow = Vector2.zero;
            _sampleFlowHelper.Sample(ref surfaceFlow);
            waterSurfaceVel += new Vector3(surfaceFlow.x, 0, surfaceFlow.y);
        }

        // I could filter the surface vel as the min of the last 2 frames. theres a hard case where a wavelength is turned on/off
        // which generates single frame vel spikes - because the surface legitimately moves very fast.

        if (_debugDraw)
        {
            Debug.DrawLine(transform.position + 5f * Vector3.up, transform.position + 5f * Vector3.up + waterSurfaceVel,
                           new Color(1, 1, 1, 0.6f));
        }

        var velocityRelativeToWater = _rb.velocity - waterSurfaceVel;

        float bottomDepth = height - transform.position.y - _bottomH;

        _inWater = bottomDepth > 0f;
        if (!_inWater)
        {
            UnityEngine.Profiling.Profiler.EndSample();
            return;
        }

        var buoyancy = -Physics.gravity.normalized * _buoyancyCoeff * bottomDepth * bottomDepth * bottomDepth;

        _rb.AddForce(buoyancy, ForceMode.Acceleration);


        // apply drag relative to water
        var forcePosition = _rb.position + _forceHeightOffset * Vector3.up;

        _rb.AddForceAtPosition(Vector3.up * Vector3.Dot(Vector3.up, -velocityRelativeToWater) * _dragInWaterUp, forcePosition, ForceMode.Acceleration);
        _rb.AddForceAtPosition(transform.right * Vector3.Dot(transform.right, -velocityRelativeToWater) * _dragInWaterRight, forcePosition, ForceMode.Acceleration);
        _rb.AddForceAtPosition(transform.forward * Vector3.Dot(transform.forward, -velocityRelativeToWater) * _dragInWaterForward, forcePosition, ForceMode.Acceleration);

        float forward    = _throttleBias;
        float rawForward = Input.GetAxis("Vertical");

        if (_playerControlled)
        {
            forward += rawForward;
        }
        _rb.AddForceAtPosition(transform.forward * _enginePower * forward, forcePosition, ForceMode.Acceleration);

        float reverseMultiplier = (rawForward < 0f ? -1f : 1f);
        float sideways          = _steerBias;

        if (_playerControlled)
        {
            sideways +=
                (Input.GetKey(KeyCode.A) ? reverseMultiplier * -1f : 0f) +
                (Input.GetKey(KeyCode.D) ? reverseMultiplier * 1f : 0f);
        }
        _rb.AddTorque(transform.up * _turnPower * sideways, ForceMode.Acceleration);

        FixedUpdateOrientation(collProvider, normal);

        UnityEngine.Profiling.Profiler.EndSample();
    }