try to fix brakes ; refactor vehicle input

This commit is contained in:
in0finite 2022-05-04 06:18:58 +02:00
parent e988839038
commit 8318a67912
5 changed files with 95 additions and 54 deletions

View file

@ -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));
}

View file

@ -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()

View file

@ -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

View file

@ -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;
}

View file

@ -61,16 +61,16 @@ namespace SanAndreasUnity.Stats
{
List<System.Object> objects = new List<System.Object>(){
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<string>() {"velocity", "accelerator", "braking", "steering", "average wheel height",
var texts = new List<string>() {"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)
: "");
}