コード例 #1
0
        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;
        }
コード例 #2
0
        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;
                }
            }
        }
コード例 #3
0
        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);
        }