diff --git a/Assets/Scripts/Behaviours/Ped/States/VehicleSittingState.cs b/Assets/Scripts/Behaviours/Ped/States/VehicleSittingState.cs index 40a69a25..f8fe2ea8 100644 --- a/Assets/Scripts/Behaviours/Ped/States/VehicleSittingState.cs +++ b/Assets/Scripts/Behaviours/Ped/States/VehicleSittingState.cs @@ -146,13 +146,13 @@ namespace SanAndreasUnity.Behaviours.Peds.States m_model.VehicleParentOffset = Vector3.zero; - var driveState = this.CurrentVehicle.Steering > 0 ? AnimIndex.DriveRight : AnimIndex.DriveLeft; + var driveState = this.CurrentVehicle.Input.steering > 0 ? AnimIndex.DriveRight : AnimIndex.DriveLeft; var state = m_model.PlayAnim(AnimGroup.Car, driveState, PlayMode.StopAll); state.speed = 0.0f; state.wrapMode = WrapMode.ClampForever; - state.time = Mathf.Lerp(0.0f, state.length, Mathf.Abs(this.CurrentVehicle.Steering)); + state.time = Mathf.Lerp(0.0f, state.length, Mathf.Abs(this.CurrentVehicle.Input.steering)); } diff --git a/Assets/Scripts/Behaviours/Vehicles/VehicleController.cs b/Assets/Scripts/Behaviours/Vehicles/VehicleController.cs index 97fd7af2..ccd398d0 100644 --- a/Assets/Scripts/Behaviours/Vehicles/VehicleController.cs +++ b/Assets/Scripts/Behaviours/Vehicles/VehicleController.cs @@ -19,7 +19,7 @@ namespace SanAndreasUnity.Behaviours.Vehicles [SyncVar] float m_net_acceleration; [SyncVar] float m_net_steering; - [SyncVar] float m_net_braking; + [SyncVar] bool m_net_isHandBrakeOn; [SyncVar] float m_net_health; @@ -184,9 +184,7 @@ namespace SanAndreasUnity.Behaviours.Vehicles // local ped is occupying driver seat - float oldAcc = m_vehicle.Accelerator; - float oldBrake = m_vehicle.Braking; - float oldSteer = m_vehicle.Steering; + var oldInput = m_vehicle.Input; if (!GameManager.CanPlayerReadInput()) this.ResetInput(); @@ -196,16 +194,14 @@ namespace SanAndreasUnity.Behaviours.Vehicles // why do we send input ? // - so that everyone knows if the gas/brake is pressed, and can simulate wheel effects // - so that server can predict position and velocity of rigid body - PedSync.Local.SendVehicleInput(m_vehicle.Accelerator, m_vehicle.Steering, m_vehicle.Braking); + PedSync.Local.SendVehicleInput(m_vehicle.Input); // TODO: also send velocity of rigid body if (!NetStatus.IsServer && !VehicleManager.Instance.controlInputOnLocalPlayer) { // local player should not control input, so restore old input - m_vehicle.Accelerator = oldAcc; - m_vehicle.Braking = oldBrake; - m_vehicle.Steering = oldSteer; + m_vehicle.Input = oldInput; } } @@ -213,9 +209,11 @@ namespace SanAndreasUnity.Behaviours.Vehicles { if (NetStatus.IsServer) { - m_net_acceleration = m_vehicle.Accelerator; - m_net_steering = m_vehicle.Steering; - m_net_braking = m_vehicle.Braking; + var vehicleInput = m_vehicle.Input; + m_net_acceleration = vehicleInput.accelerator; + m_net_steering = vehicleInput.steering; + m_net_isHandBrakeOn = vehicleInput.isHandBrakeOn; + m_net_health = m_vehicle.Health; // wheels @@ -241,9 +239,12 @@ namespace SanAndreasUnity.Behaviours.Vehicles if (!this.IsControlledByLocalPlayer || (this.IsControlledByLocalPlayer && !VehicleManager.Instance.controlInputOnLocalPlayer)) { - m_vehicle.Accelerator = m_net_acceleration; - m_vehicle.Steering = m_net_steering; - m_vehicle.Braking = m_net_braking; + m_vehicle.Input = new Vehicle.VehicleInput + { + accelerator = m_net_acceleration, + steering = m_net_steering, + isHandBrakeOn = m_net_isHandBrakeOn, + }; } // update wheels @@ -274,28 +275,21 @@ namespace SanAndreasUnity.Behaviours.Vehicles void ResetInput() { - m_vehicle.Accelerator = 0; - m_vehicle.Steering = 0; - m_vehicle.Braking = 0; + var input = m_vehicle.Input; + input.Reset(); + m_vehicle.Input = input; } void ReadInput() { var customInput = CustomInput.Instance; - var accel = customInput.GetAxis("Vertical"); - var brake = customInput.GetButton("Brake") ? 1.0f : 0.0f; - var speed = Vector3.Dot(m_vehicle.Velocity, m_vehicle.transform.forward); + var vehicleInput = new Vehicle.VehicleInput(); + vehicleInput.accelerator = customInput.GetAxis("Vertical"); + vehicleInput.isHandBrakeOn = customInput.GetButton("Brake"); + vehicleInput.steering = customInput.GetAxis("Horizontal"); - if (speed * accel < 0f) - { - brake = Mathf.Max(brake, 0.75f); - accel = 0f; - } - - m_vehicle.Accelerator = accel; - m_vehicle.Steering = customInput.GetAxis("Horizontal"); - m_vehicle.Braking = brake; + m_vehicle.Input = vehicleInput; } public void EnableOrDisableRigidBody() diff --git a/Assets/Scripts/Behaviours/Vehicles/Vehicle_Physics.cs b/Assets/Scripts/Behaviours/Vehicles/Vehicle_Physics.cs index 7f09ef98..5717c5fe 100644 --- a/Assets/Scripts/Behaviours/Vehicles/Vehicle_Physics.cs +++ b/Assets/Scripts/Behaviours/Vehicles/Vehicle_Physics.cs @@ -11,14 +11,40 @@ namespace SanAndreasUnity.Behaviours.Vehicles private Rigidbody _rigidBody; public Rigidbody RigidBody => _rigidBody; - [Range(-1, 1)] - public float Accelerator; + public struct VehicleInput + { + public float accelerator; + public float steering; + public bool isHandBrakeOn; - [Range(-1, 1)] - public float Steering; + public void Reset() + { + this.accelerator = 0f; + this.steering = 0f; + this.isHandBrakeOn = false; + } - [Range(0, 1)] - public float Braking = 1f; + public void Validate() + { + if (float.IsNaN(this.accelerator)) + this.accelerator = 0f; + if (float.IsNaN(this.steering)) + this.steering = 0f; + this.accelerator = Mathf.Clamp(this.accelerator, -1f, 1f); + this.steering = Mathf.Clamp(this.steering, -1f, 1f); + } + } + + private VehicleInput m_input; + public VehicleInput Input + { + get => m_input; + set + { + m_input = value; + m_input.Validate(); + } + } public Vector3 Velocity { get { return _rigidBody != null ? _rigidBody.velocity : Vector3.zero; } } @@ -156,22 +182,38 @@ namespace SanAndreasUnity.Behaviours.Vehicles { var vals = VConsts.Instance; + Vector3 velocity = this.Velocity; + + float movementSign = 1f; + if (velocity == Vector3.zero) + movementSign = 0f; + else if (Vector3.Angle(velocity, this.transform.forward) > 90f) // going in reverse + movementSign = -1f; + + float acc = m_input.accelerator; + float brake = m_input.isHandBrakeOn ? 1f : 0f; + if (acc != 0f && movementSign != 0f && Mathf.Sign(movementSign) != Mathf.Sign(acc)) + { + acc = 0f; + brake = 1f; + } + foreach (var wheel in _wheels) { // apply steering if (ShouldSteer(wheel)) { - wheel.Collider.steerAngle = HandlingData.SteeringLock * Steering; + wheel.Collider.steerAngle = HandlingData.SteeringLock * m_input.steering; } // apply motor torque wheel.Collider.motorTorque = - Accelerator * HandlingData.TransmissionEngineAccel + acc * HandlingData.TransmissionEngineAccel * vals.AccelerationScale * DriveBias(wheel); // apply brake torque wheel.Collider.brakeTorque = - Braking * HandlingData.BrakeDecel + brake * HandlingData.BrakeDecel * vals.BreakingScale * BrakeBias(wheel); // update travel diff --git a/Assets/Scripts/Networking/PedSync.cs b/Assets/Scripts/Networking/PedSync.cs index d2275ff0..aac461ad 100644 --- a/Assets/Scripts/Networking/PedSync.cs +++ b/Assets/Scripts/Networking/PedSync.cs @@ -68,19 +68,24 @@ namespace SanAndreasUnity.Net } - public void SendVehicleInput(float acceleration, float steering, float braking) => - this.CmdSendingVehicleInput(acceleration, steering, braking); + public void SendVehicleInput(Vehicle.VehicleInput vehicleInput) => + this.CmdSendingVehicleInput(vehicleInput.accelerator, vehicleInput.steering, vehicleInput.isHandBrakeOn); [Command] - void CmdSendingVehicleInput(float acceleration, float steering, float braking) + void CmdSendingVehicleInput(float acceleration, float steering, bool isHandBrakeOn) { - if (null == m_ped || null == m_ped.CurrentVehicle) + if (null == m_ped) return; - var v = m_ped.CurrentVehicle; - v.Accelerator = acceleration; - v.Steering = steering; - v.Braking = braking; + var vehicle = m_ped.CurrentVehicle; + if (null == vehicle) + return; + + var input = new Vehicle.VehicleInput(); + input.accelerator = acceleration; + input.steering = steering; + input.isHandBrakeOn = isHandBrakeOn; + vehicle.Input = input; } diff --git a/Assets/Scripts/Stats/MiscStats.cs b/Assets/Scripts/Stats/MiscStats.cs index c17a2f2d..9c4f0bec 100644 --- a/Assets/Scripts/Stats/MiscStats.cs +++ b/Assets/Scripts/Stats/MiscStats.cs @@ -61,16 +61,16 @@ namespace SanAndreasUnity.Stats { List objects = new List(){ vehicle.Velocity, - vehicle.Accelerator, - vehicle.Braking, - vehicle.Steering, + vehicle.Input.accelerator, + vehicle.Input.isHandBrakeOn, + vehicle.Input.steering, vehicle.AverageWheelHeight, vehicle.NetTransform.netId, vehicle.NetTransform.syncInterval, vehicle.NetTransform.ComponentIndex, }; - var texts = new List() {"velocity", "accelerator", "braking", "steering", "average wheel height", + var texts = new List() {"velocity", "accelerator", "is handbrake on", "steering angle", "average wheel height", "net id", "sync interval", "component index"}; @@ -81,8 +81,8 @@ namespace SanAndreasUnity.Stats texts.Add("\t" + w.Alignment); objects.Add( w.Collider != null - ? string.Format("travel {0} rpm {1} radius {2} motor torque {3} mass {4} is grounded {5}", - w.Travel, w.Collider.rpm, w.Collider.radius, w.Collider.motorTorque, w.Collider.mass, w.Collider.isGrounded) + ? string.Format("travel {0} rpm {1} radius {2} motor torque {3} brake torque {4} mass {5} is grounded {6}", + w.Travel, w.Collider.rpm, w.Collider.radius, w.Collider.motorTorque, w.Collider.brakeTorque, w.Collider.mass, w.Collider.isGrounded) : ""); }