Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Animation & Aiming

Discussion in 'Animation' started by cyberdev3, Apr 13, 2023.

  1. cyberdev3

    cyberdev3

    Joined:
    Dec 28, 2018
    Posts:
    43
    Hello. I'm working on a third person game. On the stage there is a character with animations on the Animator component. When starting the game, the character stands still and aims at a certain point. This was done using an "aiming" animation with just one frame. Further, a script hangs on the character, which should carry out aiming.
    using UnityEngine;

    Code (CSharp):
    1. public class TestRotator : MonoBehaviour
    2. {
    3.     [SerializeField] Transform spin;
    4.     [SerializeField] Vector2 sensinivity = new Vector2(1, 1);
    5.  
    6.     void LateUpdate()
    7.     {
    8.         Vector2 axis;
    9.  
    10.         axis.x = Input.GetAxis("Mouse X");
    11.         axis.y = Input.GetAxis("Mouse Y");
    12.  
    13.         spin.Rotate(axis.y * sensinivity.x, -axis.x * sensinivity.y, 0);
    14.  
    15.     }
    16. }
    That is, rotate the "spin" bone with the mouse. But as a result of starting the game on the stage, only the twitching of the character's hands is visible. The "aiming" animation overwrites the rotation result of the "spin" bone. How to make aiming work and animations also play? For example, I want to add a recoil animation when fired. But any animation will overwrite the result of the "spin" rotation. How can I solve this problem?
     
  2. maymaygamer

    maymaygamer

    Joined:
    Oct 22, 2022
    Posts:
    4
    if your animation is not working you can try animation rigging and ik constraints you can find tutorials on it. i recommend the code monkey's... hope this helps:)
     
  3. ElXill

    ElXill

    Joined:
    Jun 2, 2017
    Posts:
    43
    If I'm not wrong, rotate swaps your angle, it doesn't rotate with the given angle.
    Try accumulating the inputs with something like this
    axis.x += Input.GetAxis("Mouse X");


    I'm guessing rotate, late update and animations should work nicely togather.

    If you want to use rotate by combining animation you can just add object rotation and new value togather,
    spin.Rotate(spin.rotation.x + axis.y * sensinivity.x, spin.rotation.y -axis.x * sensinivity.y, 0);

    Now this code will couse interaction with animation and twiching really bad. I think you can overcome this by temporarily storing object rotation.
     
  4. cyberdev3

    cyberdev3

    Joined:
    Dec 28, 2018
    Posts:
    43
    All the same, the bone "spin" does not rotate, but only twitches. The animator still overwrites changes made by the script.
     
  5. maymaygamer

    maymaygamer

    Joined:
    Oct 22, 2022
    Posts:
    4
    if your animations are not working with script you should use animation rigging and ik constraints instead if you need to use script let me know.
     
  6. ElXill

    ElXill

    Joined:
    Jun 2, 2017
    Posts:
    43
    Hmm, I used your script with my suggestion and it worked, rotation doesn't look good but it works fine. I removed sensitivity to keep it simpler and just go with *10.

    {
    public Transform spin;
    Vector2 axis;

    void LateUpdate()
    {
    axis.x += Input.GetAxis("Mouse X");
    axis.y += Input.GetAxis("Mouse Y");

    spin.Rotate(axis.y * 10, -axis.x * 10, 0);
    }
    }
     
  7. cyberdev3

    cyberdev3

    Joined:
    Dec 28, 2018
    Posts:
    43
    Simply multiplying the axes won't help because, in my case, the animation will overwrite the results of the script anyway. I need the animation to not overwrite the rotaion. Maybe you know a video tutorial showing how to make player aiming in third person view with animations working properly.
     
  8. maymaygamer

    maymaygamer

    Joined:
    Oct 22, 2022
    Posts:
    4
    look up animation rigging and ik for tps games in unity if you can not use this way let me know.
     
  9. cyberdev3

    cyberdev3

    Joined:
    Dec 28, 2018
    Posts:
    43
    Made an experimental scene with an improvised hand. I animated the top, and rotated the hand with the script. It turned out to be a correct rotation. Conclusion: a bone that is rotated using a script should not be affected by animation. But how to remove the effect of the animation imported from the fbx file on the rotated bone, if the transformations there are not indicated by rotation, scale and position, since Unity has its own terminology for designating the transformations of animated objects? Where can I read about the terminology of animation in Unity?
     
  10. ElXill

    ElXill

    Joined:
    Jun 2, 2017
    Posts:
    43
    You can combine animation and script rotation by adding or substracting with script from rig's current animated state. If you used something like the code I wrote above, it should override all animaiton data.
    I won't go too much into detail but you can use something like this for animation data + script modification (the code may be wrong i didn't checked it but you get the idea, you should add bone rotation in script).

    spin.Rotate(spin.rotation.euler.x + axis.y * 10,spin.rotation.euler.y -axis.x * 10, 0)


    I think you should do a little more trial and error and do little test scenerios to understand how everything acts together. Becouse transformations are indicated by rotation, scale and position, only thing more to that is quaternions, which is how Unity calculates rotation but it shows us euler angles.

    I didn't come across with any different terminology special to unity, everything is pretty similar with what other programs has.
     
  11. cyberdev3

    cyberdev3

    Joined:
    Dec 28, 2018
    Posts:
    43
    I'll try to add your code. But with regard to the specific terminology (that I was talking about), it is. Here is an example scanned from a screenshot of the "Animation" animation editor window:

    Code (CSharp):
    1. > character-1 : Animator.Chest Left-Right 0
    2. > character-1 : Animator.Chest Twist Left-Right 0
    3. > character-1 : Animator.Head Nod Down-Up 23479
    4. > character-1 : Animator.Head Tilt Left-Right 28613e
    5. > character-1 : Animator.Head Tur Left-Right 5.336le
    6. > character-1 : Animator.Jaw Close 0
    7. > character-1 : Animator.Jaw Left-Right 0 5
    8. > character-1 : Animator.Left Arm Down-Up -0.6858
    9. > character-1 : Animator.Left Arm Front-Back 0.28028
    10. > character-1 : Animator.Left Arm Twist In-Out 0.1295
    11. > character-1 : Animator.Left Eye Down-Up. o 5
    12. > character-1 : Animator.Left Eye In-Out 0 5
    13. > character-1 : Animator. Left Foot Twist In-Out 0.0039 0
    14. > character-1 : Animator.Left Foot Up-Down -0.0328
    15. > character-1 : Animator.Left Forearm Stretch o7e7a
    16. > character-1 : Animator.Left Forearm Twist In-Out 0.22082
    17. > character-1 : Animator.Left Hand Down-Up. -0.0751
    18. > character-1 : Animator.Left Hand In-Out 0.099%
    19. > character-1 : Animator.Left Lower Leg Stretch 0.99822
    This is a snippet from an imported animation from Blender's blend file. All that I managed to learn from this terminology is that "Left Right" is a turn to the right - to the left. Therefore, I would like to know what the rest of the terms mean. Maybe there is a description of these terms on the Internet? I would be very grateful for a link to the material where this is described.
     
  12. ElXill

    ElXill

    Joined:
    Jun 2, 2017
    Posts:
    43
    Ah.. So this is what you mean. This is about Unity's Mecanim Humanoid system. Depending on your workflow mecanim could really make your job easy. It can retarget animations of different humanoid characters to your character and it has bunch of other features (it probably has a feature for aiming hand too probably something about IK). It also changes animaton data to a muscle system data which is the table in your post.

    At the same time using it makes your intervention with script much more complex. You can change those values in script but I wouldn't recommend that.

    Using Mecanim is optional you can use generic animations too. But I would suggest learning more about it before trying to use generic animations.

    You can read more about here;
    https://docs.unity3d.com/Manual/AnimationOverview.html

    And here is some info about IK in mecanim;
    https://docs.unity3d.com/Manual/InverseKinematics.html
     
    Last edited: Apr 18, 2023
    cyberdev3 likes this.
  13. cyberdev3

    cyberdev3

    Joined:
    Dec 28, 2018
    Posts:
    43
    Tried adding your code but it doesn't work. I realized that the code cannot directly rotate the bones when they are affected by animation. I decided to try to do as in the example https://docs.unity3d.com/Manual/InverseKinematics.html.

    Code (CSharp):
    1. using UnityEngine;
    2. using System;
    3. using System.Collections;
    4.  
    5. [RequireComponent(typeof(Animator))]
    6.  
    7. public class IKControl : MonoBehaviour {
    8.  
    9.     protected Animator animator;
    10.  
    11.     public bool ikActive = false;
    12.     public Transform rightHandObj = null;
    13.     public Transform lookObj = null;
    14.  
    15.     void Start ()
    16.     {
    17.         animator = GetComponent<Animator>();
    18.     }
    19.  
    20.     //a callback for calculating IK
    21.     void OnAnimatorIK()
    22.     {
    23.         if(animator) {
    24.  
    25.             //if the IK is active, set the position and rotation directly to the goal.
    26.             if(ikActive) {
    27.  
    28.                 // Set the look target position, if one has been assigned
    29.                 if(lookObj != null) {
    30.                     animator.SetLookAtWeight(1);
    31.                     animator.SetLookAtPosition(lookObj.position);
    32.                 }  
    33.  
    34.                 // Set the right hand target position and rotation, if one has been assigned
    35.                 if(rightHandObj != null) {
    36.                     animator.SetIKPositionWeight(AvatarIKGoal.RightHand,1);
    37.                     animator.SetIKRotationWeight(AvatarIKGoal.RightHand,1);
    38.                     animator.SetIKPosition(AvatarIKGoal.RightHand,rightHandObj.position);
    39.                     animator.SetIKRotation(AvatarIKGoal.RightHand,rightHandObj.rotation);
    40.                 }      
    41.  
    42.             }
    43.  
    44.             //if the IK is not active, set the position and rotation of the hand and head back to the original position
    45.             else {        
    46.                 animator.SetIKPositionWeight(AvatarIKGoal.RightHand,0);
    47.                 animator.SetIKRotationWeight(AvatarIKGoal.RightHand,0);
    48.                 animator.SetLookAtWeight(0);
    49.             }
    50.         }
    51.     }  
    52. }
    But, unfortunately, the character turns only the head behind the tracking object. The right hand does not move after him. With what it can be connected? Does Unity have inverse kinematics in the imported rig from the character model initially or does it need to be added? I got the impression that IK is present for the head, but not for the right rune.
     
  14. ElXill

    ElXill

    Joined:
    Jun 2, 2017
    Posts:
    43
    Yeah, my code won't work in case it is used in humanoid/mecanim rig. I don't really have any experience with mecanim IK, I just know it exists. I couldn't find any other useful source about it.