HandFootIKCtrl.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. using System;
  2. using System.Collections.Generic;
  3. using kt.Physics;
  4. using kt.Utility;
  5. using RootMotion.FinalIK;
  6. using UnityEngine;
  7. [Serializable]
  8. public class HandFootIKCtrl : ALimbIKCtrl
  9. {
  10. public HandFootIKCtrl(IKEffector effector, FBIKChain chain, IKMappingLimb ik_mapping, FullBodyIKMgr ik_ctrl, FullBodyIKMgr.IKEffectorType effector_type) : base(ik_ctrl, chain, ik_mapping, effector_type)
  11. {
  12. this.effector = effector;
  13. this.effector.target = base.constraintTarget;
  14. base.isUpperBody = (effector_type == FullBodyIKMgr.IKEffectorType.Hand_L || effector_type == FullBodyIKMgr.IKEffectorType.Hand_R);
  15. this.NoPullBodyIK = base.constraintTarget.parent.gameObject.AddComponent<LimbIK>();
  16. this.NoPullBodyIK.solver.SetChain(base.chainBones[0], base.chainBones[1], base.chainBones[2], base.chainBones[0]);
  17. this.NoPullBodyIK.solver.target = base.constraintTarget;
  18. this.NoPullBodyIK.solver.bendModifier = IKSolverLimb.BendModifier.Goal;
  19. this.NoPullBodyIK.solver.maintainRotationWeight = ik_mapping.maintainRotationWeight;
  20. this.NoPullBodyIK.enabled = false;
  21. switch (effector_type)
  22. {
  23. case FullBodyIKMgr.IKEffectorType.Hand_R:
  24. this.NoPullBodyIK.solver.goal = AvatarIKGoal.RightHand;
  25. break;
  26. default:
  27. switch (effector_type)
  28. {
  29. case FullBodyIKMgr.IKEffectorType.Foot_R:
  30. this.NoPullBodyIK.solver.goal = AvatarIKGoal.RightFoot;
  31. break;
  32. case FullBodyIKMgr.IKEffectorType.Foot_L:
  33. this.NoPullBodyIK.solver.goal = AvatarIKGoal.LeftFoot;
  34. break;
  35. }
  36. break;
  37. case FullBodyIKMgr.IKEffectorType.Hand_L:
  38. this.NoPullBodyIK.solver.goal = AvatarIKGoal.LeftHand;
  39. break;
  40. }
  41. if (!base.isUpperBody)
  42. {
  43. if (!this.myIKMgr.body.IsCrcBody && this.myIKMgr.chara.boMAN)
  44. {
  45. return;
  46. }
  47. string str = (this.effectorType != FullBodyIKMgr.IKEffectorType.Foot_L) ? "Bip01 R " : "Bip01 L ";
  48. Transform bone = this.myIKMgr.body.GetBone(str + "Toe0");
  49. Transform bone2 = this.myIKMgr.body.GetBone(str + "Toe1");
  50. Transform bone3 = this.myIKMgr.body.GetBone(str + "Toe2");
  51. this.ToeBoneLocalAngleDic = new Dictionary<Transform, Vector3>();
  52. this.ToeBoneLocalAngleDic[bone] = bone.localEulerAngles;
  53. this.ToeBoneLocalAngleDic[bone2] = bone2.localEulerAngles;
  54. this.ToeBoneLocalAngleDic[bone3] = bone3.localEulerAngles;
  55. if (this.isLeft)
  56. {
  57. base.limbCapsule = this.myIKMgr.body.limbColliderMgr.GetCollider(LimbColliderMgr.LimbType.Calf_L);
  58. }
  59. else
  60. {
  61. base.limbCapsule = this.myIKMgr.body.limbColliderMgr.GetCollider(LimbColliderMgr.LimbType.Calf_R);
  62. }
  63. }
  64. else if (this.isLeft)
  65. {
  66. base.limbCapsule = this.myIKMgr.body.limbColliderMgr.GetCollider(LimbColliderMgr.LimbType.Forearm_L);
  67. }
  68. else
  69. {
  70. base.limbCapsule = this.myIKMgr.body.limbColliderMgr.GetCollider(LimbColliderMgr.LimbType.Forearm_R);
  71. }
  72. }
  73. public override ALimbIKCtrl pairIK
  74. {
  75. get
  76. {
  77. FullBodyIKMgr.IKEffectorType effector_type;
  78. if (base.isUpperBody)
  79. {
  80. effector_type = ((!this.isLeft) ? FullBodyIKMgr.IKEffectorType.Hand_L : FullBodyIKMgr.IKEffectorType.Hand_R);
  81. }
  82. else
  83. {
  84. effector_type = ((!this.isLeft) ? FullBodyIKMgr.IKEffectorType.Foot_L : FullBodyIKMgr.IKEffectorType.Foot_R);
  85. }
  86. return this.myIKMgr.GetIKCtrl<ALimbIKCtrl>(effector_type);
  87. }
  88. }
  89. public override bool isLeft
  90. {
  91. get
  92. {
  93. return this.effectorType == FullBodyIKMgr.IKEffectorType.Hand_L || this.effectorType == FullBodyIKMgr.IKEffectorType.Foot_L;
  94. }
  95. }
  96. protected override bool IsUseOldIK
  97. {
  98. get
  99. {
  100. return this.effectorType == FullBodyIKMgr.IKEffectorType.Hand_L || this.effectorType == FullBodyIKMgr.IKEffectorType.Hand_R;
  101. }
  102. }
  103. public override bool isNeedFullbodySolverUpdate
  104. {
  105. get
  106. {
  107. return base.isNeedFullbodySolverUpdate && base.pointIKData.attachType != AIKCtrl.IKAttachType.Point;
  108. }
  109. }
  110. public ShoulderThighIKCtrl shoulderThighCtrl { get; private set; }
  111. public ElbowKneeIKCtrl elbowKneeCtrl { get; private set; }
  112. public void SetChain(ElbowKneeIKCtrl elbowknee_data, ShoulderThighIKCtrl shoulderthigh_data)
  113. {
  114. this.elbowKneeCtrl = elbowknee_data;
  115. this.ChainParentCtrl = elbowknee_data;
  116. this.shoulderThighCtrl = shoulderthigh_data;
  117. this.NoPullBodyIK.solver.bendGoal = elbowknee_data.constraintTarget;
  118. }
  119. public override void TargetTransCpy()
  120. {
  121. base.TargetTransCpy();
  122. this.effector.positionWeight = 0f;
  123. this.effector.rotationWeight = 0f;
  124. this.NoPullBodyIK.solver.IKPositionWeight = 0f;
  125. this.NoPullBodyIK.solver.IKRotationWeight = 0f;
  126. this.NoPullBodyIK.solver.bendModifierWeight = 0f;
  127. }
  128. protected override void SetTargetTransform(AIKCtrl.IKSettingData data, Vector3 pos, Quaternion rot)
  129. {
  130. base.SetTargetTransform(data, pos, rot);
  131. if (!data.isPointAttach || data.attachType == AIKCtrl.IKAttachType.Point)
  132. {
  133. return;
  134. }
  135. this.CalcElbowKneeTgtPosRot();
  136. }
  137. private void CalcElbowKneeTgtPosRot()
  138. {
  139. Transform constraintTarget = this.shoulderThighCtrl.constraintTarget;
  140. Transform constraintTarget2 = this.elbowKneeCtrl.constraintTarget;
  141. this.elbowKneeCtrl.rotationWeight = base.positionWeight;
  142. Vector3 fromDirection = base.bone.position - this.elbowKneeCtrl.bone.position;
  143. Vector3 toDirection = base.constraintTarget.position - constraintTarget2.position;
  144. constraintTarget2.rotation = Quaternion.FromToRotation(fromDirection, toDirection) * constraintTarget2.rotation;
  145. if (this.elbowKneeCtrl.pointIKData.isIKExecNotWeight0)
  146. {
  147. return;
  148. }
  149. Vector3 position = base.bone.InverseTransformPoint(this.elbowKneeCtrl.bone.position);
  150. Vector3 vector = base.constraintTarget.TransformPoint(position);
  151. Vector3 vector2 = base.constraintTarget.position - vector;
  152. Vector3 vector3 = vector - constraintTarget.position;
  153. float f = Vector3.Dot(vector2.normalized, vector3.normalized);
  154. float num = Mathf.Acos(f) * 57.29578f;
  155. if (float.IsNaN(num))
  156. {
  157. num = 0f;
  158. }
  159. float t = Mathf.Clamp01(num / this.BendFadeBorder);
  160. Vector3 vector4 = base.constraintTarget.position - constraintTarget.position;
  161. float num2 = Vector3.Dot(vector - constraintTarget.position, vector4.normalized);
  162. if (float.IsNaN(num2))
  163. {
  164. num2 = 0f;
  165. }
  166. Vector3 vector5 = constraintTarget.position + vector4.normalized * num2;
  167. Vector3 a = constraintTarget2.rotation * Vector3.up * 0.01f;
  168. Vector3 b = (vector - vector5) * this.BendStlength;
  169. Vector3 b2 = Vector3.Lerp(a, b, t);
  170. if (base.pointIKData.blendType == AIKCtrl.IKBlendType.IK_To_Detach)
  171. {
  172. constraintTarget2.position = Vector3.Lerp(this.elbowKneeCtrl.bone.position, vector5 + b2, base.positionWeight);
  173. }
  174. else
  175. {
  176. constraintTarget2.position = vector5 + b2;
  177. }
  178. this.SetElbowKneePositionWeight(base.positionWeight);
  179. }
  180. private void SetElbowKneePositionWeight(float val)
  181. {
  182. if (this.IsPullBody)
  183. {
  184. this.elbowKneeCtrl.positionWeight = val;
  185. }
  186. else
  187. {
  188. this.NoPullBodyIK.solver.bendModifierWeight = val;
  189. }
  190. }
  191. protected override void SetTargetTransformNoExec()
  192. {
  193. if (this.elbowKneeCtrl.positionWeight > 0f)
  194. {
  195. base.positionWeight = this.elbowKneeCtrl.positionWeight;
  196. base.constraintTarget.position += this.elbowKneeCtrl.constraintTarget.position - this.elbowKneeCtrl.bone.position;
  197. }
  198. if (this.elbowKneeCtrl.rotationWeight > 0f)
  199. {
  200. base.constraintTarget.position = this.elbowKneeCtrl.constraintTarget.TransformPoint(base.bone.localPosition);
  201. base.constraintTarget.rotation = this.elbowKneeCtrl.constraintTarget.rotation * base.bone.localRotation;
  202. }
  203. }
  204. protected override void DoPlaneCorrect(Vector3 normal)
  205. {
  206. ALimbIKCtrl.BorderCorrectType correctType = this.correctType;
  207. if (correctType != ALimbIKCtrl.BorderCorrectType.Bone)
  208. {
  209. if (correctType != ALimbIKCtrl.BorderCorrectType.HalfBody)
  210. {
  211. base.DoPlaneCorrect(normal);
  212. }
  213. else
  214. {
  215. base.DoPlaneCorrect(normal);
  216. this.shoulderThighCtrl.constraintTarget.position += normal;
  217. this.shoulderThighCtrl.positionWeight = base.positionWeight;
  218. this.elbowKneeCtrl.constraintTarget.position += normal;
  219. this.elbowKneeCtrl.positionWeight = base.positionWeight;
  220. }
  221. }
  222. else
  223. {
  224. Vector3 position = this.elbowKneeCtrl.bone.position;
  225. this.CorrectByElbowKnee(normal);
  226. if (this.elbowKneeCtrl.isNeedCorrect)
  227. {
  228. Vector3 position2 = base.bone.position;
  229. Vector3 fromDirection = this.elbowKneeCtrl.bone.position - this.shoulderThighCtrl.bone.position;
  230. Vector3 toDirection = position - this.shoulderThighCtrl.bone.position;
  231. this.shoulderThighCtrl.bone.rotation = Quaternion.FromToRotation(fromDirection, toDirection) * this.shoulderThighCtrl.bone.rotation;
  232. fromDirection = base.bone.position - this.elbowKneeCtrl.bone.position;
  233. toDirection = position2 - this.elbowKneeCtrl.bone.position;
  234. this.elbowKneeCtrl.bone.rotation = Quaternion.FromToRotation(fromDirection, toDirection) * this.elbowKneeCtrl.bone.rotation;
  235. }
  236. }
  237. }
  238. private void CorrectByElbowKnee(Vector3 normal)
  239. {
  240. Transform bone = this.shoulderThighCtrl.bone;
  241. Transform bone2 = this.elbowKneeCtrl.bone;
  242. Vector3 vector = base.bone.position + normal;
  243. Debug.DrawLine(base.bone.position, vector);
  244. float t = Mathf.Clamp01(Vector3.Dot(-bone.right, -bone2.right));
  245. Vector3 bend_pos = Vector3.Lerp(bone2.position, bone2.position + normal, t);
  246. this.ForceNoPullBodyIKSolve(vector, base.bone.rotation, bend_pos);
  247. }
  248. private void ForceNoPullBodyIKSolve(Vector3 target_pos, Quaternion target_rot, Vector3 bend_pos)
  249. {
  250. AIKCtrl.PosRotPair posRotPair = default(AIKCtrl.PosRotPair);
  251. posRotPair.Copy(this.NoPullBodyIK.solver.target);
  252. IKSolverLimb solver = this.NoPullBodyIK.solver;
  253. solver.IKPositionWeight = (solver.IKRotationWeight = 1f);
  254. solver.target.position = target_pos;
  255. solver.target.rotation = target_rot;
  256. solver.bendModifierWeight = 1f;
  257. Vector3 position = solver.bendGoal.position;
  258. solver.bendGoal.position = bend_pos;
  259. solver.Update();
  260. solver.target.position = posRotPair.pos;
  261. solver.target.rotation = posRotPair.rot;
  262. solver.bendGoal.position = position;
  263. }
  264. public override void HitCheck()
  265. {
  266. base.HitCheck();
  267. if (this.pairIK.colliderEnable && this.myIKMgr.body.IsCrcBody)
  268. {
  269. NativePlaneCollider nativePlaneCollider;
  270. if (base.isUpperBody)
  271. {
  272. nativePlaneCollider = ((!this.isLeft) ? this.myIKMgr.upperCrossBorder.right : this.myIKMgr.upperCrossBorder.left);
  273. }
  274. else
  275. {
  276. nativePlaneCollider = ((!this.isLeft) ? this.myIKMgr.lowerCrossBorder.right : this.myIKMgr.lowerCrossBorder.left);
  277. }
  278. Vector3 position = base.bone.position;
  279. if (this.elbowKneeCtrl.ForceCollidePlaneCollider(ALimbIKCtrl.BorderCorrectType.Bone, nativePlaneCollider))
  280. {
  281. Vector3 vector = position - base.bone.position;
  282. vector -= nativePlaneCollider.worldDirection * Vector3.Dot(vector, nativePlaneCollider.worldDirection);
  283. this.ForceNoPullBodyIKSolve(position, base.bone.rotation, this.elbowKneeCtrl.bone.position);
  284. }
  285. }
  286. }
  287. public override void OnPostFullBodySolverUpdate()
  288. {
  289. if (base.pointIKData.attachType == AIKCtrl.IKAttachType.Point)
  290. {
  291. return;
  292. }
  293. if (!base.isIKExec || this.IsPullBody)
  294. {
  295. base.OnPostFullBodySolverUpdate();
  296. return;
  297. }
  298. this.NoPullBodyIK.solver.Update();
  299. base.OnPostFullBodySolverUpdate();
  300. }
  301. public override void OnPostIKUpdate()
  302. {
  303. if (!base.isUpperBody)
  304. {
  305. this.SetHighHeelAngle();
  306. }
  307. base.OnPostIKUpdate();
  308. }
  309. private void SetHighHeelAngle()
  310. {
  311. if (!this.myIKMgr.body.IsHiheel)
  312. {
  313. return;
  314. }
  315. float num = Mathf.Clamp01(Vector3.Dot(Vector3.up, base.bone.right));
  316. float d = 25f * num;
  317. Vector3 localEulerAngles = base.bone.localEulerAngles;
  318. base.bone.localEulerAngles += Vector3.forward * d;
  319. if (MathUtility.AngleClamp180(base.bone.localEulerAngles.z) > 45f)
  320. {
  321. base.bone.localEulerAngles = new Vector3(localEulerAngles.x, localEulerAngles.y, 45f);
  322. }
  323. foreach (KeyValuePair<Transform, Vector3> keyValuePair in this.ToeBoneLocalAngleDic)
  324. {
  325. Transform key = keyValuePair.Key;
  326. Vector3 value = keyValuePair.Value;
  327. key.localEulerAngles = value - Vector3.forward * 25f;
  328. }
  329. }
  330. protected override void OnPostSetPositionWeight(float val)
  331. {
  332. if (base.pointIKData.attachType == AIKCtrl.IKAttachType.Point)
  333. {
  334. return;
  335. }
  336. if (this.IsPullBody)
  337. {
  338. this.effector.positionWeight = val;
  339. }
  340. else
  341. {
  342. this.NoPullBodyIK.solver.IKPositionWeight = val;
  343. }
  344. }
  345. protected override void OnPostSetRotationWeight(float val)
  346. {
  347. if (base.IsOldIKExec)
  348. {
  349. return;
  350. }
  351. if (this.IsPullBody)
  352. {
  353. this.effector.rotationWeight = val;
  354. }
  355. else
  356. {
  357. this.NoPullBodyIK.solver.IKRotationWeight = val;
  358. }
  359. }
  360. private const float HIGHHEEL_ANGLE = 25f;
  361. private const float ANGLEZ_RIMMIT = 45f;
  362. [SerializeField]
  363. [Space]
  364. [Range(1f, 90f)]
  365. private float BendFadeBorder = 30f;
  366. [SerializeField]
  367. [Range(1f, 2f)]
  368. private float BendStlength = 1.01f;
  369. public readonly IKEffector effector;
  370. private LimbIK NoPullBodyIK;
  371. private readonly Dictionary<Transform, Vector3> ToeBoneLocalAngleDic;
  372. }