using System; using RootMotion.FinalIK; using UnityEngine; [Serializable] public class FABRIKCtrl : AIKCtrl { public FABRIKCtrl(FullBodyIKMgr ik_mgr, FullBodyIKMgr.IKEffectorType effector_type) : base(ik_mgr, effector_type) { this.IK = base.constraintTarget.parent.gameObject.AddComponent(); this.IK.solver.target = base.constraintTarget; this.IK.fixTransforms = false; this.IK.solver.SetChain(this.ChainBones, this.ChainBones[0]); this.IK.enabled = false; for (int i = 0; i < this.ChainBones.Length - 1; i++) { Transform transform = this.ChainBones[i]; Transform transform2 = base.chainBones[i + 1]; this.BoneLengthSum += Vector3.Distance(transform.position, transform2.position); } } public override void OnPostFullBodySolverUpdate() { if (base.pointIKData.isIKExec) { if (base.pointIKData.isBlendNow) { float num = Vector3.Distance(this.ChainBones[0].position, base.constraintTarget.position); if (num > this.BoneLengthSum) { Vector3 a = this.ChainBones[0].position - base.constraintTarget.position; base.constraintTarget.position += a / num * (num - this.BoneLengthSum); float num2 = 1f - Mathf.Clamp01((num - this.BoneLengthSum) / this.BoneLengthSum); base.positionWeight *= num2; } } this.IK.solver.Update(); } if (base.rotateIKData.isIKExec) { base.bone.rotation = Quaternion.Slerp(base.bone.rotation, base.constraintTarget.rotation, base.rotationWeight); } } protected override void OnPostSetPositionWeight(float val) { this.IK.solver.IKPositionWeight = val; } [SerializeField] protected FABRIK IK; protected readonly float BoneLengthSum; }