ALimbIKCtrl.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. using System;
  2. using System.Collections.Generic;
  3. using kt.Physics;
  4. using kt.Utility;
  5. using RootMotion.FinalIK;
  6. using UnityEngine;
  7. public abstract class ALimbIKCtrl : AIKCtrl
  8. {
  9. public ALimbIKCtrl(FullBodyIKMgr ik_mgr, FBIKChain chain, IKMappingLimb ik_mapping, FullBodyIKMgr.IKEffectorType effector_type) : base(ik_mgr, effector_type)
  10. {
  11. ALimbIKCtrl $this = this;
  12. this.chain = chain;
  13. this.ikMapping = ik_mapping;
  14. this.OrijinPull = this.chain.pull;
  15. this.ColliderMeta = base.constraintTarget.parent.gameObject.AddComponent<IKColliderMeta>();
  16. this.ColliderMeta.effectorType = this.effectorType;
  17. if (this.myIKMgr.body.IsCrcBody)
  18. {
  19. ik_mgr.colliderLoader.onPostLoad.Add(delegate
  20. {
  21. $this.ColliderMeta.colliderList = ik_mgr.colliderLoader.GetColliderList(effector_type);
  22. $this.colliderEnable = false;
  23. }, false);
  24. }
  25. GameObject gameObject = new GameObject(effector_type.ToString() + "_IKPlaneCollider");
  26. gameObject.transform.SetParent(this.myIKMgr.planeColliderTrans, false);
  27. this.floorCollider = gameObject.AddComponent<NativePlaneCollider>();
  28. this.floorCollider.planeStatus.direction = MathUtility.VectorType.Y;
  29. this.floorCollider.enabled = true;
  30. this.wallCollider = gameObject.gameObject.AddComponent<NativePlaneCollider>();
  31. this.wallCollider.planeStatus.direction = MathUtility.VectorType.Z;
  32. this.wallCollider.enabled = false;
  33. this.myIKMgr.AddFloorCollider(this.floorCollider);
  34. this.myIKMgr.AddWallCollider(this.wallCollider);
  35. }
  36. protected List<ANativeColliderBase> ColliderList
  37. {
  38. get
  39. {
  40. return this.ColliderMeta.colliderList;
  41. }
  42. }
  43. public abstract bool isLeft { get; }
  44. public abstract ALimbIKCtrl pairIK { get; }
  45. public override bool isNeedFullbodySolverUpdate
  46. {
  47. get
  48. {
  49. return (base.isIKExec && this.IsPullBody) || (this.isNeedCorrect && this.correctType == ALimbIKCtrl.BorderCorrectType.HalfBody);
  50. }
  51. }
  52. public bool isNeedCorrect { get; protected set; }
  53. public bool colliderEnable
  54. {
  55. get
  56. {
  57. return this.ColliderMeta.enabled;
  58. }
  59. set
  60. {
  61. this.ColliderMeta.enabled = value;
  62. }
  63. }
  64. public NativePlaneCollider floorCollider { get; protected set; }
  65. public NativePlaneCollider wallCollider { get; protected set; }
  66. public NativeMaidPropCollider limbCapsule { get; protected set; }
  67. public override void Reset()
  68. {
  69. base.Reset();
  70. this.correctType = ALimbIKCtrl.BorderCorrectType.Bone;
  71. this.colliderEnable = false;
  72. this.HitCheckLimbList.Clear();
  73. this.isOldHitCheck = false;
  74. }
  75. public override void SetPullState(bool pull_on)
  76. {
  77. this.IsPullBody = pull_on;
  78. if (pull_on)
  79. {
  80. this.chain.pull = this.OrijinPull;
  81. }
  82. else
  83. {
  84. this.chain.pull = 0.1f;
  85. }
  86. }
  87. public void AddHitCheckLimb(ALimbIKCtrl limb)
  88. {
  89. if (!this.HitCheckLimbList.Contains(limb))
  90. {
  91. this.HitCheckLimbList.Add(limb);
  92. }
  93. }
  94. public override void TargetTransCpy()
  95. {
  96. base.TargetTransCpy();
  97. if (base.isUpperBody)
  98. {
  99. this.ikMapping.weight = 0f;
  100. }
  101. }
  102. public override void ApplyIKSetting()
  103. {
  104. this.isNeedCorrect = false;
  105. this.SolvedBonePos = base.bone.position;
  106. base.ApplyIKSetting();
  107. if (!base.isIKExec)
  108. {
  109. this.SetTargetTransformNoExec();
  110. }
  111. if (this.correctType == ALimbIKCtrl.BorderCorrectType.HalfBody)
  112. {
  113. this.HitCheck();
  114. }
  115. if (base.isUpperBody)
  116. {
  117. this.ikMapping.weight = Mathf.Max(this.ikMapping.weight, Mathf.Max(base.positionWeight, base.rotationWeight));
  118. }
  119. }
  120. protected virtual void SetTargetTransformNoExec()
  121. {
  122. }
  123. public virtual void HitCheck()
  124. {
  125. if (this.myIKMgr.body.IsCrcBody)
  126. {
  127. this.CheckLimbCapsule();
  128. }
  129. this.CheckPlaneCollider();
  130. }
  131. private void CheckLimbCapsule()
  132. {
  133. using (HashSet<ALimbIKCtrl>.Enumerator enumerator = this.HitCheckLimbList.GetEnumerator())
  134. {
  135. while (enumerator.MoveNext())
  136. {
  137. ALimbIKCtrl limb = enumerator.Current;
  138. ALimbIKCtrl $this = this;
  139. if (this.myIKMgr.ikExecOrder >= limb.myIKMgr.ikExecOrder && !limb.myIKMgr.body.isLateUpdateEnd && !this.myIKMgr.body.isLateUpdateEnd)
  140. {
  141. if (limb.myIKMgr.isIKExec)
  142. {
  143. limb.myIKMgr.onPostSolverUpdate.Add(delegate
  144. {
  145. $this.CheckLimbCapsule(limb);
  146. }, true);
  147. }
  148. else
  149. {
  150. limb.myIKMgr.body.onLateUpdateEnd.Add(delegate
  151. {
  152. $this.CheckLimbCapsule(limb);
  153. }, true);
  154. }
  155. }
  156. else
  157. {
  158. this.CheckLimbCapsule(limb);
  159. }
  160. }
  161. }
  162. }
  163. private void CheckLimbCapsule(ALimbIKCtrl limb)
  164. {
  165. NativeMaidPropCollider limbCapsule = limb.limbCapsule;
  166. if (!limbCapsule)
  167. {
  168. return;
  169. }
  170. for (int i = 0; i < 4; i++)
  171. {
  172. Vector3 b;
  173. if (!limbCapsule.Collide(this.limbCapsule, out b))
  174. {
  175. break;
  176. }
  177. Vector3 vector = base.bone.position + b;
  178. Transform bone = this.ChainParentCtrl.bone;
  179. Debug.DrawLine(base.bone.position, vector, Color.red);
  180. bone.rotation = Quaternion.FromToRotation(base.bone.position - bone.position, vector - bone.position) * bone.rotation;
  181. }
  182. }
  183. private void CheckPlaneCollider()
  184. {
  185. if (this.correctType != ALimbIKCtrl.BorderCorrectType.HalfBody)
  186. {
  187. bool flag = false;
  188. Vector3 offset = Vector3.zero;
  189. if (this.ChainParentCtrl != null && this.ChainParentCtrl.isNeedCorrect)
  190. {
  191. flag |= this.CheckPlaneCollider(this.floorCollider);
  192. flag |= this.CheckPlaneCollider(this.wallCollider);
  193. offset = this.SolvedBonePos - base.bone.position;
  194. }
  195. if (!flag)
  196. {
  197. flag |= this.CheckPlaneCollider(this.floorCollider, offset, null);
  198. flag |= this.CheckPlaneCollider(this.wallCollider, offset, null);
  199. }
  200. }
  201. else
  202. {
  203. this.CheckPlaneCollider(this.floorCollider, base.constraintTarget);
  204. this.CheckPlaneCollider(this.wallCollider, base.constraintTarget);
  205. }
  206. }
  207. private bool CheckPlaneCollider(NativePlaneCollider plane_collider)
  208. {
  209. return this.CheckPlaneCollider(plane_collider, Vector3.zero, null);
  210. }
  211. private bool CheckPlaneCollider(NativePlaneCollider plane_collider, Transform target_trs)
  212. {
  213. return this.CheckPlaneCollider(plane_collider, Vector3.zero, target_trs);
  214. }
  215. private bool CheckPlaneCollider(NativePlaneCollider plane_collider, Vector3 offset, Transform copy_trs = null)
  216. {
  217. if (!plane_collider.enabled || !this.colliderEnable)
  218. {
  219. return false;
  220. }
  221. Vector3 zero = Vector3.zero;
  222. bool flag = false;
  223. if (this.isOldHitCheck)
  224. {
  225. for (int i = 0; i < 4; i++)
  226. {
  227. Vector3 position = base.bone.position;
  228. bool flag2 = plane_collider.Collide(ref position, 0f);
  229. flag = (flag || flag2);
  230. if (!flag2)
  231. {
  232. break;
  233. }
  234. if (this.ChainParentCtrl)
  235. {
  236. Debug.DrawLine(this.ChainParentCtrl.bone.position, base.bone.position, Color.gray, 0f, false);
  237. }
  238. this.DoPlaneCorrect(position - base.bone.position);
  239. }
  240. if (flag && this.ChainParentCtrl != null)
  241. {
  242. Debug.DrawLine(this.ChainParentCtrl.bone.position, base.bone.position, Color.magenta);
  243. }
  244. }
  245. else if (this.ColliderList != null)
  246. {
  247. foreach (ANativeColliderBase anativeColliderBase in this.ColliderList)
  248. {
  249. if (anativeColliderBase && anativeColliderBase.enabled)
  250. {
  251. Vector3 localPosition = anativeColliderBase.transform.localPosition;
  252. Quaternion localRotation = anativeColliderBase.transform.localRotation;
  253. if (copy_trs && copy_trs != base.bone)
  254. {
  255. Vector3 position2 = base.bone.InverseTransformPoint(anativeColliderBase.transform.position);
  256. Quaternion rhs = Quaternion.Inverse(base.bone.rotation) * anativeColliderBase.transform.rotation;
  257. anativeColliderBase.transform.position = copy_trs.TransformPoint(position2);
  258. anativeColliderBase.transform.rotation = copy_trs.rotation * rhs;
  259. }
  260. else
  261. {
  262. anativeColliderBase.transform.position += offset;
  263. }
  264. for (int j = 0; j < 4; j++)
  265. {
  266. bool flag3 = plane_collider.Collide(anativeColliderBase, out zero);
  267. flag = (flag || flag3);
  268. if (!flag3)
  269. {
  270. break;
  271. }
  272. if (this.ChainParentCtrl)
  273. {
  274. Debug.DrawLine(this.ChainParentCtrl.bone.position, base.bone.position, Color.gray, 0f, false);
  275. }
  276. anativeColliderBase.transform.localPosition = localPosition;
  277. anativeColliderBase.transform.localRotation = localRotation;
  278. this.DoPlaneCorrect(zero);
  279. }
  280. anativeColliderBase.transform.localPosition = localPosition;
  281. anativeColliderBase.transform.localRotation = localRotation;
  282. }
  283. }
  284. if (flag && this.ChainParentCtrl != null)
  285. {
  286. Debug.DrawLine(this.ChainParentCtrl.bone.position, base.bone.position, Color.magenta);
  287. }
  288. }
  289. return flag;
  290. }
  291. protected virtual void DoPlaneCorrect(Vector3 normal)
  292. {
  293. switch (this.correctType)
  294. {
  295. case ALimbIKCtrl.BorderCorrectType.Bone:
  296. {
  297. Vector3 vector = base.bone.position + normal;
  298. Debug.DrawLine(base.bone.position, vector);
  299. if (this.ChainParentCtrl != null)
  300. {
  301. AIKCtrl.PosRotPair posRotPair = default(AIKCtrl.PosRotPair);
  302. if (this.ChainChildCtrl)
  303. {
  304. posRotPair.Copy(this.ChainChildCtrl.bone);
  305. }
  306. Quaternion rotation = base.bone.rotation;
  307. Transform bone = this.ChainParentCtrl.bone;
  308. Vector3 fromDirection = base.bone.position - bone.position;
  309. Vector3 toDirection = vector - bone.position;
  310. bone.rotation = Quaternion.FromToRotation(fromDirection, toDirection) * bone.rotation;
  311. base.bone.rotation = rotation;
  312. if (this.ChainChildCtrl)
  313. {
  314. fromDirection = this.ChainChildCtrl.bone.position - base.bone.position;
  315. toDirection = posRotPair.pos - base.bone.position;
  316. base.bone.rotation = Quaternion.FromToRotation(fromDirection, toDirection) * base.bone.rotation;
  317. this.ChainChildCtrl.bone.rotation = posRotPair.rot;
  318. }
  319. this.isNeedCorrect = true;
  320. }
  321. break;
  322. }
  323. case ALimbIKCtrl.BorderCorrectType.HalfBody:
  324. if (!base.GetIKSettingData(AIKCtrl.IKAttachType.NewPoint).isIKExec)
  325. {
  326. base.GetIKSettingData(AIKCtrl.IKAttachType.NewPoint).isIKExec = true;
  327. }
  328. if (base.positionWeight == 0f)
  329. {
  330. base.positionWeight = 1f;
  331. }
  332. base.constraintTarget.position += normal;
  333. break;
  334. case ALimbIKCtrl.BorderCorrectType.Chara:
  335. this.myIKMgr.bodyOffsetCtrl.AddPosOffset(normal);
  336. break;
  337. case ALimbIKCtrl.BorderCorrectType.WithPartner:
  338. this.myIKMgr.bodyOffsetCtrl.AddPosOffset(normal);
  339. foreach (Maid maid in this.myIKMgr.partnerList)
  340. {
  341. maid.body0.fullBodyIK.bodyOffsetCtrl.AddPosOffset(normal);
  342. }
  343. break;
  344. }
  345. }
  346. public bool ForceCollidePlaneCollider(ALimbIKCtrl.BorderCorrectType correct_type, NativePlaneCollider collider)
  347. {
  348. bool colliderEnable = this.colliderEnable;
  349. this.colliderEnable = true;
  350. ALimbIKCtrl.BorderCorrectType borderCorrectType = this.correctType;
  351. this.correctType = correct_type;
  352. bool result = this.CheckPlaneCollider(collider);
  353. this.correctType = borderCorrectType;
  354. this.colliderEnable = colliderEnable;
  355. return result;
  356. }
  357. public override void OnPostFullBodySolverUpdate()
  358. {
  359. this.SolvedBonePos = base.bone.position;
  360. }
  361. public override void OnPostIKUpdate()
  362. {
  363. if (base.isIKExec && this.correctType != ALimbIKCtrl.BorderCorrectType.HalfBody)
  364. {
  365. this.HitCheck();
  366. }
  367. base.OnPostIKUpdate();
  368. }
  369. private const int COLIDER_CHECK_COUNT = 4;
  370. public ALimbIKCtrl.BorderCorrectType correctType;
  371. private IKColliderMeta ColliderMeta;
  372. public readonly FBIKChain chain;
  373. public readonly IKMappingLimb ikMapping;
  374. protected float OrijinPull = -1f;
  375. protected ALimbIKCtrl ChainParentCtrl;
  376. protected ALimbIKCtrl ChainChildCtrl;
  377. protected bool IsPullBody = true;
  378. private Vector3 SolvedBonePos;
  379. private HashSet<ALimbIKCtrl> HitCheckLimbList = new HashSet<ALimbIKCtrl>();
  380. [HideInInspector]
  381. public bool isOldHitCheck;
  382. public enum BorderCorrectType
  383. {
  384. Bone,
  385. HalfBody,
  386. Chara,
  387. WithPartner,
  388. All
  389. }
  390. }