using System; using UnityEngine; public abstract class IKCtrlData { public IKCtrlData(FullBodyIKCtrl ik_ctrl, Transform tgt_bone, bool use_old = false, bool attach_ik = false) { this.MyIKCtrl = ik_ctrl; this.UseOldIK = use_old; this.m_TargetBone = tgt_bone; this.m_AttachPointIK = attach_ik; string text = (!this.MyIKCtrl.TgtMaid.boMAN) ? "Bip01" : "ManBip"; string name = this.m_TargetBone.name; Transform transform = this.MyIKCtrl.IKTgtRoot.Find(name); if (!transform) { transform = new GameObject(name).transform; transform.transform.SetParent(this.MyIKCtrl.IKTgtRoot, false); GameObject gameObject = new GameObject("IKTarget"); gameObject.transform.SetParent(transform.transform, false); this.m_IKTarget = gameObject.transform; } else { this.m_IKTarget = transform.Find("IKTarget"); } this.m_BoneTgtPair = new IKCtrlData.BoneTgtPair(this.TargetBone, this.m_IKTarget); this.IkCmoInit(); } public bool ForceIK { get { return this.m_ForceIK; } set { this.m_ForceIK = (this.m_ForceIKEnable && value); } } public IKCtrlData.PosRotPair BlendPosRot { get { return this.m_BlendPosRot; } } public IKCtrlData.IKParam PointIK { get { return (!this.m_PointFlagData.IsFlagOn) ? this.m_PointIK : this.m_NextPointIK; } } public IKCtrlData.IKParam RotateIK { get { return (!this.m_RotateFlagData.IsFlagOn) ? this.m_RotateIK : this.m_NextRotateIK; } } public TBody.IKCMO IKCmo { get { return this.m_IKCmo; } } public IKCtrlData.Vec3Enable PosEnable { get { return this.m_PosEnable; } } public IKCtrlData.Vec3Enable RotEnable { get { return this.m_RotEnable; } } public bool IsIKExec { get { return this.PointIK.IsIKExec || this.RotateIK.IsIKExec || this.ForceIK; } } public bool OldIkExec { get { return this.PointIK.IsIKExec && this.PointIK.IsOldIK; } } public bool AttachPointIK { get { return this.m_AttachPointIK; } } public Transform IKTarget { get { return this.m_IKTarget; } } public IKCtrlData.Vec3Enable OffsetEnable { get { return this.m_OffsetEnable; } } public IKCtrlData.ChangeFlagData PointFlagData { get { return this.m_PointFlagData; } } public IKCtrlData.ChangeFlagData RotateFlagData { get { return this.m_RotateFlagData; } } public virtual Transform TargetBone { get { return this.m_TargetBone; } } public abstract Transform[] ChainBones { get; } public abstract float PositionWeight { get; set; } public abstract float RotationWeight { get; set; } public static bool operator true(IKCtrlData data) { return data != null; } public static bool operator false(IKCtrlData data) { return data == null; } public static bool operator !(IKCtrlData data) { return data == null; } private void IkCmoInit() { if (!this.UseOldIK) { return; } this.IKCmo.Init(this.TargetBone.parent.parent, this.TargetBone.parent, this.TargetBone, this.MyIKCtrl.TgtBody); } private void IkCmoPorc(Vector3 tgt, Vector3 vechand_offset) { if (!this.UseOldIK) { return; } for (int i = 0; i < 3; i++) { this.IKCmo.Porc(this.TargetBone.parent.parent, this.TargetBone.parent, this.TargetBone, tgt, vechand_offset, this); } } private void SetIKPosRot(IKCtrlData.IKParam data, ref Vector3 pos, ref Quaternion rot, bool include_offset = false) { if (data.Target != null) { pos = data.Target.position; rot = data.Target.rotation; } else if (data.Tgt_AttachName != string.Empty) { if (this.MyIKCtrl.TgtBody.goSlot[data.Tgt_AttachSlot].morph != null) { if (data.TgtMaid != null && data.TgtMaid.body0 != null) { Vector3 vector; data.TgtMaid.body0.goSlot[data.Tgt_AttachSlot].morph.GetAttachPoint(data.Tgt_AttachName, out pos, out rot, out vector, false); if (data.MyType == IKCtrlData.IKAttachType.NewPoint && data.AxisTgt) { rot = data.AxisTgt.rotation; } } else { data.IsIKExec = false; data.Tgt_AttachName = string.Empty; } } } else if (this.ForceIK) { pos = this.m_IKTarget.position; rot = this.m_IKTarget.rotation; } else if (data.BlendWeight != 1f && data.BlendType == IKCtrlData.IKBlendType.IK_To_Detach) { pos = this.BlendPosRot.pos; rot = this.BlendPosRot.rot; } else { data.IsIKExec = false; } if (data.IsIKExec) { pos = this.GetIKEnable(data.MyType).GetEnable(this.TargetBone.position, pos, false); if (include_offset && !data.DoSetOffset) { data.DoSetOffset = true; if (data.IsPointAttach) { Vector3 start = pos; if (this.OffsetWorld) { pos += data.TgtOffset; } else if (this.OffsetBone) { pos -= this.TargetBone.rotation * data.TgtOffset; } else { pos += rot * data.TgtOffset; } Debug.DrawLine(start, pos, Color.white); } else { rot *= Quaternion.Euler(this.GetIKEnable(data.MyType).GetEnable(data.TgtOffset, false)); } } } } private void ApplyIKSetting(IKCtrlData.IKParam data) { if (this.MyIKCtrl.IsUpdateLate) { return; } if (data.TgtMaid && data.TgtMaid != this.MyIKCtrl.TgtMaid) { IKCtrlData ikdata = data.TgtMaid.IKCtrl.GetIKData(data.Tgt_AttachName, false); if (ikdata != null && ikdata.IsIKExec) { IKCtrlData.IKParam ikparam = ikdata.GetIKParam(data.MyType, false, false); this.m_EachOtherIK = (ikparam.IsIKExec && ikparam.Target == this.TargetBone); } if (!data.TgtMaid.body0.LateUpdateEnd && !this.MyIKCtrl.TgtBody.LateUpdateEnd) { this.MyIKCtrl.IsUpdateLate = true; if (data.TgtMaid.IKCtrl.IsIKExec) { FullBodyIKCtrl ikctrl = data.TgtMaid.IKCtrl; ikctrl.PostSolverUpdate = (Action)Delegate.Combine(ikctrl.PostSolverUpdate, new Action(this.MyIKCtrl.LateIKUpdate)); } else { TBody body = data.TgtMaid.body0; body.OnLateUpdateEnd = (Action)Delegate.Combine(body.OnLateUpdateEnd, new Action(this.MyIKCtrl.LateIKUpdate)); } return; } } data.DoSetOffset = false; data.IsIKExec = true; Vector3 vector = this.TargetBone.position; Quaternion quaternion = this.TargetBone.rotation; if (this.GetFlagData(data.MyType).IsEnable) { if (!this.GetFlagData(data.MyType).BlendCtrlSelf) { IKCtrlData.IKParam ikparam2 = this.GetIKParam(data.MyType, true, false); ikparam2.DoSetOffset = false; Vector3 a = vector; Quaternion a2 = quaternion; this.SetIKPosRot(ikparam2, ref a, ref a2, true); IKCtrlData.IKParam ikparam3 = this.GetIKParam(data.MyType, true, true); ikparam3.DoSetOffset = false; Vector3 b = vector; Quaternion b2 = quaternion; this.SetIKPosRot(ikparam3, ref b, ref b2, true); float num = this.GetFlagData(data.MyType).Value01(); data.IsIKExec = (num != 0f); if (data.IsPointAttach) { vector = Vector3.Lerp(a, b, num); } else { quaternion = Quaternion.Lerp(a2, b2, num); } } else if (this.GetFlagData(data.MyType).IsFlagChange()) { bool isFlagOn = this.GetFlagData(data.MyType).IsFlagOn; IKCtrlData.IKParam ikparam4 = this.GetIKParam(data.MyType, true, !isFlagOn); IKCtrlData.IKParam ikparam5 = this.GetIKParam(data.MyType, true, isFlagOn); ikparam4.BlendRecet(true); ikparam5.BlendRecet(true); ikparam5.SetLastTarget(ikparam4.Tgt_AttachName, ikparam4.TgtMaid, ikparam4.Target); ikparam5.CheckBlendType(false); if (ikparam5.MyType == IKCtrlData.IKAttachType.Rotate) { this.BlendPosRot.rot = this.m_lastIKPosRot.rot; } else { this.BlendPosRot.pos = this.m_lastIKPosRot.pos; } if (ikparam5.BlendType == IKCtrlData.IKBlendType.IK_To_Detach && ikparam5.BlendTime <= 0f) { ikparam5.BlendTime = ikparam4.BlendTime; } this.SetIKPosRot(data, ref vector, ref quaternion, false); } else { this.SetIKPosRot(data, ref vector, ref quaternion, false); } } else { this.SetIKPosRot(data, ref vector, ref quaternion, false); } if (data.IsIKExec) { if (this.m_EachOtherIK && !data.TgtMaid.IKCtrl.IsUpdateEnd) { if (data.IsPointAttach) { vector = Vector3.Lerp(this.TargetBone.position, vector, 0.5f); } else { quaternion = Quaternion.Lerp(this.TargetBone.rotation, quaternion, 0.5f); } } if (data.FirstFrame && !data.BlendNow) { if (data.IsPointAttach) { this.m_FirstTgtPosRot.pos = vector; } else { this.m_FirstTgtPosRot.rot = quaternion; } } if (data.DoAnimation && !data.BlendNow) { if (!data.DoSetPosRot) { Transform targetBone = this.TargetBone; if (data.IsPointAttach) { if (!data.FirstFrame) { this.m_PosRotOffset.pos = targetBone.position - vector - this.m_FirstPosRotOffset.pos; } else { this.m_FirstPosRotOffset.pos = targetBone.position - vector; } } else if (!data.FirstFrame) { this.m_PosRotOffset.rot = targetBone.rotation * Quaternion.Inverse(quaternion) * Quaternion.Inverse(this.m_FirstPosRotOffset.rot); } else { this.m_FirstPosRotOffset.rot = targetBone.rotation * Quaternion.Inverse(quaternion); } } } else { this.m_PosRotOffset.Recet(); } this.SetTargetTransform(data, vector, quaternion); if (!data.BlendNow) { data.FirstFrame = false; } if (data.IsTgtAxis) { KasaiUtility.DrawAxis(vector, quaternion, 0.125f); } if (data.BlendNow && !data.DoSetPosRot) { data.ElapsedTime += Time.deltaTime; } data.DoSetPosRot = true; } } protected bool IsEachBoneIK(IKCtrlData.IKParam param) { return param.IsIKExec && param.Target == this.TargetBone; } protected virtual void SetTargetTransform(IKCtrlData.IKParam data, Vector3 pos, Quaternion rot) { switch (data.MyType) { case IKCtrlData.IKAttachType.Point: pos += this.m_PosRotOffset.pos; Debug.DrawLine(pos, pos + rot * Vector3.forward * 0.2f, Color.cyan); if (!data.DoSetOffset) { this.IkCmoPorc(pos, data.TgtOffset); } else { this.IkCmoPorc(pos, Vector3.zero); } break; case IKCtrlData.IKAttachType.Rotate: rot *= this.m_PosRotOffset.rot; if (!data.DoSetOffset) { rot *= Quaternion.Euler(this.GetIKEnable(data.MyType).GetEnable(data.TgtOffset, false)); } this.m_IKTarget.rotation = rot; if (data.BlendType == IKCtrlData.IKBlendType.IK_To_IK) { this.m_IKTarget.rotation = Quaternion.Lerp(this.BlendPosRot.rot, this.m_IKTarget.rotation, data.BlendWeight); this.RotationWeight = this.m_IKWeight; } else if (data.BlendType == IKCtrlData.IKBlendType.IK_To_Detach) { this.RotationWeight = this.m_IKWeight * (1f - data.BlendWeight); } else { this.RotationWeight = this.m_IKWeight * data.BlendWeight; } break; case IKCtrlData.IKAttachType.NewPoint: pos += this.m_PosRotOffset.pos; if (!data.DoSetOffset) { Vector3 start = pos; if (this.OffsetWorld) { pos += data.TgtOffset; } else if (this.OffsetBone) { pos -= this.TargetBone.rotation * data.TgtOffset; } else { pos += rot * data.TgtOffset; } Debug.DrawLine(start, pos, Color.white); } this.m_IKTarget.position = pos; if (data.BlendType == IKCtrlData.IKBlendType.IK_To_IK) { this.m_IKTarget.position = Vector3.Lerp(this.BlendPosRot.pos, this.m_IKTarget.position, data.BlendWeight); this.PositionWeight = this.m_IKWeight; } else if (data.BlendType == IKCtrlData.IKBlendType.IK_To_Detach) { this.PositionWeight = this.m_IKWeight * (1f - data.BlendWeight); } else { this.PositionWeight = this.m_IKWeight * data.BlendWeight; } break; } data.DoSetOffset = true; } public IKCtrlData.IKParam GetIKParam(IKCtrlData.IKAttachType attach_type, bool ignore_flag = false, bool is_next = false) { if (ignore_flag) { if (attach_type == IKCtrlData.IKAttachType.Rotate) { return (!is_next) ? this.m_RotateIK : this.m_NextRotateIK; } return (!is_next) ? this.m_PointIK : this.m_NextPointIK; } else { if (attach_type == IKCtrlData.IKAttachType.Rotate) { return this.RotateIK; } return this.PointIK; } } public IKCtrlData.IKParam GetNextIKParam(IKCtrlData.IKAttachType attach_type) { return this.GetIKParam(attach_type, true, true); } public IKCtrlData.ChangeFlagData GetFlagData(IKCtrlData.IKAttachType attach_type) { if (attach_type == IKCtrlData.IKAttachType.Rotate) { return this.m_RotateFlagData; } return this.m_PointFlagData; } public IKCtrlData.Vec3Enable GetIKEnable(IKCtrlData.IKAttachType attach_type) { if (attach_type == IKCtrlData.IKAttachType.Rotate) { return this.RotEnable; } return this.PosEnable; } public void SetFlagTarget(IKCtrlData.IKAttachType attach_type, string name) { if (this.MyIKCtrl.TgtMaid.boMAN) { this.GetFlagData(attach_type).Target = this.MyIKCtrl.TgtBody.GetBone(name); } else { this.GetFlagData(attach_type).Target = this.MyIKCtrl.GetSTFlagObj(name); } } public void SetIKSetting(IKCtrlData.IKAttachType attachType, bool is_another, Maid tgt_maid, int slot_no, string attach_name, Transform axis_bone, Vector3 f_vecOffset, bool do_animation = false, float blend_time = 0f) { this.SetIKSetting(attachType, is_another, tgt_maid, slot_no, attach_name, axis_bone, null, f_vecOffset, do_animation, blend_time); } public void SetIKSetting(IKCtrlData.IKAttachType attachType, bool is_another, Maid tgt_maid, Transform target, Vector3 f_vecOffset, bool do_animation = false, float blend_time = 0f) { this.SetIKSetting(attachType, is_another, tgt_maid, -1, string.Empty, null, target, f_vecOffset, do_animation, blend_time); } public void SetIKSetting(IKCtrlData.IKAttachType attachType, bool is_another, Transform target, Vector3 f_vecOffset, bool do_animation = false, float blend_time = 0f) { this.SetIKSetting(attachType, is_another, null, -1, string.Empty, null, target, f_vecOffset, do_animation, blend_time); } public void SetIKSetting(IKCtrlData.IKAttachType attachType, bool is_another, Maid tgt_maid, string bone_name, Transform target, Vector3 f_vecOffset, bool do_animation = false, float blend_time = 0f) { this.SetIKSetting(attachType, is_another, tgt_maid, -1, bone_name, null, target, f_vecOffset, do_animation, blend_time); } public virtual void Update() { } public virtual void ApplyIKSetting() { if (this.ForceIK) { this.PointIK.ChangePointType(IKCtrlData.IKAttachType.NewPoint); } if (!this.MyIKCtrl.IsUpdateEnd) { float num = 0f; this.RotationWeight = num; this.PositionWeight = num; this.m_BoneTgtPair.Cppy(); this.m_EachOtherIK = false; this.ForceIK |= this.MyIKCtrl.AllForceIK; } this.ApplyIKSetting(this.PointIK); this.ApplyIKSetting(this.RotateIK); } public virtual 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, float blend_time = 0f) { this.GetIKParam(attachType, true, is_next).ChangePointType(attachType); if (this.GetIKParam(attachType, true, is_next).MyType != attachType) { return; } this.MyIKCtrl.IKActive = true; this.BlendPosRot.Copy(this.m_lastIKPosRot); this.m_PosRotOffset.Recet(); this.m_FirstPosRotOffset.Recet(); this.m_FirstTgtPosRot.Recet(); this.GetIKParam(attachType, true, is_next).SetIKSetting(tgt_maid, slot_no, attach_name, axis_bone, target, f_vecOffset, do_animation, blend_time); this.GetFlagData(attachType).IsFlagChange(); } public virtual void Detach(IKCtrlData.IKAttachType attachType, float blend_time = 0f) { this.OffsetBone = false; this.OffsetWorld = false; this.ForceIK = false; this.m_BoneTgtPair.PosOffset = Vector3.zero; this.BlendPosRot.Copy(this.m_lastIKPosRot); this.GetFlagData(attachType).Reset(); this.GetIKParam(attachType, true, false).Detach(blend_time); this.GetIKParam(attachType, true, true).Detach(blend_time); } public virtual void LateUpdate() { if (this.IsIKExec && this.m_DrawLine && !this.MyIKCtrl.IsUpdateLate) { KasaiUtility.DrawObjAxis(this.TargetBone, 0.0625f); if (!this.OldIkExec) { Color color = (!this.PointIK.IsIKExec) ? Color.cyan : Color.yellow; for (int i = 0; i < this.ChainBones.Length - 1; i++) { Debug.DrawLine(this.ChainBones[i].position, this.ChainBones[i + 1].position, color); } } } this.m_lastIKPosRot.Copy(this.m_TargetBone); this.PointIK.DoSetPosRot = (this.RotateIK.DoSetPosRot = false); } public virtual void SetTargetOffset(Vector3 offset, bool inverse = false) { if (this.IsIKExec) { return; } this.m_BoneTgtPair.PosOffset = this.m_OffsetEnable.GetEnable(offset, inverse); } [SerializeField] [Header("位置IK")] private IKCtrlData.IKParam m_PointIK = new IKCtrlData.IKParam(IKCtrlData.IKAttachType.NewPoint, false); [SerializeField] private IKCtrlData.IKParam m_NextPointIK = new IKCtrlData.IKParam(IKCtrlData.IKAttachType.NewPoint, true); [SerializeField] private IKCtrlData.Vec3Enable m_PosEnable = new IKCtrlData.Vec3Enable(); [SerializeField] [Header("回転IK")] private IKCtrlData.IKParam m_RotateIK = new IKCtrlData.IKParam(IKCtrlData.IKAttachType.Rotate, false); [SerializeField] private IKCtrlData.IKParam m_NextRotateIK = new IKCtrlData.IKParam(IKCtrlData.IKAttachType.Rotate, true); [SerializeField] private IKCtrlData.Vec3Enable m_RotEnable = new IKCtrlData.Vec3Enable(); private TBody.IKCMO m_IKCmo = new TBody.IKCMO(); private IKCtrlData.PosRotPair m_BlendPosRot = new IKCtrlData.PosRotPair(); [SerializeField] [Space] private IKCtrlData.PosRotPair m_PosRotOffset = new IKCtrlData.PosRotPair(); private IKCtrlData.PosRotPair m_FirstPosRotOffset = new IKCtrlData.PosRotPair(); [SerializeField] private bool m_AttachPointIK; [SerializeField] private Transform m_TargetBone; [SerializeField] private Transform m_IKTarget; [SerializeField] private bool m_DrawLine = true; private IKCtrlData.BoneTgtPair m_BoneTgtPair; protected IKCtrlData.PosRotPair m_FirstTgtPosRot = new IKCtrlData.PosRotPair(); protected IKCtrlData.PosRotPair m_lastIKPosRot = new IKCtrlData.PosRotPair(); [SerializeField] [Range(0f, 1f)] protected float m_IKWeight = 1f; [SerializeField] protected bool m_ForceIK; protected bool m_ForceIKEnable; protected bool m_EachOtherIK; protected IKCtrlData.Vec3Enable m_OffsetEnable = new IKCtrlData.Vec3Enable(); [SerializeField] [Header("フラグ情報")] protected IKCtrlData.ChangeFlagData m_PointFlagData = new IKCtrlData.ChangeFlagData(); [SerializeField] protected IKCtrlData.ChangeFlagData m_RotateFlagData = new IKCtrlData.ChangeFlagData(); [Space] public bool OffsetWorld; public bool OffsetBone; public readonly FullBodyIKCtrl MyIKCtrl; public readonly bool UseOldIK; public enum IKAttachType { Point, Rotate, NewPoint } public enum IKBlendType { Detach_To_IK, IK_To_IK, IK_To_Detach, Not_Blend } [Serializable] public class Vec3Enable { public bool AnyDisable { get { return !this.EnableX || !this.EnableY || !this.EnableZ; } } public Vector3 GetEnable(Vector3 pos, bool inverse = false) { if (this.EnableX == inverse) { pos.x = 0f; } if (this.EnableY == inverse) { pos.y = 0f; } if (this.EnableZ == inverse) { pos.z = 0f; } return pos; } public Vector3 GetEnable(Vector3 from, Vector3 to, bool inverse = false) { if (this.EnableX == inverse) { to.x = from.x; } if (this.EnableY == inverse) { to.y = from.y; } if (this.EnableZ == inverse) { to.z = from.z; } return to; } public void Recet() { this.EnableX = (this.EnableY = (this.EnableZ = true)); } public void Copy(IKCtrlData.Vec3Enable cpy) { this.EnableX = cpy.EnableX; this.EnableY = cpy.EnableY; this.EnableZ = cpy.EnableZ; } public bool EnableX = true; public bool EnableY = true; public bool EnableZ = true; } [Serializable] public class PosRotPair { public void Recet() { this.pos = Vector3.zero; this.rot = new Quaternion(0f, 0f, 0f, 1f); } public void Copy(IKCtrlData.PosRotPair pair) { this.pos = pair.pos; this.rot = pair.rot; } public void Copy(Transform transform) { this.pos = transform.position; this.rot = transform.rotation; } public void DrawAxis() { KasaiUtility.DrawAxis(this.pos, this.rot, 0.0625f); } public Vector3 pos = Vector3.zero; public Quaternion rot = new Quaternion(0f, 0f, 0f, 1f); } public class BoneTgtPair { public BoneTgtPair(Transform bone, Transform target) { this.Bone = bone; this.Target = target; } public void Cppy() { this.Target.position = this.Bone.position + this.PosOffset; this.Target.rotation = this.Bone.rotation; } public readonly Transform Bone; public readonly Transform Target; public Vector3 PosOffset = Vector3.zero; } [Serializable] public class ChangeFlagData { public bool IsEnable { get { return this.Target != null; } } public bool IsFlagOn { get { return this.IsEnable && this.Value() >= this.OnValue; } } public float Value() { if (!this.Target) { return 0f; } Vector3 vector = KasaiUtility.Vec3Multiply(this.Target.localPosition, this.Axis); return vector.magnitude * Vector3.Dot(this.Axis, vector.normalized); } public float Value01() { return Mathf.Clamp01(this.Value() / this.OnValue); } public bool IsFlagChange() { if (!this.Target) { return false; } bool cunnretFlag = this.m_CunnretFlag; this.m_CunnretFlag = this.IsFlagOn; return cunnretFlag != this.m_CunnretFlag; } public void Reset() { this.Target = null; this.m_CunnretFlag = false; this.BlendCtrlSelf = false; } private bool m_CunnretFlag; public Transform Target; public Vector3 Axis = Vector3.forward; public float OnValue = 0.1f; [HideInInspector] public bool BlendCtrlSelf; } [Serializable] public class IKParam { public IKParam(IKCtrlData.IKAttachType type, bool is_next = false) { this.MyType = type; this.IsNext = is_next; this.BlendType = IKCtrlData.IKBlendType.Not_Blend; } public IKCtrlData.IKAttachType MyType { get; private set; } public IKCtrlData.IKBlendType BlendType { get; private set; } public bool DoIKBlend { get; private set; } public bool IsPointAttach { get { return this.MyType != IKCtrlData.IKAttachType.Rotate; } } public bool NeedBlend { get { return this.BlendTime > 0f; } } public float BlendWeight { get { return (!this.NeedBlend || !this.DoIKBlend) ? 1f : Mathf.Clamp01(this.ElapsedTime / this.BlendTime); } } public bool BlendNow { get { return this.NeedBlend && this.ElapsedTime <= this.BlendTime; } } public bool IsOldIK { get { return this.MyType == IKCtrlData.IKAttachType.Point; } } public bool ExistTgt { get { return this.Target != null || !string.IsNullOrEmpty(this.Tgt_AttachName); } } public void ChangePointType(IKCtrlData.IKAttachType type) { if (this.MyType == IKCtrlData.IKAttachType.Rotate) { return; } this.MyType = type; } public bool IsEachOtherIK(bool check_update = false) { return this.TgtMaid && this.TgtMaid.IKCtrl.IsIKExec && this.TgtMaid.IKCtrl.IsUpdateEnd == check_update; } public void CheckBlendType(bool check_time = true) { this.BlendType = IKCtrlData.IKBlendType.IK_To_IK; this.DoIKBlend = true; if (this.m_lastTarget) { if (!this.Target && string.IsNullOrEmpty(this.Tgt_AttachName)) { this.BlendType = IKCtrlData.IKBlendType.IK_To_Detach; } else if (this.Target) { this.DoIKBlend = (this.m_lastTarget != this.Target); } } else if (!string.IsNullOrEmpty(this.m_lastAttachName)) { if (string.IsNullOrEmpty(this.Tgt_AttachName) && !this.Target) { this.BlendType = IKCtrlData.IKBlendType.IK_To_Detach; } else if (!this.Target) { this.DoIKBlend = (this.m_lastAttachName != this.Tgt_AttachName || this.m_lastTgtMaid != this.TgtMaid); } } else { this.BlendType = IKCtrlData.IKBlendType.Detach_To_IK; if (!this.Target && string.IsNullOrEmpty(this.Tgt_AttachName)) { this.BlendType = IKCtrlData.IKBlendType.Not_Blend; this.DoIKBlend = false; } } if (check_time) { this.DoIKBlend &= (this.BlendTime > 0f); } } public void SetLastTarget(string attach_name, Maid maid, Transform target) { this.m_lastAttachName = attach_name; this.m_lastTgtMaid = maid; this.m_lastTarget = target; } public void BlendRecet(bool elpsed_only = false) { this.ElapsedTime = 0f; if (!elpsed_only) { this.DoIKBlend = false; this.BlendTime = -1f; this.BlendType = IKCtrlData.IKBlendType.Not_Blend; } } public void SetIKSetting(Maid tgt_maid, int slot_no, string attach_name, Transform axis_bone, Transform target, Vector3 f_vecOffset, bool do_animation, float blend_time) { this.SetLastTarget(this.Tgt_AttachName, this.TgtMaid, this.Target); this.TgtMaid = tgt_maid; this.Tgt_AttachSlot = slot_no; this.Tgt_AttachName = attach_name; this.Target = target; this.AxisTgt = axis_bone; if (this.IsPointAttach) { this.TgtOffset = f_vecOffset; } else { this.TgtOffset = KasaiUtility.AngleRimmit360(f_vecOffset); } this.BlendRecet(false); this.BlendTime = blend_time; this.CheckBlendType(true); this.DoAnimation = do_animation; this.IsIKExec = true; this.FirstFrame = true; } public void Detach(float blend_time = 0f) { this.BlendRecet(false); this.BlendTime = blend_time; this.SetLastTarget(this.Tgt_AttachName, this.TgtMaid, this.Target); this.TgtMaid = null; this.Tgt_AttachSlot = -1; this.Tgt_AttachName = string.Empty; this.Target = null; this.AxisTgt = null; this.TgtOffset = Vector3.zero; this.CheckBlendType(true); this.DoSetOffset = false; this.DoSetPosRot = false; this.DoAnimation = false; this.IsIKExec = false; this.FirstFrame = false; } private string m_lastAttachName = string.Empty; private Transform m_lastTarget; private Maid m_lastTgtMaid; public Transform Target; public Vector3 TgtOffset; public int Tgt_AttachSlot = -1; public string Tgt_AttachName = string.Empty; public Maid TgtMaid; public bool IsTgtAxis; public bool IsIKExec; public Transform AxisTgt; public float BlendTime = -1f; public float ElapsedTime; [HideInInspector] public bool FirstFrame; public bool DoAnimation; [HideInInspector] public bool DoSetPosRot; [HideInInspector] public bool DoSetOffset; public readonly bool IsNext; } }