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 = base.TargetBone; } public Transform BendBone { get { return this.m_BoneBendGoal.Bone; } } 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; 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; 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; } } } public override void ApplyIKSetting() { this.m_BoneBendGoal.Cppy(); this.m_RootBoneTgtPair.Cppy(); base.ApplyIKSetting(); if (base.ForceIK) { this.CheckBorder(this.WallCorrect); this.CheckBorder(this.FloorCorrect); } } public override void Detach(IKCtrlData.IKAttachType attachType, float blend_time = 0f) { base.Detach(attachType, blend_time); this.Chain.bendConstraint.weight = 1f; 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 = base.TargetBone; this.CorrectType = BipedIKCtrlData.BorderCorrectType.Bone; } public override void SetTargetOffset(Vector3 offset, bool inverse = false) { if (base.IsIKExec) { return; } base.SetTargetOffset(offset, inverse); this.m_BoneBendGoal.PosOffset = this.m_OffsetEnable.GetEnablePos(offset, inverse); this.m_RootBoneTgtPair.PosOffset = this.m_OffsetEnable.GetEnablePos(offset, inverse); } private IKCtrlData.BoneTgtPair m_BoneBendGoal; private IKCtrlData.BoneTgtPair m_RootBoneTgtPair; [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; 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; } }