using System; using RootMotion.FinalIK; using UnityEngine; [Serializable] public class ElbowKneeIKCtrl : ALimbIKCtrl { public ElbowKneeIKCtrl(FBIKChain chain, IKMappingLimb ik_mapping, FullBodyIKMgr ik_ctrl, FullBodyIKMgr.IKEffectorType effector_type) : base(ik_ctrl, chain, ik_mapping, effector_type) { this.chain.bendConstraint.bendGoal = base.constraintTarget; base.isUpperBody = (effector_type == FullBodyIKMgr.IKEffectorType.Forearm_L || effector_type == FullBodyIKMgr.IKEffectorType.Forearm_R); this.FABRIK = base.constraintTarget.parent.gameObject.AddComponent(); this.FABRIK.solver.SetChain(new Transform[] { base.chainBones[0], base.chainBones[1] }, base.chainBones[0]); this.FABRIK.solver.target = base.constraintTarget; this.FABRIK.enabled = false; if (!base.isUpperBody) { if (this.isLeft) { base.limbCapsule = this.myIKMgr.body.limbColliderMgr.GetCollider(LimbColliderMgr.LimbType.Thigh_L); } else { base.limbCapsule = this.myIKMgr.body.limbColliderMgr.GetCollider(LimbColliderMgr.LimbType.Thigh_R); } } else if (this.isLeft) { base.limbCapsule = this.myIKMgr.body.limbColliderMgr.GetCollider(LimbColliderMgr.LimbType.UpperArm_L); } else { base.limbCapsule = this.myIKMgr.body.limbColliderMgr.GetCollider(LimbColliderMgr.LimbType.UpperArm_R); } } public override bool isLeft { get { return this.effectorType == FullBodyIKMgr.IKEffectorType.Forearm_L || this.effectorType == FullBodyIKMgr.IKEffectorType.Calf_L; } } public override ALimbIKCtrl pairIK { get { FullBodyIKMgr.IKEffectorType effector_type; if (base.isUpperBody) { effector_type = ((!this.isLeft) ? FullBodyIKMgr.IKEffectorType.Forearm_L : FullBodyIKMgr.IKEffectorType.Forearm_R); } else { effector_type = ((!this.isLeft) ? FullBodyIKMgr.IKEffectorType.Calf_L : FullBodyIKMgr.IKEffectorType.Calf_R); } return this.myIKMgr.GetIKCtrl(effector_type); } } public ShoulderThighIKCtrl shoulderThighCtrl { get; private set; } public HandFootIKCtrl handFootCtrl { get; private set; } public void SetChain(HandFootIKCtrl handfoot_data, ShoulderThighIKCtrl shoulderthigh_data) { this.handFootCtrl = handfoot_data; this.ChainChildCtrl = handfoot_data; this.shoulderThighCtrl = shoulderthigh_data; this.ChainParentCtrl = shoulderthigh_data; } public override void TargetTransCpy() { base.TargetTransCpy(); this.chain.bendConstraint.weight = 0f; this.FABRIK.solver.IKPositionWeight = 0f; } public override void ApplyIKSetting() { this.BoneLocalRot = base.bone.localRotation; this.HandFootLocalRot = this.handFootCtrl.bone.localRotation; base.ApplyIKSetting(); } protected override void SetTargetTransform(AIKCtrl.IKSettingData data, Vector3 pos, Quaternion rot) { base.SetTargetTransform(data, pos, rot); Vector3 vector = this.shoulderThighCtrl.bone.InverseTransformPoint(base.bone.position); Transform constraintTarget = this.shoulderThighCtrl.constraintTarget; if (data.isPointAttach) { constraintTarget.rotation = Quaternion.FromToRotation(base.bone.position - constraintTarget.position, base.constraintTarget.position - constraintTarget.position) * constraintTarget.rotation; if (!this.shoulderThighCtrl.pointIKData.isIKExecNotWeight0) { this.shoulderThighCtrl.positionWeight = Mathf.Max(base.positionWeight, this.shoulderThighCtrl.positionWeight); Vector3 position = base.bone.InverseTransformPoint(this.shoulderThighCtrl.bone.position); constraintTarget.position = base.constraintTarget.TransformPoint(position); } } else { Vector3 axis = base.constraintTarget.position - constraintTarget.position; Quaternion rotation = base.constraintTarget.rotation; Vector3 lhs = rotation * Vector3.forward; Vector3 rhs = base.bone.rotation * Vector3.forward; float f = Vector3.Dot(lhs, rhs); float num = Mathf.Acos(f) * 57.29578f; if (float.IsNaN(num)) { num = 0f; } constraintTarget.rotation = Quaternion.AngleAxis(num, axis) * constraintTarget.rotation; } } protected override void DoPlaneCorrect(Vector3 normal) { base.DoPlaneCorrect(normal); if (this.correctType == ALimbIKCtrl.BorderCorrectType.HalfBody) { Transform constraintTarget = this.shoulderThighCtrl.constraintTarget; constraintTarget.position += normal; if (!this.shoulderThighCtrl.pointIKData.isIKExec) { this.shoulderThighCtrl.positionWeight = base.positionWeight; } } } public override void OnPostFullBodySolverUpdate() { if (!base.isIKExec || this.handFootCtrl.isIKExecNotWeight0) { base.OnPostFullBodySolverUpdate(); return; } if (base.rotateIKData.isIKExec) { this.shoulderThighCtrl.bone.rotation = Quaternion.Slerp(this.shoulderThighCtrl.bone.rotation, this.shoulderThighCtrl.constraintTarget.rotation, base.rotationWeight); base.bone.localRotation = this.BoneLocalRot; this.handFootCtrl.bone.localRotation = this.HandFootLocalRot; } Quaternion rotation = base.bone.rotation; if (base.pointIKData.isIKExec) { this.FABRIK.solver.Update(); base.bone.rotation = rotation; } base.OnPostFullBodySolverUpdate(); } protected override void OnPostSetPositionWeight(float val) { if (this.IsPullBody) { this.chain.bendConstraint.weight = val; } this.FABRIK.solver.IKPositionWeight = val; } private FABRIK FABRIK; private Quaternion HandFootLocalRot = Quaternion.identity; private Quaternion BoneLocalRot = Quaternion.identity; }