|
Right now in our first-person game we have an aiming system similar to (but not exactly like) Red Orchestra (http://www.youtube.com/watch?v=oiP82nAV9xM if you're not familiar): when the player moves the mouse, the screen will reorient perfectly, but the gun's aim will interpolate to follow the player's head with a little lag (to simulate imperfect aim when firing from the hip). However, though right now the implementation we have works, it doesn't constrain the gun's movement when the player moves their aim too quickly for the gun to catch up. The result is that if the player moves the aim too quickly the gun will fall so far behind that it ends up just rotating around and around if the player moves their aim quickly enough. Anyway, here's the relevant code we have so far, along with some failed solutions I've already tried. Anyone have any ideas on how to solve this problem? Obviously I don't understand Quaternions well enough to solve this myself.
(comments are locked)
|
|
I did something similar once just Lerp'ing the weapon to follow its parent. That's my hierarchy:
Player
Camera
Weapon Holder <- script attached to this empty object
Machine Gun
Rocket Launcher
Laser Gun
etc.
That's the script:
var speed: float = 15;
private var localRot: Quaternion;
private var curRot: Quaternion;
function Start () {
localRot = transform.localRotation; // save starting local rotation
curRot = transform.rotation;
}
function Update () {
// targetRot is the ideal rotation:
var targetRot = transform.parent.rotation * localRot;
// curRot follows targetRot with some delay:
curRot = Quaternion.Lerp(curRot, targetRot, speed * Time.deltaTime);
transform.rotation = curRot;
}
EDITED: I can't understand your script because some parts are missing, but I suppose it's similar to mine: you get the desired rotation and Lerp to it using Time.deltaTime (we both should use Slerp instead!).
public float maxAngle = 10;
private Quaternion curRotation; // the current weapon rotation
...
// Slerp to it over time:
curRotation = Quaternion.Slerp(curRotation, aimAtAimPoint, Time.deltaTime * aimSpeed);
float angle = Quaternion.Angle(curRotation, targetRot);
if (angle > maxAngle){ // if maxAngle exceeded...
// find max rotation using interpolation:
curRotation = Quaternion.Slerp(aimAtAimPoint, curRotation, maxAngle/angle);
}
...
How it works: if angle > maxAngle, the value maxAngle/angle is exactly what you need to find the max acceptable rotation by interpolating between aimAtAimPoint and curRotation. The interpolation must be linear in degrees, what means Slerp, the spherical interpolation. Unfortunately that doesn't seem to work. It actually just makes the weapon keep the same rotation over time (it just Lerps the gun back to wherever it was pointing to begin with, no matter where the player is looking). I made sure to disable our previous rotation code so that didn't affect it, so I'm not sure why it's doing that. Forgive me if I'm wrong, but it seems like your script would have the same problems in the end anyway (the gun not rotating fast enough if the player moves the camera too quickly). Our goal is to have the gun's rotation constrained so that it never points anywhere off screen from a first-person perspective.
Apr 07 '12 at 05:25 PM
VVander
I don't know why my script didn't work in your case, but maybe it's due to differences in the hierarchy. Anyway, you can limit the max angle between the ideal and the delayed rotations using a smart trick with interpolation. Take a look at my answer: I edited it to include this limit (and translated it to C#, too...)
Apr 08 '12 at 11:41 PM
aldonaletto
(comments are locked)
|
