Search Unity

Weapon Recoil - Forward Vector seems to be global and not local

Discussion in 'Scripting' started by Justin_Donaldson, Aug 13, 2019.

  1. Justin_Donaldson

    Justin_Donaldson

    Joined:
    Apr 19, 2019
    Posts:
    1
    Hey all,
    Been banging my head trying to figure this out and I get the feeling it is a simple oversight on my part. The Code Below is used to create weapon recoil.

    The issue: the weapon recoils but towards the global Z axis, and not the local Z axis - The model is in a hierarchy with an empty object first, then the attached objects such as player model, weapon model, pivot points etc beneath. At the moment, the weaponHolderIk.gameObject is always facing the appropriate direction that -Transform.forward, should return the correct recoil direction. Can someone help me understand what I missed or have done wrong here?

    Code (CSharp):
    1.     float rotationSpeed = 10f;
    2.     Transform aimTarget;
    3.     Animator anim;
    4.     GameObject rightShoulderIKHelper;
    5.     Transform rightShoulder;
    6.     Transform weaponHolderIK;
    7.     Vector3 offsetShoulderPosition;
    8.     float returnSpeed = 30f;
    9.     bool IsFiring;
    10.  
    11.     private void Start()
    12.     {
    13.         anim = GetComponentInChildren<Animator>();
    14.         rightShoulder = anim.GetBoneTransform(HumanBodyBones.RightUpperArm);      
    15.         rightShoulderIKHelper = new GameObject("Right Shoulder Helper IK");
    16.     }
    17.  
    18.     private void Update()
    19.     {
    20.         HandleShoulderMovementWithHelper();
    21.     }
    22.  
    23.     void HandleShoulderMovementWithHelper()
    24.     {
    25.         SmoothLookAt(weaponHolderIK);
    26.  
    27.         Vector3 rightShoulderPos = rightShoulder.TransformPoint(Vector3.zero);
    28.         rightShoulderIKHelper.transform.position = rightShoulderPos;
    29.         if (rightShoulderIKHelper.transform.parent != transform)
    30.             rightShoulderIKHelper.transform.parent = transform;
    31.  
    32.         RecoilSystemFinal();
    33.     }
    34.  
    35.     private void RecoilSystemFinal()
    36.     {
    37.         offsetShoulderPosition = Vector3.Lerp(offsetShoulderPosition, rightShoulderIKHelper.transform.localPosition, Time.deltaTime * returnSpeed);
    38.         weaponHolderIK.localPosition = Vector3.Lerp(weaponHolderIK.localPosition, offsetShoulderPosition, Time.deltaTime * returnSpeed);
    39.     }
    40.  
    41.  
    42.     public void FireRecoil(float recoil)
    43.     {
    44.         offsetShoulderPosition += aimTarget.forward * -recoil;
    45.     }
     
  2. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,748
    Unity resets animated objects to default (T-Pose for humanoids) at the beginning of every frame. Thus, in Update you're getting original positions and rotations. In order to affect animated transforms, you want to read/write them in the LateUpdate. But if you want nice recoil, you want to affect hands IK target positions.