using System; using System.Linq; using RootMotion.FinalIK; using UnityEngine; [Serializable] public class BipedIKCtrlData : IKCtrlData { public BipedIKCtrlData(IKEffector effector, FBIKChain chain, IKMappingLimb ik_mapping, FullBodyIKCtrl ik_ctrl, Transform tgt_bone, IKEffector sub_effector, bool use_old = false) : base(ik_ctrl, tgt_bone, use_old, false) { this.Effector = effector; this.Effector.target = base.IKTarget; this.Chain = chain; this.IKMapping = ik_mapping; this.RootEffector = sub_effector; Transform transform = this.CreateSubTarget("BendBone"); this.m_BoneBendGoal = new IKCtrlData.BoneTgtPair(this.Chain.bendConstraint.bone2, transform); this.Chain.bendConstraint.bendGoal = transform; this.Chain.bendConstraint.weight = 1f; this.RootEffector.target = this.CreateSubTarget("ChainRootBone"); this.m_RootBoneTgtPair = new IKCtrlData.BoneTgtPair(this.RootEffector.bone, this.RootEffector.target); this.m_ForceIKEnable = true; this.ToCorrectBone = this.TargetBone; this.m_BendweitCtrl.Axis = Vector3.up; } public Transform BendBone { get { return this.m_BoneBendGoal.Bone; } } public Transform RootBone { get { return this.m_RootBoneTgtPair.Bone; } } public IKCtrlData.ChangeFlagData BendweightCtrl { get { return this.m_BendweitCtrl; } } public override Transform TargetBone { get { if (this.IsRootIK) { return this.RootBone; } if (this.IsBendIK) { return this.BendBone; } return base.TargetBone; } } public override Transform[] ChainBones { get { return (from node in this.Chain.nodes select node.transform).ToArray(); } } public override float PositionWeight { get { return this.Effector.positionWeight; } set { this.Effector.positionWeight = value; } } public override float RotationWeight { get { return this.Effector.rotationWeight; } set { this.Effector.rotationWeight = value; } } private Transform CreateSubTarget(string name) { Transform transform = base.IKTarget.parent.Find(name); if (!transform) { transform = new GameObject(name).transform; transform.SetParent(base.IKTarget.parent, false); } return transform; } private void CheckBorder(BipedIKCtrlData.BorderCorrectData correctData) { if (!correctData.Enable) { return; } float num = 0f; Vector3 check_pos = this.ToCorrectBone.position + this.MyIKCtrl.BodyCtrlData.BodyOffset; if (correctData.CheckBorder(check_pos, ref num)) { switch (this.CorrectType) { case BipedIKCtrlData.BorderCorrectType.Bone: base.IKTarget.position += correctData.Axis * num; this.m_BoneBendGoal.Target.position += correctData.Axis * num; if (this.PositionWeight == 0f) { this.PositionWeight = 1f; base.PointIK.IsIKExec = true; } break; case BipedIKCtrlData.BorderCorrectType.HalfBody: base.IKTarget.position += correctData.Axis * num; this.m_BoneBendGoal.Target.position += correctData.Axis * num; this.m_RootBoneTgtPair.Target.position += correctData.Axis * num; if (this.PositionWeight == 0f) { this.PositionWeight = 1f; base.PointIK.IsIKExec = true; } break; case BipedIKCtrlData.BorderCorrectType.Chara: if (correctData.GetValue(this.MyIKCtrl.BodyCtrlData.AddOffset) < num) { this.MyIKCtrl.BodyCtrlData.SetAddOffset(correctData.Axis * num); } break; case BipedIKCtrlData.BorderCorrectType.All: if (correctData.GetValue(this.MyIKCtrl.BodyCtrlData.AllOffset) < num) { this.MyIKCtrl.BodyCtrlData.SetAllOffset(correctData.Axis * num); } break; } } } protected override void SetTargetTransform(IKCtrlData.IKParam data, Vector3 pos, Quaternion rot) { base.SetTargetTransform(data, pos, rot); Transform target = this.m_BoneBendGoal.Target; Transform target2 = this.m_RootBoneTgtPair.Target; if (this.IsRootIK || this.IsBendIK) { Vector3 position = target2.InverseTransformPoint(target.position); Vector3 position2 = this.m_BoneBendGoal.Bone.InverseTransformPoint(base.TargetBone.position); if (this.IsRootIK) { if (data.IsPointAttach) { this.RootEffector.positionWeight = this.PositionWeight; target2.position = base.IKTarget.position; } else { this.RootEffector.rotationWeight = this.RotationWeight; target2.rotation = base.IKTarget.rotation; target.rotation = target2.rotation * this.m_BoneBendGoal.Bone.localRotation; base.IKTarget.rotation = target.rotation * base.TargetBone.localRotation; } target.position = target2.TransformPoint(position); base.IKTarget.position = target.TransformPoint(position2); } else { if (data.IsPointAttach) { this.Chain.bendConstraint.weight = this.PositionWeight; this.RootEffector.positionWeight = (this.RootEffector.rotationWeight = this.PositionWeight); target2.rotation = Quaternion.FromToRotation(target.position - target2.position, base.IKTarget.position - target2.position) * target2.rotation; Vector3 b = base.IKTarget.position - target2.TransformPoint(position); target2.position += b; target.position = base.IKTarget.position; } else { target.rotation = base.IKTarget.rotation; base.IKTarget.rotation = target.rotation * base.TargetBone.localRotation; } base.IKTarget.position = this.m_BoneBendGoal.Target.TransformPoint(position2); } } else if (data.IsPointAttach) { Vector3 vector = this.m_BoneBendGoal.Bone.position - this.TargetBone.position; Vector3 vector2 = this.m_RootBoneTgtPair.Bone.position - this.m_BoneBendGoal.Bone.position; float f = Vector3.Dot(vector.normalized, vector2.normalized); float num = Mathf.Acos(f) * 57.29578f; float num2 = Mathf.Clamp01(num / this.m_BendFadeBorder); this.Chain.bendConstraint.weight = num2 * this.PositionWeight; Vector3 position3 = this.TargetBone.InverseTransformPoint(this.m_RootBoneTgtPair.Bone.position); target2.position = base.IKTarget.TransformPoint(position3); Vector3 position4 = this.TargetBone.InverseTransformPoint(this.m_BoneBendGoal.Bone.position); Vector3 position5 = base.IKTarget.TransformPoint(position4); target.position = position5; } } public void SetBendweightCtrl(string name) { if (this.MyIKCtrl.TgtMaid.boMAN) { this.BendweightCtrl.Target = this.MyIKCtrl.TgtBody.GetBone(name); } else { this.BendweightCtrl.Target = this.MyIKCtrl.GetSTFlagObj(name); } } public override void ApplyIKSetting() { this.m_BoneBendGoal.Cppy(); this.m_RootBoneTgtPair.Cppy(); this.Chain.bendConstraint.weight = 0f; this.RootEffector.positionWeight = 0f; this.RootEffector.rotationWeight = 0f; if (!base.PointIK.IsIKExec && !base.PointFlagData.IsEnable && (this.FloorCorrect.Enable || this.WallCorrect.Enable)) { base.ForceIK = true; } base.ApplyIKSetting(); this.CheckBorder(this.WallCorrect); this.CheckBorder(this.FloorCorrect); if (!this.IsBendIK && !this.IsRootIK && this.m_BendweitCtrl.IsEnable) { this.Chain.bendConstraint.weight = 1f - this.m_BendweitCtrl.Value01(); } } public void SetPullState(bool pull_on) { if (this.m_OrijinPull < 0f) { this.m_OrijinPull = this.Chain.pull; } if (pull_on) { this.Chain.pull = this.m_OrijinPull; } else { this.Chain.pull = 0.1f; } } public override void SetIKSetting(IKCtrlData.IKAttachType attachType, bool is_next, Maid tgt_maid, int slot_no, string attach_name, Transform axis_bone, Transform target, Vector3 f_vecOffset, bool do_animation = false) { base.SetIKSetting(attachType, is_next, tgt_maid, slot_no, attach_name, axis_bone, target, f_vecOffset, do_animation); if (this.IsRootIK) { base.BlendPosRot.Copy(this.m_lastRootPosRot); } else if (this.IsBendIK) { base.BlendPosRot.Copy(this.m_lastBendPosRot); } } public override void Detach(IKCtrlData.IKAttachType attachType) { base.Detach(attachType); this.IsRootIK = (this.IsBendIK = false); this.RootEffector.positionWeight = 0f; this.RootEffector.rotationWeight = 0f; this.m_BoneBendGoal.PosOffset = Vector3.zero; this.m_RootBoneTgtPair.PosOffset = Vector3.zero; this.WallCorrect.Reset(); this.FloorCorrect.Reset(); this.ToCorrectBone = this.TargetBone; this.CorrectType = BipedIKCtrlData.BorderCorrectType.Bone; this.m_BendweitCtrl.Reset(); } public override void SetTargetOffset(Vector3 offset, bool inverse = false) { if (base.IsIKExec) { return; } base.SetTargetOffset(offset, inverse); this.m_BoneBendGoal.PosOffset = this.m_OffsetEnable.GetEnable(offset, inverse); this.m_RootBoneTgtPair.PosOffset = this.m_OffsetEnable.GetEnable(offset, inverse); } public override void LateUpdate() { base.LateUpdate(); this.m_lastBendPosRot.Copy(this.m_BoneBendGoal.Bone); this.m_lastRootPosRot.Copy(this.m_RootBoneTgtPair.Bone); } private const float PULL_MIN_VALUE = 0.1f; private IKCtrlData.BoneTgtPair m_BoneBendGoal; private IKCtrlData.PosRotPair m_lastBendPosRot = new IKCtrlData.PosRotPair(); private IKCtrlData.ChangeFlagData m_BendweitCtrl = new IKCtrlData.ChangeFlagData(); private IKCtrlData.BoneTgtPair m_RootBoneTgtPair; private IKCtrlData.PosRotPair m_lastRootPosRot = new IKCtrlData.PosRotPair(); private float m_OrijinPull = -1f; [Header("壁・床補正情報")] public BipedIKCtrlData.BorderCorrectData WallCorrect = new BipedIKCtrlData.BorderCorrectData(Vector3.forward); public BipedIKCtrlData.BorderCorrectData FloorCorrect = new BipedIKCtrlData.BorderCorrectData(Vector3.up); public BipedIKCtrlData.BorderCorrectType CorrectType; public Transform ToCorrectBone; [Header("肘・膝をターゲットに合わせるフラグ")] public bool IsBendIK; [Header("肩・太ももをターゲットに合わせるフラグ")] public bool IsRootIK; [SerializeField] [Space] [Range(1f, 90f)] private float m_BendFadeBorder = 30f; public readonly IKEffector Effector; public readonly FBIKChain Chain; public readonly IKMappingLimb IKMapping; public readonly IKEffector RootEffector; 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; } }