private void Awake() { rpgCharacterMovementController = GetComponent <RPGCharacterMovementController>(); rpgCharacterWeaponController = GetComponent <RPGCharacterWeaponController>(); rpgCharacterInputController = GetComponent <RPGCharacterInputController>(); animator = GetComponentInChildren <Animator>(); if (animator == null) { Debug.LogError("ERROR: There is no animator for character."); Destroy(this); } //Find HeadLookController if applied. headLookController = GetComponent <PerfectLookAt.PerfectLookAt>(); ikHands = GetComponent <IKHands>(); //Set for starting Relax state. weapon = Weapon.RELAX; animator.SetInteger("Weapon", -1); animator.SetInteger("WeaponSwitch", -1); StartCoroutine(_ResetIdleTimer()); //Turn off headlook in editor. #if UNITY_EDITOR headLook = false; #endif isHeadlook = headLook; }
private void FixSwivelAngle(ref Vector3[] positions) { if (m_afterSolvingSwivelDir == Vector3.zero) { return; } float angle = Vector3.Angle(m_afterSolvingSwivelDir, m_originalSwivelDir); if (angle > 0.0f) { Vector3 swivelAngleAxis = positions[positions.Length - 1] - positions[0]; m_originalSwivelDir.Normalize(); m_afterSolvingSwivelDir.Normalize(); Vector3 CrossVec = Vector3.Cross(m_afterSolvingSwivelDir, m_originalSwivelDir); if (Mathf.Abs(CrossVec.z) > Mathf.Epsilon) { if (CrossVec.y < 0.0f) { swivelAngleAxis = -swivelAngleAxis; } } else if (Mathf.Abs(CrossVec.x) > Mathf.Epsilon) { if (CrossVec.y < 0.0f) { swivelAngleAxis = -swivelAngleAxis; } } else if (Mathf.Abs(CrossVec.z) > Mathf.Epsilon) { if (CrossVec.x < 0.0f) { swivelAngleAxis = -swivelAngleAxis; } } Quaternion swivelRot = PerfectLookAt.QuaternionFromAngleAxis(ref swivelAngleAxis, Mathf.Deg2Rad * angle); Vector3 currentPos; for (int i = positions.Length - 1; i > 0; i--) { currentPos = positions[i] - positions[0]; currentPos = swivelRot * currentPos; positions[i] = positions[0] + currentPos; } } }
public void FixLeg(byte iterations, float minErrorToStartSolving) { if (m_iKWeight <= Mathf.Epsilon || m_BonesCount <= 1) { return; } if ((m_footPosBeforeLookAt - m_FootBone.transform.position).magnitude < minErrorToStartSolving) { return; } //check if the bone numbers are changed at run-time or not to reinitialize and avoid getting null reference exceptions if (m_BoneLengths.Length != m_BonesCount - 1) { Initialize(); } Transform buffTr = m_FootBone; Quaternion originalFootRotMS = m_FootBone.transform.rotation; Transform[] transforms = new Transform[m_BonesCount]; Vector3[] positions = new Vector3[m_BonesCount]; Vector3[] fwdVecs = new Vector3[m_BonesCount - 1]; Vector3 firstBonePos = Vector3.zero; for (int i = 0; i < m_BonesCount; i++) { positions[i] = buffTr.transform.position; transforms[i] = buffTr.transform; if (i < m_BonesCount - 1) { fwdVecs[i] = buffTr.transform.position - buffTr.parent.transform.position; buffTr = buffTr.parent; } else { firstBonePos = buffTr.transform.position; } } m_originalSwivelDir = FindProjectionVector(m_firstBonePosBeforeLookAt, m_middleBonePosBeforeLookAt, m_footPosBeforeLookAt); FABRIKSolver.SolveFabrik(ref positions, ref m_BoneLengths, m_footPosBeforeLookAt, m_IKChainLength, iterations, minErrorToStartSolving); //if knee angle is completely extended and angle between thigh and calf is small we skip updating swivel dir and use the last frame swivel dir. Ths helps to have the right knee hinge axis every frame. float solvedKneeAngle = Vector3.Angle(m_FootBone.transform.position - firstBonePos, positions[m_BonesCount / 2] - firstBonePos); if (solvedKneeAngle > Mathf.Epsilon) { m_afterSolvingSwivelDir = FindProjectionVector(firstBonePos, positions[m_BonesCount / 2], m_footPosBeforeLookAt); } FixSwivelAngle(ref positions); Quaternion RotBuff = Quaternion.identity; Vector3 currentFwdVec; float iKBlendWeight = Mathf.Clamp01(m_iKWeight); for (uint i = m_BonesCount - 1; i > 0; i--) { currentFwdVec = positions[i - 1] - positions[i]; if (i == 1) { fwdVecs[0] = m_FootBone.transform.position - m_FootBone.parent.transform.position; } RotBuff = Quaternion.Slerp(Quaternion.identity, PerfectLookAt.GetWorldLookAtRotation(currentFwdVec, fwdVecs[i - 1]), iKBlendWeight); transforms[i].rotation = RotBuff * transforms[i].rotation; } m_FootBone.transform.rotation = Quaternion.Slerp(m_FootBone.transform.rotation, m_footRotBeforeLookAt, iKBlendWeight); }