Hi,
I’ve been struggling with this game mechanic for 7 hours for 3 freaking DAYS, i wanna d*!*e
anyways I have a first-person shooter game and the player later will be on the wheelchair, I’m planning to make the wheelchair Gameplay similar to the “Wolfenstein 2: The New Colossus” when the player plays on the wheelchair, so I went ahead and added the wheelchair movement and made the camera controls.
Then I wanted to add a general game mechanic which is when the player want to move side ways they’ll press A/D and the wheelchair should strafe that way but to make it realistic I wanted to make the chair rotate that way before strafing, so the chair should rotate -90 and 90 degrees before moving, everything cool until now, but I don’t want that limit to be constant, but rather relative to the camera rotation, in other words if the camera have rotated 93 degrees the limits will be 3 to 183. sounds easy huh? NO it’s not… no matter what I do it never works, I milked ChatGPT to the last drop and I didn’t achieve anything. the problem is mostly because of the Quaternion and the weird rotation of the Camera and it’s difference from the wheelchair rotation.
Please Help me with this and it would be much appreciated if you tried it before sending a simple solution and calling me an idiot, here’s my code and I highlighted with comments the section that needs attention.
ow and first one who manages to solve my puzzle, I’ll put there name in my upcoming game credits
private PlayerInput playerinput;
private PlayerInput.BasicActions input;
private Rigidbody rb;
public Transform wheelchair;
public Transform orientation;
public Transform bigWheelR;
public Transform bigWheelL;
public Transform viewStart;
public Transform viewEnd;
public FirstPersonCam fps;
public Transform Cam;
//public float pushRate;
//private float pushTimer;
public float speed;
public float rotationSpeed;
public float rotationSmoothness;
private float decelerationForce;
public float decayRate = 0.05f; // Decay for deceleration
private float yRotation;
private float currentForce;
private bool braking;
public bool canMove = true;
private int steeringDirMultiplier = 1;
public bool isMoving;
[SerializeField] private bool isSteering;
private float lastDir;
private float lastRot;
private readonly float wheelRadius = 0.47f;
private void Awake()
{
playerinput = InputManager.playerinput;
input = playerinput.Basic;
rb = GetComponent<Rigidbody>();
}
private void FixedUpdate()
{
// Apply rotation for wheels
float rot = ((rb.velocity.magnitude * Time.fixedDeltaTime) / wheelRadius) * Mathf.Rad2Deg * lastDir;
bigWheelR.Rotate(rot, 0, 0);
bigWheelL.Rotate(rot, 0, 0);
if (!isMoving && isSteering)
{
float circularRot = ((rotationSpeed * Time.fixedDeltaTime) / wheelRadius) * Mathf.Rad2Deg * lastRot * 0.5f;
bigWheelR.Rotate(circularRot, 0, 0);
bigWheelL.Rotate(-circularRot, 0, 0);
}
if (braking) return;
// Move player
if (!canMove) return;
//here's the function VVVVVVVVVVVVVVVVVVVVVVVVVVVV
Vector2 moveDir = input.Move.ReadValue<Vector2>().normalized;
float X = moveDir.x * rotationSpeed * Time.deltaTime;
float CamYRot = Cam.eulerAngles.y;
float minRot = Mathf.Min(0, CamYRot - 100);
float maxRot = Mathf.Max(0, CamYRot + 100);
if(wheelchair.eulerAngles.y >= minRot && wheelchair.eulerAngles.y <= maxRot)
yRotation += X * steeringDirMultiplier;
//else if (wheelchair.eulerAngles.y < minRot)
//{
// yRotation = minRot;
//}
//else if (wheelchair.eulerAngles.y > maxRot)
//{
// yRotation = maxRot;
//}
wheelchair.localRotation = Quaternion.Lerp(wheelchair.localRotation, Quaternion.Euler(0, wheelchair.localRotation.y + yRotation, 0), rotationSmoothness);
Debug.Log($"minRot:{minRot}, maxRot:{maxRot}, chairRot:{wheelchair.eulerAngles.y}, yrot:{yRotation}");
//Ends here.XXXXXXXXXXXXXXXXXXX
currentForce = speed * -moveDir.y;
if (moveDir.y == 0 && rb.velocity.magnitude != 0) // Input is released => Apply deceleration
{
//pushTimer = 0f;
if (decelerationForce == 0)
{
decelerationForce = rb.velocity.magnitude * speed * lastDir;
}
decelerationForce *= Mathf.Pow(1f - decayRate, Time.fixedDeltaTime); // Apply exponential decay
rb.AddForce(decelerationForce * orientation.forward, ForceMode.Force);
}
else decelerationForce = 0;
// Check current stats
if (moveDir.y < 0)
steeringDirMultiplier = -1;
else
steeringDirMultiplier = 1;
if (moveDir.x != 0)
{
isSteering = true;
lastRot = moveDir.x;
}
else isSteering = false;
if (moveDir.y != 0)
{
isMoving = true;
lastDir = -moveDir.y;
}
else
isMoving = false;
//if(moveDir.y != 0)
//{
// // Add Push to the camera periodically for wheelchair effect
// print(pushTimer);
// pushTimer += Time.fixedDeltaTime;
// if (pushTimer >= pushRate)
// {
// fps.LeanForward();
// pushTimer = 0f;
// }
//}
rb.AddForce(10f * currentForce * orientation.forward, ForceMode.Force);
}
private void Brakes(bool activate)
{
braking = activate;
decelerationForce = 0;
}
private void OnEnable()
{
input.Brake.started += _ => Brakes(true);
input.Brake.canceled += _ => Brakes(false);
}
private void OnDisable()
{
input.Brake.started -= _ => Brakes(true);
input.Brake.canceled -= _ => Brakes(false);
}