Reputation: 1
Making a script for camera recoil for an FPS game, got it to work but when I set the recoil values to anything other than 0, Unity freezes and I have to task manager it. Doesn't crash, just freezes. Since my mouse is locked in the Unity wnidow, and pressing esc does nothing, I am practically stuck in a purgatory if I press left click while testing my game. Tried using a public game object and rotating that before, but camera wouldnt rotate at all so I tried localEulerAngles, since I used it earlier in the script.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FirstPersonCamera : MonoBehaviour
{
// Variables
public Transform player;
public float mouseSensitivity = 2f;
float cameraVerticalRotation = 0f;
public float recoilAmount;
public float recoilRecoverySpeed;
float recoverToAngle;
float ammo = 12;
bool lockedCursor = true;
void Start()
{
// Lock and Hide the Cursor
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
}
void Update()
{
// Collect Mouse Input
float inputX = Input.GetAxis("Mouse X")*mouseSensitivity;
float inputY = Input.GetAxis("Mouse Y")*mouseSensitivity;
// Rotate the Camera around its local X axis
cameraVerticalRotation -= inputY;
cameraVerticalRotation = Mathf.Clamp(cameraVerticalRotation, -90f, 90f);
transform.localEulerAngles = Vector3.right * cameraVerticalRotation;
// Rotate the Player Object and the Camera around its Y axis
player.Rotate(Vector3.up * inputX);
//detect shooting
if(Input.GetKeyDown(KeyCode.Mouse0))
{
ammo--;
addRecoil();
}
//detect reload
if(Input.GetKeyDown(KeyCode.R))
{
ammo = 12;
}
}
void addRecoil()
{
//set return angle
recoverToAngle = transform.localEulerAngles.y;
transform.localEulerAngles = new Vector3(0f, recoilAmount, 0f);
//recover from recoil to orig position upon firing
recoilRecover();
}
void recoilRecover()
{
while(transform.localEulerAngles.y > recoverToAngle)
{
transform.localEulerAngles = new Vector3(0f, -recoilRecoverySpeed, 0f);
}
}
}
Couldn't try anything since I couldn't think of any solutions, can't figure out where it went wrong since Unity is unresponsive.
Upvotes: -4
Views: 56
Reputation: 125
In the recoilRecover function, you are setting the angle to the same value everytime rather than reducing it, so you never exit the loop.
Instead, you could do something like:
bool isRecoling = false;
void Update()
{
Vector3 fromAngle = new Vector3(0f, recoilAmount, 0f);
Vector3 toAngle = new Vector3(0f, recoverToAngle, 0f);
if (isRecoiling)
transform.localEulerAngles = Vector3.Lerp(fromAngle, toAngle, Time.deltaTime * recoilRecoverySpeed);
if (transform.localEulerAngles.y <= recoverToAngle + 0.02f) // or any small value to ensure it eventually rounds to the desired value
{
isRecoling = false;
transform.localEulerAngles = toAngle;
}
}
void addRecoil()
{
//the rest of the code
//remove the call to recoilRecover
isRecoling = true;
}
which will lerp the angle from the recoil amount to the original rotation, using the parameter recoilRecoverySpeed
to change the lerp time.
Hope this helps
Upvotes: -2