- Home /
Animation order problem
Hey, people.
I'm making a third person shooter and to make my animations correct, I modify animations through code. It's nothing out of the ordinary, really. I make the hand point towards where I'm aiming (a smile LookAt in LateUpdate). Then I want to use Inverse Kinematics to put the protagonists left hand on the foregrip of the gun. And that's the problem I'm having and have been having for a long time.
To my understanding, the problem lies in the execution order, that IK happens before Late Update. So my basic solution I want to use is quite simply to get the position of the foregrip after the LookAt in LateUpdate, and then use IK to move the hand into the correct position the next frame. Of course, there would be a one-frame error, but that would be good enough. But nope, that doesn't work either.
Ideas?
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
[RequireComponent(typeof(Animator))]
public class WeaponManager : MonoBehaviour {
[Serializable]
public struct Weapons
{
public string Name;
public GameObject Gun;
public Transform LocalMagazine;
public Vector3 MagazineOffset;
public Quaternion MagazineRotationOffset;
public GameObject WeaponUI;
public Quaternion AimOffset1;
public Quaternion HandOffset;
public Quaternion LastHandRotation;
public Text AmmoText;
public Text MagazineText;
public Transform Foregrip;
public Vector3 ForegripOffset;
public Quaternion ForegripRotationOffset;
public bool HasWeapon;
}
[SerializeField]
public Weapons[] weapons;
public Transform AimPoint;
public Animator PlayerAnimator;
public static int RifleAmmoCount;
Text PistolText;
Text RifleText;
Text RifleMagazineText;
public static int MGAmmoCount;
Text MGText;
public static int GrenadeCount;
public static int ShellCount;
Text ShellText;
Text ShellMagazineText;
int LastWeapon;
public bool Gameplay;
bool HasAR;
bool HasShotgun;
bool HasMG;
public Animator LowerBodyAnimator;
public int Weapon=1;
public int Current;
Transform Chest;
Transform RightHand;
Transform LeftHand;
public Camera MainCamera;
public Transform Foregrip;
public float GripStrength;
Quaternion CurrentOffset;
public Vector3 LastForegripPosition;
private RuleHandler rulehandler;
public ForehandIKScript forehandikscript;
public bool Reloading;
public bool HoldingGun;
public Vector3 PositionOffset;
public Quaternion RotationOffset;
void Start () {
rulehandler= GameObject.FindWithTag("RuleHandler").GetComponent<RuleHandler>();
if (Camera.main == null)
{
MainCamera = GameObject.FindWithTag("MainCamera").GetComponent<Camera>();
}
else
{
MainCamera = Camera.main;
}
Chest = PlayerAnimator.GetBoneTransform(HumanBodyBones.Chest);
RightHand = PlayerAnimator.GetBoneTransform(HumanBodyBones.RightHand);
LeftHand= PlayerAnimator.GetBoneTransform(HumanBodyBones.LeftHand);
weapons[1].AmmoText= GameObject.Find("PistolMagazineReadout").GetComponent<Text>();
weapons[2].AmmoText= GameObject.Find("ShotgunReserveReadout").GetComponent<Text>();
weapons[2].MagazineText = GameObject.Find("ShotgunMagazineReadout").GetComponent<Text>();
weapons[3].AmmoText= GameObject.Find("AssaultRifleReadout").GetComponent<Text>();
weapons[3].MagazineText= GameObject.Find("AssaultRifleMagazineReadout").GetComponent<Text>();
weapons[4].AmmoText= GameObject.Find("MachineGunReadout").GetComponent<Text>();
}
// Update is called once per frame
void FixedUpdate () {
HoldingGun = forehandikscript.HoldingGun;
Reloading = forehandikscript.Reloading;
Gameplay = rulehandler.Gameplay;
weapons[2].AmmoText.text = ShellCount.ToString();
weapons[3].AmmoText.text = RifleAmmoCount.ToString() + "\n" + GrenadeCount.ToString();
weapons[4].AmmoText.text = MGAmmoCount.ToString();
if (Input.GetAxisRaw ("SelectPistol") ==1) {
LowerBodyAnimator.SetInteger("Weapon", 1);
Weapon = 1;
}
if (Input.GetAxisRaw ("SelectShotgun")==1 && HasShotgun == true) {
LowerBodyAnimator.SetInteger("Weapon", 3);
Weapon = 2;
}
if (Input.GetAxisRaw ("SelectPistol")==-1 && HasAR == true) {
LowerBodyAnimator.SetInteger("Weapon", 2);
Weapon = 3;
}
if (Input.GetAxisRaw ("SelectShotgun")==-1 && HasMG == true) {
LowerBodyAnimator.SetInteger("Weapon", 1);
Weapon = 4;
}
if (LastWeapon != Weapon)
{
Reloading = false;
for (int i = 0; i < weapons.Length; i++)
{
if (i == Weapon)
{
if (weapons[i].AmmoText != null)
{
weapons[i].AmmoText.fontSize = 30;
}
if (weapons[i].MagazineText != null)
{
weapons[i].MagazineText.fontSize = 30;
}
if (weapons[i].Gun != null)
{
weapons[i].Gun.SetActive(true);
Debug.Log("Enabling " + weapons[i].Name);
}
else
{
Debug.Log("Unable to disable " + weapons[i].Name);
}
}
else
{
if (weapons[i].AmmoText != null)
{
weapons[i].AmmoText.fontSize = 15;
}
if (weapons[i].MagazineText != null)
{
weapons[i].MagazineText.fontSize = 15;
}
if (weapons[i].Gun != null)
{
weapons[i].Gun.SetActive(false);
Debug.Log("Disabling " + weapons[i].Name);
}
else
{
Debug.Log("Unable to disable " + weapons[i].Name);
}
}
}
//Debug.Log("Creating enemy number: " + i);
}
if (Reloading == true)
{
Foregrip = weapons[Weapon].LocalMagazine;
PositionOffset = weapons[Weapon].ForegripOffset;
RotationOffset = weapons[Weapon].ForegripRotationOffset;
}
else
{
Foregrip = weapons[Weapon].Foregrip;
PositionOffset = weapons[Weapon].ForegripOffset;
RotationOffset = weapons[Weapon].ForegripRotationOffset;
}
LastWeapon = Weapon;
}
void LateUpdate()
{
if (Gameplay==true)
{
Chest.LookAt(AimPoint.transform.position);
CurrentOffset = Quaternion.Lerp(CurrentOffset, weapons[Weapon].AimOffset1, 0.1f);
Chest.rotation = Chest.rotation * CurrentOffset;
LastForegripPosition = Foregrip.position;
if (HoldingGun == true)
{
RightHand.LookAt(AimPoint.transform.position);
RightHand.rotation = RightHand.rotation * weapons[Weapon].HandOffset;
weapons[Weapon].LastHandRotation = RightHand.rotation;
}
else
{
}
}
}
void OnAnimatorIK()
{
if (HoldingGun == true)
{
//GripStrength = Mathf.Lerp(GripStrength, 0.9f, 0.5f);
PlayerAnimator.SetIKPositionWeight(AvatarIKGoal.LeftHand, GripStrength);
PlayerAnimator.SetIKRotationWeight(AvatarIKGoal.LeftHand, GripStrength);
PlayerAnimator.SetIKPosition(AvatarIKGoal.LeftHand, Foregrip.position);
PlayerAnimator.SetIKRotation(AvatarIKGoal.LeftHand, Foregrip.rotation * RotationOffset);
}
else
{
//GripStrength = Mathf.Lerp(GripStrength, 0, 0.5f);
PlayerAnimator.SetIKPositionWeight(AvatarIKGoal.LeftHand, GripStrength);
PlayerAnimator.SetIKRotationWeight(AvatarIKGoal.LeftHand, GripStrength);
}
}
public void AmmoPickup(int RoundAmmount, string ammotype)
{
if (ammotype == "AssaultRifle")
{
RifleAmmoCount += RoundAmmount;
HasAR = true;
if (RifleAmmoCount >= 200)
{
RifleAmmoCount = 200;
}
}
if (ammotype == "Grenade")
{
GrenadeCount += RoundAmmount;
HasAR = true;
if (GrenadeCount >= 6)
{
GrenadeCount = 6;
}
}
if (ammotype == "ShotgunShell")
{
ShellCount += RoundAmmount;
HasShotgun = true;
if (ShellCount >= 200)
{
ShellCount = 200;
}
}
if (ammotype == "MachineGunAmmo")
{
MGAmmoCount += RoundAmmount;
HasMG = true;
if (MGAmmoCount >= 1000)
{
MGAmmoCount = 1000;
}
}
}
}
Your answer
![](https://koobas.hobune.stream/wayback/20220613052647im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Prefab .fbx updates 0 Answers
Trigger animation-function in Update 0 Answers
Setting position after respawn. 0 Answers
How to update 3D character 1 Answer
Stop the Update function so death animation can complete. 1 Answer