I am building an FPS game in Unity 3D everything was going cool but when I tried to implement aiming for the rifle everything just broke.
1): I have an IK setup which triggers when you equip weapon, this IK only calculate the hand position and orientation needed to hold the gun and after that the IK system disables itself, basically I am using IK for getting the proper hand position on different guns.
2): Once hands are positioned correctly on the gun then I rotate the hands(or spine, which will rotate hands and head with it) with the mouse to look up, down, right and left.
3): Handgun is very easy to handle, equip it and rotate the arms, arms are almost straight along the z-axis so I just rotate them on the y-axis to aim upward and downwards.
4): With the rifle, I can calculate the hand position and rotation to hold the rifle easily but (because static animation pose of holding he rifle is little oriented to make the player little realistic) when I rotate arms they rotate weirdly.
I checked in the editor by changing the y-axis of the rotation and found that only y-axis can't rotate the arm the way I want and to rotate it that way other axis must change their values. I searched a bit and found that it is a situation called as Gimbal Lock which is very common with euler rotations, I tried many things but still can't fix it.
leftArm.transform.localEulerAngles = new Vector3(leftArm.transform.localEulerAngles.x, leftArm.transform.localEulerAngles.y + (currentCamRotX + offset), leftArm.transform.localEulerAngles.z); rightArm.transform.localEulerAngles = new Vector3(rightArmFPS.transform.localEulerAngles.x, rightArmFPS.transform.localEulerAngles.y + (currentCamRotX + offset), rightArmFPS.transform.localEulerAngles.z);
It works great with Handgun but not with Rifle.
I read about and tried following but in vain:
//Method 1: Failed var target = camera.GetChild(0).GetChild(0); var direction = target.position - rightArmFPS.position; var toRotation = Quaternion.FromToRotation(rightArmFPS.up, direction); rightArmFPS.rotation = Quaternion.Lerp(rightArmFPS.rotation, toRotation, Time.deltaTime * 5); //Method 2: Failed var targetForward = target.position - spine.position; targetForward.Normalize(); var rotAxis = Vector3.Cross(Vector3.forward, targetForward); var angle = Mathf.Acos(Vector3.Dot(Vector3.forward, targetForward)) * Mathf.Rad2Deg; spine.eulerAngles = rotAxis * angle;
What I am looking for now is if someone can point me what topic I should be looking in(because my poor maths skills are really getting me and I often use very poor workarounds for what could be solved easily with maths or physics), pseudo code to get me started or anything that might help me resolving this issue.
I know there are bunch of other ways to achieve what I am looking for and I have tried many of them like: using IK to position hands and then moving the guns up or down or having animations for each gun aiming up or down but honestly each method has it's own drawback(or its just me who is too noob for these things).
I followed this solution: Orienting a model to face a target
and many others, you might find it duplicate but none of the post on the internet has solved my problem(it is second day and I still can't figure this out).
Hope you understood the question and thanks for reading this:)