void FixedUpdateBuoyancy(ICollProvider collProvider)
        {
            float archimedesForceMagnitude = WATER_DENSITY * Mathf.Abs(Physics.gravity.y);

            for (int i = 0; i < _forcePoints.Length; i++)
            {
                FloaterForcePoints point = _forcePoints[i];
                var transformedPoint     = transform.TransformPoint(point._offsetPosition + new Vector3(0, _centerOfMass.y, 0));

                Vector3 undispPos;
                if (!collProvider.ComputeUndisplacedPosition(ref transformedPoint, _samplingData, out undispPos))
                {
                    // If we couldn't get wave shape, assume flat water at sea level
                    undispPos   = transformedPoint;
                    undispPos.y = OceanRenderer.Instance.SeaLevel;
                }

                Vector3 displaced;
                collProvider.SampleDisplacement(ref undispPos, _samplingData, out displaced);

                var dispPos    = undispPos + displaced;
                var heightDiff = dispPos.y - transformedPoint.y;
                if (heightDiff > 0)
                {
                    RB.AddForceAtPosition(archimedesForceMagnitude * heightDiff * Vector3.up * point._weight * _forceMultiplier / _totalWeight, transformedPoint);
                }
            }
        }
Exemple #2
0
    void FixedUpdateEngine()
    {
        var forcePosition = RB.position;

        var forward = _engineBias;

        //if (_playerControlled) forward += Input.GetAxis("Vertical");
        if (_playerControlled)
        {
            forward += joystick.Vertical;
        }
        RB.AddForceAtPosition(transform.forward * _enginePower * forward, forcePosition, ForceMode.Acceleration);

        var sideways = _turnBias;

        //if (_playerControlled) sideways += (Input.GetKey(KeyCode.A) ? -1f : 0f) + (Input.GetKey(KeyCode.D) ? 1f : 0f);
        //if (_playerControlled) sideways += (Input.GetKey(KeyCode.A) ? -1f : 0f) + (Input.GetKey(KeyCode.D) ? 1f : 0f);
        if (_playerControlled)
        {
            sideways = sideways + joystick.Horizontal;
        }
        var rotVec = transform.up + _turningHeel * transform.forward;

        RB.AddTorque(rotVec * _turnPower * sideways, ForceMode.Acceleration);
    }
Exemple #3
0
    public void FixedUpdate()
    {
        GetInput();
        RB.AddForce(-AirDragCoeff * RB.velocity * RB.velocity.magnitude);          //air drag (quadratic)
        RB.AddForce(-AirDownForceCoeff * RB.velocity.sqrMagnitude * transform.up); //downforce (quadratic)
        RB.AddForceAtPosition(-TireDragCoeff * RB.velocity, transform.position);   //tire drag (Linear)

        SetGearRatio();
        SetRPM();
        ApplySteer();
        ApplyTorque();
        TractionControl();
        SetMileTick();
    }
        void FixedUpdateDrag(ICollProvider collProvider, Vector3 waterSurfaceVel)
        {
            // Apply drag relative to water
            var     pos = RB.position;
            Vector3 undispPos;

            if (!collProvider.ComputeUndisplacedPosition(ref pos, _samplingData, out undispPos))
            {
                // If we couldn't get wave shape, assume flat water at sea level
                undispPos   = pos;
                undispPos.y = OceanRenderer.Instance.SeaLevel;
            }

            var _velocityRelativeToWater = RB.velocity - waterSurfaceVel;

            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);
        }
    public void FixedUpdate()
    {
        if (vehicleController != null)
        {
            SteerInput  = vehicleController.SteerInput;
            AccellInput = vehicleController.AccelInput;
        }

        //air drag (quadratic)
        RB.AddForce(-airDragCoeff * RB.velocity * RB.velocity.magnitude);

        //downforce (quadratic)
        RB.AddForce(-airDownForceCoeff * RB.velocity.sqrMagnitude * transform.up);

        //tire drag (Linear)
        RB.AddForceAtPosition(-tireDragCoeff * RB.velocity, transform.position);

        //calc current gear ratio
        float gearRatio = Mathf.Lerp(gearRatios[Mathf.FloorToInt(CurrentGear) - 1], gearRatios[Mathf.CeilToInt(CurrentGear) - 1], CurrentGear - Mathf.Floor(CurrentGear));

        if (Reverse)
        {
            gearRatio = -1.0f * gearRatios[0];
        }

        //calc engine RPM from wheel rpm
        float wheelsRPM = (axles[1].right.rpm + axles[1].left.rpm) / 2f;

        if (wheelsRPM < 0)
        {
            wheelsRPM = 0;
        }

        // if the engine is on, the fuel injectors are going to be triggered at minRPM
        // to keep the engine running.  If the engine is OFF, then the engine will eventually
        // go all the way down to 0, because there's nothing keeping it spinning.
        var minPossibleRPM = IgnitionStatus == IgnitionStatus.On ? minRPM : 0.0f;

        CurrentRPM = Mathf.Lerp(CurrentRPM, minPossibleRPM + (wheelsRPM * finalDriveRatio * gearRatio), Time.fixedDeltaTime * RPMSmoothness);
        // I don't know why, but logging RPM while engine is off and we're not moving, is showing
        // a constant drift between 0.0185 and 0.0192 or so .. so just clamp it down to 0 at that
        // point.
        if (CurrentRPM < 0.02f)
        {
            CurrentRPM = 0.0f;
        }

        //find out which wheels are on the ground
        foreach (var axle in axles)
        {
            axle.isGroundedLeft  = axle.left.GetGroundHit(out axle.hitLeft);
            axle.isGroundedRight = axle.right.GetGroundHit(out axle.hitRight);
        }

        //convert inputs to torques
        float steer = maxSteeringAngle * SteerInput;

        currentTorque = (float.IsNaN(CurrentRPM / maxRPM)) ? 0.0f : rpmCurve.Evaluate(CurrentRPM / maxRPM) * gearRatio * finalDriveRatio * tractionControlAdjustedMaxTorque;

        foreach (var axle in axles)
        {
            if (axle.steering)
            {
                axle.left.steerAngle  = steer;
                axle.right.steerAngle = steer;
            }
        }

        if (HandBrake)
        {
            //Make the accellInput negative so that brakes are applied in ApplyTorque()
            AccellInput = -1.0f;
        }

        // No autodrive while engine is off.
        if (IgnitionStatus == IgnitionStatus.On)
        {
            AutoSteer();
        }

        ApplyTorque();
        TractionControl();

        //shift if need be. No auto shifting while engine is off.
        if (IgnitionStatus == IgnitionStatus.On)
        {
            AutoGearBox();
        }

        //record current speed in MPH
        CurrentSpeed = RB.velocity.magnitude * 2.23693629f;

        float deltaDistance = wheelsRPM / 60.0f * (axles[1].left.radius * 2.0f * Mathf.PI) * Time.fixedDeltaTime;

        odometer   += deltaDistance;
        mileTicker += deltaDistance;

        if ((mileTicker * 0.00062137f) > 1)
        {
            mileTicker = 0;
            SIM.LogSimulation(SIM.Simulation.MileTick);
        }

        /*
         * // why does this not work :(
         * float currentRPS = currentRPM / 60.0f;
         *
         * float accel = Mathf.Max(0.0f, accellInput);
         * float angularV = currentRPS * Mathf.PI * 2.0f;
         *
         * float power = currentTorque //(rpmCurve.Evaluate(currentRPM / maxRPM) * accel * maxMotorTorque)  //Nm
         * angularV; // Watt
         *
         * float energy = power * Time.fixedDeltaTime  // w/s
         *  / 1000.0f * 3600.0f;                    // kw/h
         *
         * print("p:" + power + " e:" + energy);
         * //approximation function for
         * // https://en.wikipedia.org/wiki/Brake_specific_fuel_consumption#/media/File:Brake_specific_fuel_consumption.svg
         * // range ~ 200-400 g/kWh
         * float bsfc = (206.0f + Mathf.Sqrt(Mathf.Pow(currentRPM - 2200, 2.0f)
         + Mathf.Pow((accel - 0.9f) * 10000.0f, 2.0f)) / 80 + currentRPM / 4500); // g/kWh
         +
         + float gasolineDensity = 1f / .75f;      // cm^3/g
         +
         + float deltaConsumption = bsfc * energy  // g
         * gasolineDensity                   // cm^3
         *  / 1000.0f;                          // l
         */

        // FIXME fix the more correct method above...
        float deltaConsumption = CurrentRPM * 0.00000001f
                                 + currentTorque * 0.000000001f * Mathf.Max(0.0f, AccellInput);

        // if engine is not powered up, or there's zero acceleration, AND we're not idling
        // the engine to keep it on, then the fuel injectors are off, and no fuel is being used
        // idling == non-scientific calculation of "minRPM + 25%".
        if (IgnitionStatus != IgnitionStatus.On || (AccellInput <= 0.0f && CurrentRPM > minRPM + (minRPM * 0.25)))
        {
            deltaConsumption = 0.0f;
        }

        consumptionDistance = deltaConsumption / deltaDistance;       // l/m
        consumptionTime     = deltaConsumption / Time.fixedDeltaTime; // l/s

        fuelLevel -= deltaConsumption;

        float engineWeight     = 200.0f;                    // kg
        float energyDensity    = 34.2f * 1000.0f * 1000.0f; // J/l fuel
        float specificHeatIron = 448.0f;                    // J/kg for 1K temperature increase

        EngineTemperatureK += (deltaConsumption * energyDensity) / (specificHeatIron * engineWeight);

        float coolFactor = 0.00002f; //ambient exchange

        if (EngineTemperatureK > ZERO_K + 90.0f && !CoolingMalfunction)
        {
            coolFactor += 0.00002f + 0.0001f * Mathf.Max(0.0f, CurrentSpeed); // working temperature reached, start cooling
        }
        EngineTemperatureK = Mathf.Lerp(EngineTemperatureK, AmbientTemperatureK, coolFactor);

        //find current road surface type
        WheelHit hit;

        if (axles[0].left.GetGroundHit(out hit))
        {
            traction = hit.forwardSlip; // ground
            var roadObject = hit.collider.transform.parent == null ? hit.collider.transform : hit.collider.transform.parent;
        }
        else
        {
            traction = 0f; // air
        }

        CurrentSpeedMeasured = ((RB.position - lastRBPosition) / Time.fixedDeltaTime).magnitude;
        lastRBPosition       = RB.position;
    }