Ok, lets say I’m using the machinegun script from the FPS tutorial, I want to code recoil - when the user fires the gun gets “pushed” up little bits a a time. I also want to code slight inaccuracy for weapons.
Where would I start?
Ok, lets say I’m using the machinegun script from the FPS tutorial, I want to code recoil - when the user fires the gun gets “pushed” up little bits a a time. I also want to code slight inaccuracy for weapons.
Where would I start?
Start with how much you want the recoil to rotate the gun. From there, use the localEulerAngles variable for its transform and use the time from the recoil. Like this:
var curRecoil : float;
var maxRecoil : float;
var recoilAmount : float;
var startingRotation : float;
var recoveryModifier : float;
var gun : Transform;
function Fire()
{
// Shoot stuff at stuff
if (maxRecoil > curRecoil) {
gun.localEulerAngles.x -= recoilAmount * Time.deltaTime;
curRecoil += recoilAmount * Time.deltaTime;
}
}
function Update()
{
// Other stuff
if (curRecoil > 0) {
curRecoil -= recoveryModifier * recoilAmount * Time.deltaTime;
gun.localEulerAngles.x += recoveryModifier * recoilAmount * Time.deltaTime;
if (curRecoil < 0) {
gun.localEulerAngles.x = startingRotation;
curRecoil = 0;
}
}
}
This is, like most replies on these boards, untested code. Enjoy it at your own risk!
I usually just use a recoil animation, although that doesn’t help too much when you want recoil to change how the bullets fire.
If you want minor inaccuracies, just add to the eulerAngles of the bullets being fired like this:
var bulletVariance : float;
function Shoot()
{
var temp = // Bullet creation stuff
temp.localEulerAngles.x += ((Random.value - .5) * bulletVariance);
temp.localEulerAngles.y += ((Random.value - .5) * bulletVariance);
}
would that work with raycasted bullets?
It should, so long as you create a new rotation using the technique in my code and use that rotation for the raycast.
Edit: Thinking about it, you might as well just use an empty gameObject and rotate it like you would the bullets so you can use the localEulerAngles. Store the starting eulerAngles in the temporary first, of course… You’ll need to set the empty back to its original rotation after every temporary rotation.
I didn’t catch a word of that… lol… it’ll take me a while to decipher but that sounds good.
Recoil and inaccuracy are pretty well built in if you use physics. I have used configurable joints to control the aiming of guns. You can have a simple AddForce call for each shot fired for recoil. You get neat effects like wobbles from running or a delayed reaction to turning quickly. Getting knocked around adds jerks to the gun movement. You get easy, dynamic and smooth effects with very little coding.
The setup is to attach a rigidbody gun to your player with a configurable joint. Set the XY&Z movement to locked and the angular movement to whatever you want the restrictions to be. Then you use a script to translate your mouse input into the target rotation variable of the configurable joint. You’ll need to play with the joint drives to get the right feel, with higher forces making for quicker aiming and less wobbling.
thats really cool, any chance of a unity package?
OK it kinda works but:
any idea on how to fix this?
Have you tried adding the Perlin Noise script on your gun from the wiki? theres a unitypackage there courtesy of Uncle Eric. It adds random movement, with settings in inspector.
AaronC
Sorry Alec, I have been mostly offline lately. I will whip up an example project and post it soon.
Here is that example I promised. Sorry about the delay. It uses the standard built-in FPS controller with a few modifications. There is a kinematic rigidbody with a mouselook script attached as a child of the FPS. The FPS camera has a non-kinematic rigidbody and it attached to the kinematic with a configurable joint. The gun is then simply a child of the camera.
When the player moves/turns/aims, it moves the kinematic rigidbody. The configurable joint then attempts to move the camera/gun to match rotations with the kinematic rigidbody.
Recoil and inaccuracy are then simulated with one simple rigidBody.AddTorque() call. Additionally, things like inertia from turning too quickly are built-in to this system. Jumping/using elevators will cause a similar effect. ie, the gun barrel dipping when the elevator starts moving up.
The recoil can be tailored by simply changing the torque added each shot, or by changing the strength of the joint.
An alternative set-up would be to have the camera be the kinematic rigidbody and the gun be attached by the configurable joint. In my quick experiment, this looked a little too jittery, as the gun can move independently of the camera.
You’ll notice in this package that there are two cameras on the FPS controller. I was experimenting with the depth clearing technique described in the manual chapter on cameras. Hope it doesn’t make it too confusing to see what is going on.
Anyways, I hope that gets you started.
Looking at AAA games they have the mouse aim code recoil. The problem is, in Unity the mouse look code prevents the camera from staying aligned with the gun.
So even though I applied the recoil and recovery code to the camera object, it has mouse look code helping it recover faster, so the gun ends up aiming above the cross hairs. I’m confused.
…Unless I forgot to put the code on the gun camera also!
I’ve been using a recoil system based on your example here. The problem is that it needs to recover, after all we can’t leave the Euler angles jacked up can we? This is annoying, in game you want to aim at soemthing but your gun is moving itself downwards all the time. I’d like the camera to just stop and stay where ever the recoil left you aiming. In other words I want to get rid of the recover part of the code but still have not have the Euler angles messed up. Is this possible?
has this been possible for you Khyrid? i am having the exact same issue.
make the camera a parent of an empty gameobject and call it Recoil or something, this is how i got that issue fixed but im having another issue with Euler where i dont want it to recover but we are forced to.