Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How do you properly work with angular velocity/acceleration?

Discussion in 'Scripting' started by PartyBoat, Aug 24, 2016.

  1. PartyBoat

    PartyBoat

    Joined:
    Oct 21, 2012
    Posts:
    97
    So first of all let me give you a good visual of what I'm trying to do:


    As you can see I'm working on adding recoil to my weapons (and yes in this case I'm adding recoil to the actual weapon instead of the camera because I'm working in VR, although in practice I assume the math behind everything should be about the same).

    For the ridiculous number of FPS games that have been made it seems kind of crazy to me how hard it is to find some solid information on how to get this done. A lot of tutorials or answers to this question don't account for recoil that isn't purely pitch-based (aka in the examples recoil only brings the camera/weapon straight up).

    I'm interested in recoil that can affect both the pitch and the yaw of the weapon at the same time. Working with angles works fine for only changing pitch but it has proven to be pretty annoying to try and add some rotational acceleration to the weapon in a direction like shown in the image above. This is mainly because I want to have control over the magnitude of the velocity (i.e. how big the recoil "kick" is in that direction), and working in pitch and yaw separately doesn't let me do that.

    So what I would really like to be able to do is think about the recoil I add to the gun as a vector. This would make it much easier for me to work with and think about (especially when it comes to adding multiple rotational accelerations together like when adding the recoil from firing to the "gravity" applied to the gun that brings it back down). I feel really comfortable working with the positions of objects in 3D space (adding accelerations to the object's velocity, and adding its velocity to its position), and I'd like to feel just as comfortable working with rotations.

    Can anybody tell me how to properly add angular accelerations/velocities (am I even using the right term?) to an object like shown in the reference image? In particular I'd like to be able to understand how to add accelerations to the rotational velocity of an object in a similar way to how I can add accelerations to positional velocity.

    TL;DR: In short, what is the rotational version of this?:

    Code (CSharp):
    1.     acceleration = movementForce + gravityForce;
    2.     velocity += acceleration * Time.deltaTime;
    3.     controller.Move(velocity * Time.deltaTime);

    Thanks a bunch!
     
    Last edited: Aug 24, 2016
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    OK, first of all, the reason you don't see solid information on how this is done is because (I would bet serious pizza money) it is pretty much always done as a simple animation. It's no different from animating anything else.

    But anyway, if I understand you correctly, you just need to know how to work better with rotations. It sounds like you're currently dealing in Euler angles, which do indeed lead to grief. You need to embrace quaternions, and then all your orientation/rotation manipulations become just as easy as working with positions/translations.

    A bit of quick googling turned up this tutorial... I don't know if it's any good, but it looks like a reasonable one to try.
     
    HoodieBashoo likes this.
  3. PartyBoat

    PartyBoat

    Joined:
    Oct 21, 2012
    Posts:
    97
    Yeah I've looked into quaternions, but all of the tutorials teach really basic or obvious stuff (like the Unity tutorial that you linked, it only tells you how to use the LookAt function which is about the least helpful thing they could have gone over). The best info I could find was in this article, but I couldn't understand it well enough to bring it into Unity.

    The most helpful part of that article is this:

    I think what this is suggesting is that to convert the angular velocity vector into a usable quaternion which you can add to an object's rotation you need to use something like Quaternion.AngleAxis() and use the length of the vector as the angle parameter, and use direction of the vector as the axis parameter. However, I haven't been able to get that to work, or convert the code in the article into something that works in Unity.
     
  4. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Your understanding is correct; that particular (in my opinion, somewhat goofy) way of representing angular velocity mushes together the rotation axis (as the direction of the vector) and speed (as the length of the vector).

    So, as you said, to convert that into Unity you'd do something like:

    Code (CSharp):
    1. Quaternion angVel = Quaternion.AngleAxis(a.magnitude, a.normalized);
    where a is your angular velocity vector.

    I am curious, though, why you don't just use an animation for the gun recoil. No code required at all.
     
  5. PartyBoat

    PartyBoat

    Joined:
    Oct 21, 2012
    Posts:
    97
    How could I use an animation for gun recoil when it needs to be totally procedural? Or do you mean I should use some kind of tween?

    Edit: Also I did try implementing the angle axis method and it certainly makes no intuitive sense for what I am trying to do. So you're probably right about it being the wrong way to do this.
     
  6. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    The modern practice is to use a blend space so you have min and max recoil animations for your gun and you can supply a value to the animator to determine how much it will blend between the animations at runtime. You can get pretty fancy with blending between different recoil directions to create totally unique results for every gun/projectile type.

    This is how modern games have the running animation's direction and speed mapped to the actual character movement.

    https://docs.unity3d.com/Manual/class-BlendTree.html
     
    JoeStrout likes this.
  7. PartyBoat

    PartyBoat

    Joined:
    Oct 21, 2012
    Posts:
    97
    I did a quick google search on using blend trees for weapon recoil in Unity and found nothing. Looks way too complicated for what I want to do, or maybe it's not but its use for this purpose seems completely undocumented. Using an animation curve looks more useful, but it still has the problem of needing to change direction, and size etc. Basically it has all the problems of the pure math way that I have been trying to figure out.
     
  8. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    That's because blend trees can be used for anything. There's no specific tutorial for recoil because that's an uncommon thing to need procedural animation for but the process is the same for creating them.

    You could use a tweening library like DoTween. They have rotational punch and easing that you can use to fire off a one liner procedural animation. There are parameters for random or not random directions, amount of elasticity, etc. Could work for you.

    See the Transform section under "B. The shortcuts way":
    dotween.demigiant.com/documentation.php
     
    JoeStrout likes this.