using System; using RootMotion.FinalIK; using UnityEngine; [Serializable] public class HandFootIKData : LimbIKData { public HandFootIKData(IKEffector effector, FBIKChain chain, IKMappingLimb ik_mapping, FullBodyIKCtrl ik_ctrl, Transform tgt_bone, bool use_old = false) : base(ik_ctrl, chain, ik_mapping, tgt_bone, use_old) { this.Effector = effector; this.Effector.target = base.IKTarget; this.m_IsUpperBody = (this.TargetBone == this.MyIKCtrl.GetIKBone(FullBodyIKCtrl.IKBoneType.Hand_L) || this.TargetBone == this.MyIKCtrl.GetIKBone(FullBodyIKCtrl.IKBoneType.Hand_R)); this.m_ForceIKEnable = true; this.NoPullBodyIK = base.IKTarget.parent.gameObject.AddComponent(); this.NoPullBodyIK.solver.SetChain(base.ChainBones[0], base.ChainBones[1], base.ChainBones[2], base.ChainBones[0]); this.NoPullBodyIK.solver.target = base.IKTarget; this.NoPullBodyIK.solver.bendModifier = IKSolverLimb.BendModifier.Goal; this.NoPullBodyIK.solver.maintainRotationWeight = effector.maintainRelativePositionWeight; this.NoPullBodyIK.enabled = false; if (this.TargetBone == this.MyIKCtrl.GetIKBone(FullBodyIKCtrl.IKBoneType.Hand_L)) { this.NoPullBodyIK.solver.goal = AvatarIKGoal.LeftHand; } else if (this.TargetBone == this.MyIKCtrl.GetIKBone(FullBodyIKCtrl.IKBoneType.Hand_R)) { this.NoPullBodyIK.solver.goal = AvatarIKGoal.RightHand; } else if (this.TargetBone == this.MyIKCtrl.GetIKBone(FullBodyIKCtrl.IKBoneType.Foot_L)) { this.NoPullBodyIK.solver.goal = AvatarIKGoal.LeftFoot; } else if (this.TargetBone == this.MyIKCtrl.GetIKBone(FullBodyIKCtrl.IKBoneType.Foot_R)) { this.NoPullBodyIK.solver.goal = AvatarIKGoal.RightFoot; } this.ToCorrectBone = this.TargetBone; } public ShoulderThighIKData ShoulderThighData { get { return this.m_ShoulderThighData; } } public ElbowKneeIKData ElbowKneeData { get { return this.m_ElbowKneeData; } } private void CheckBorder(HandFootIKData.BorderCorrectData correctData) { if (!correctData.Enable) { return; } float d = 0f; Vector3 position = this.ToCorrectBone.position; if (correctData.CheckBorder(position, ref d)) { if (!base.GetIKSettingData(IKCtrlData.IKAttachType.NewPoint).IsIKExec) { base.GetIKSettingData(IKCtrlData.IKAttachType.NewPoint).IsIKExec = true; } switch (this.CorrectType) { case HandFootIKData.BorderCorrectType.Bone: base.IKTarget.position += correctData.Axis * d; this.m_ElbowKneeData.IKTarget.position += correctData.Axis * d; break; case HandFootIKData.BorderCorrectType.HalfBody: base.IKTarget.position += correctData.Axis * d; this.m_ElbowKneeData.IKTarget.position += correctData.Axis * d; this.m_ShoulderThighData.IKTarget.position += correctData.Axis * d; break; case HandFootIKData.BorderCorrectType.Chara: this.MyIKCtrl.BodyCtrlData.SetPosOffset(correctData.Axis * d); break; } } } public override void TagetTransCpy() { base.TagetTransCpy(); this.Effector.positionWeight = 0f; this.Effector.rotationWeight = 0f; this.NoPullBodyIK.solver.IKPositionWeight = 0f; this.NoPullBodyIK.solver.IKRotationWeight = 0f; this.NoPullBodyIK.solver.bendModifierWeight = 0f; } protected override void SetTargetTransform(IKCtrlData.IKSettingData data, Vector3 pos, Quaternion rot) { base.SetTargetTransform(data, pos, rot); if (!data.IsPointAttach) { return; } Transform iktarget = this.m_ShoulderThighData.IKTarget; Transform iktarget2 = this.m_ElbowKneeData.IKTarget; if (!this.ElbowKneeData.GetIKExecTruth(IKCtrlData.IKAttachType.NewPoint)) { Vector3 position = this.TargetBone.InverseTransformPoint(this.m_ElbowKneeData.TargetBone.position); Vector3 vector = base.IKTarget.TransformPoint(position); Vector3 vector2 = base.IKTarget.position - vector; Vector3 vector3 = vector - iktarget.position; float f = Mathf.Clamp(Vector3.Dot(vector2.normalized, vector3.normalized), -1f, 1f); float num = Mathf.Abs(Mathf.Acos(f) * 57.29578f); float t = Mathf.Clamp01(num / this.m_BendFadeBorder); Vector3 vector4 = base.IKTarget.position - iktarget.position; float num2 = Vector3.Dot(vector - iktarget.position, vector4.normalized); if (float.IsNaN(num2)) { num2 = 0f; } Vector3 vector5 = iktarget.position + vector4.normalized * num2; Vector3 a = iktarget2.rotation * Vector3.up * 0.01f; Vector3 b = (vector - vector5) * this.m_BendStlength; Vector3 b2 = Vector3.Slerp(a, b, t); iktarget2.position = vector5 + b2; this.SetElbowKneePositionWeight(base.PositionWeight); } this.ElbowKneeData.RotationWeight = base.PositionWeight; iktarget2.rotation = Quaternion.FromToRotation(this.TargetBone.position - this.ElbowKneeData.TargetBone.position, base.IKTarget.position - iktarget2.position) * iktarget2.rotation; } private void SetElbowKneePositionWeight(float val) { if (this.m_IsPullBody) { this.ElbowKneeData.PositionWeight = val; } else { this.NoPullBodyIK.solver.bendModifierWeight = val; } } public override void ApplyIKSetting() { if (!base.GetIKSettingData(IKCtrlData.IKAttachType.NewPoint).IsIKExec && !base.GetFlagData(IKCtrlData.IKAttachType.NewPoint).IsEnable && (this.FloorCorrect.Enable || this.WallCorrect.Enable)) { base.ForceIK = true; } base.ApplyIKSetting(); if (!base.IsIKExecTruth) { if (this.ElbowKneeData.RotationWeight > 0f) { base.PositionWeight = this.ElbowKneeData.RotationWeight; base.RotationWeight = this.ElbowKneeData.RotationWeight; base.IKTarget.position = this.ElbowKneeData.IKTarget.TransformPoint(this.TargetBone.localPosition); } else { base.PositionWeight = this.ElbowKneeData.PositionWeight; base.IKTarget.position += this.ElbowKneeData.IKTarget.position - this.ElbowKneeData.TargetBone.position; } } this.CheckBorder(this.WallCorrect); this.CheckBorder(this.FloorCorrect); } public override void Detach(IKCtrlData.IKAttachType attachType) { base.Detach(attachType); this.WallCorrect.Reset(); this.FloorCorrect.Reset(); this.ToCorrectBone = this.TargetBone; this.CorrectType = HandFootIKData.BorderCorrectType.Bone; } public void SetChainData(ElbowKneeIKData elbowknee_data, ShoulderThighIKData shoulderthigh_data) { this.m_ElbowKneeData = elbowknee_data; this.m_ShoulderThighData = shoulderthigh_data; this.NoPullBodyIK.solver.bendGoal = elbowknee_data.IKTarget; } protected override void OnPostSetPositionWeight(float val) { if (this.m_IsPullBody) { this.Effector.positionWeight = val; } else { this.NoPullBodyIK.solver.IKPositionWeight = val; } } protected override void OnPostSetRotationWeight(float val) { if (this.m_IsPullBody) { this.Effector.rotationWeight = val; } else { this.NoPullBodyIK.solver.IKRotationWeight = val; } } public override void Update() { if (this.m_IsPullBody) { return; } this.NoPullBodyIK.solver.Update(); } [Header("壁・床補正情報")] public HandFootIKData.BorderCorrectData WallCorrect = new HandFootIKData.BorderCorrectData(Vector3.forward); public HandFootIKData.BorderCorrectData FloorCorrect = new HandFootIKData.BorderCorrectData(Vector3.up); public HandFootIKData.BorderCorrectType CorrectType; public Transform ToCorrectBone; [SerializeField] [Space] [Range(1f, 90f)] private float m_BendFadeBorder = 30f; [SerializeField] [Range(1f, 2f)] private float m_BendStlength = 1.01f; public readonly IKEffector Effector; private ShoulderThighIKData m_ShoulderThighData; private ElbowKneeIKData m_ElbowKneeData; private LimbIK NoPullBodyIK; public enum BorderCorrectType { Bone, HalfBody, Chara, All } [Serializable] public class BorderCorrectData { public BorderCorrectData(Vector3 axis) { this.Axis = axis; } public void Reset() { this.Border = 0f; this.Enable = false; } public float GetValue(Vector3 pos) { pos = KasaiUtility.Vec3Multiply(pos, this.Axis); return pos.magnitude * Vector3.Dot(this.Axis, pos.normalized); } public bool CheckBorder(Vector3 check_pos, ref float diff) { float value = this.GetValue(check_pos); diff = this.Border - value; return value < this.Border; } public float Border; public bool Enable; public Vector3 Axis; } }