action_run.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. /// <summary>
  2. /// ZWN
  3. /// 跳和跑代码
  4. /// 20210917
  5. /// </summary>
  6. using System.Collections;
  7. using System.Collections.Generic;
  8. using UnityEngine;
  9. using UnityEngine.UI;
  10. public enum action_run_state
  11. {
  12. None,
  13. Jump,
  14. Run
  15. }
  16. public class action_run : MonoBehaviour
  17. {
  18. public static action_run single;
  19. public float space_time = 0.5f;//状态改变间隔时间
  20. public bool Run_Flag = false;//整体是否检测
  21. public float space_X = 0.5f;//跳跃阈值
  22. public float spacehand = 0.5f;//跑步阈值
  23. Dictionary<int, Vector3> zwn_Single_Vec = new Dictionary<int, Vector3>();//关于位置数据的存储
  24. Vector3 hand_Right, Shoulder_Right, hand_Left, Shoulder_Left;//右手//右肘//右肩//左手//左肘//左肩
  25. int hand_Count = 6, buff_sz = 3; //存储帧数
  26. [HideInInspector]
  27. public action_run_state cur_RunState = action_run_state.None;//当前状态
  28. [HideInInspector]
  29. public action_run_state last_RunState = action_run_state.None;//上状态记录
  30. public float width;//宽
  31. public List<int> list_Shoulder_Y, list_Shoulder_X;//肩部XY记录
  32. int jump_num, run_num, none_num;//状态数量统计
  33. public Text show_Num;//状态显示
  34. string last_state;//上个状态
  35. Vector3 default_vec = new Vector3(-1, -1, 0);
  36. //关于左侧属性
  37. #region
  38. bool flag_time_Left = false;
  39. float state_time_Left = 0;
  40. public List<float> list_Hand_X_Left, list_Hand_Y_Left;//左右手X Y列表
  41. #endregion
  42. //关于右侧属性
  43. #region
  44. bool flag_time_Right = false;
  45. float state_time_Right = 0;
  46. public List<float> list_Hand_X_Right, list_Hand_Y_Right;//左右手X Y列表
  47. #endregion
  48. void Awake()
  49. {
  50. space_X = 1f;//跳跃阈值
  51. spacehand = 1.5f;//跑步阈值
  52. single = this;
  53. if (Application.platform == RuntimePlatform.WindowsEditor
  54. || Application.platform == RuntimePlatform.WindowsPlayer)
  55. {
  56. hand_Count = 25;
  57. }
  58. if (Application.platform == RuntimePlatform.Android)// 使用Unity切换Platform无法模拟
  59. {
  60. hand_Count = 6;
  61. }
  62. //Init_Run();
  63. }
  64. bool reInit = false;
  65. /// <summary>
  66. /// 初始化判断
  67. /// </summary>
  68. public void Init_Run()
  69. {
  70. time_vec = 0;
  71. cur_RunState = action_run_state.None;
  72. flag_time_Left = true;
  73. state_time_Left = 0;
  74. flag_time_Right = true;
  75. state_time_Right = 0;
  76. if (reInit)
  77. {
  78. clear();
  79. }
  80. Run_Flag = true;
  81. if (!reInit)
  82. {
  83. reInit = true;
  84. }
  85. }
  86. /// <summary>
  87. /// 结束判断
  88. /// </summary>
  89. public void End_Run()
  90. {
  91. if (reInit)
  92. {
  93. clear();
  94. }
  95. cur_RunState = action_run_state.None;
  96. flag_time_Left = true;
  97. state_time_Left = 0;
  98. flag_time_Right = true;
  99. state_time_Right = 0;
  100. Run_Flag = false;
  101. }
  102. void Update()
  103. {
  104. if (Run_Flag)
  105. {
  106. ZWN_Single_Vec();
  107. List_Run();
  108. if (show_Num != null)
  109. {
  110. show_Num.text = last_state + "跳:" + jump_num +
  111. "\n跑:" + run_num + "\n空:" + none_num;
  112. }
  113. }
  114. }
  115. void List_Run()
  116. {
  117. if (
  118. Shoulder_Right.x != -1 && Shoulder_Right.y != -1 &&
  119. Shoulder_Left.x != -1 && Shoulder_Left.y != -1)
  120. {
  121. list_Shoulder_Y.Add((int)((Shoulder_Right.y + Shoulder_Left.y) / 2));
  122. list_Shoulder_X.Add((int)(Mathf.Abs(Shoulder_Right.x - Shoulder_Left.x) / 2));
  123. }
  124. if (list_Shoulder_Y.Count > hand_Count)
  125. {
  126. list_Shoulder_Y.Remove(list_Shoulder_Y[0]);
  127. list_Shoulder_X.Remove(list_Shoulder_X[0]);
  128. List_Run_Y();
  129. List_Run_X();
  130. ratioTmpY = (max_RunY - min_RunY) / width;//肩部Y占比例
  131. ratioTmpX = ave_List_RunX / width;//肩部X占比例
  132. /* print("跳"+ cur_DirY +" "+ (cur_DirY > 0) + "\nratioTmpY:" + ratioTmpY
  133. + "\nratioTmpX:"+ratioTmpX+" "+ ratioTmpX * space_X + (ratioTmpY > ratioTmpX * space_X));*/
  134. if (cur_DirY > 0 && ratioTmpY > ratioTmpX * space_X)
  135. {
  136. State_Jump();
  137. }
  138. else
  139. {
  140. List_Run_Left();
  141. }
  142. }
  143. }
  144. float cur_DirY = 0, cur_Dir_StartY = 0, cur_Dir_EndY = 0, max_RunY = -0xffff, min_RunY = 0xffff;
  145. float ratioTmpY;
  146. /// <summary>
  147. /// 求X位移差、位移比例、滑动方向
  148. /// </summary>
  149. void List_Run_Y()
  150. {
  151. cur_DirY = 0;
  152. cur_Dir_StartY = 0;
  153. cur_Dir_EndY = 0;
  154. max_RunY = -0xffff;
  155. min_RunY = 0xffff;
  156. for (int i = 0; i < list_Shoulder_Y.Count; i++)
  157. {
  158. if (i == 0)
  159. {
  160. max_RunY = list_Shoulder_Y[i];
  161. min_RunY = list_Shoulder_Y[i];
  162. }
  163. if (i < buff_sz)
  164. {
  165. cur_Dir_StartY += list_Shoulder_Y[i];
  166. }
  167. if (i >= list_Shoulder_Y.Count - buff_sz)
  168. {
  169. cur_Dir_EndY += list_Shoulder_Y[i];
  170. }
  171. if (list_Shoulder_Y[i] > max_RunY)
  172. max_RunY = list_Shoulder_Y[i];
  173. if (list_Shoulder_Y[i] < min_RunY)
  174. min_RunY = list_Shoulder_Y[i];
  175. }
  176. cur_DirY = (cur_Dir_StartY / buff_sz) - (cur_Dir_EndY / buff_sz);
  177. }
  178. float cur_DirX = 0, cur_Dir_StartX = 0, cur_Dir_EndX = 0, max_RunX = -0xffff, min_RunX = 0xffff;
  179. float ave_List_RunX, ratioTmpX;
  180. /// <summary>
  181. /// 求X位移差、位移比例、滑动方向
  182. /// </summary>
  183. void List_Run_X()
  184. {
  185. cur_DirX = 0;
  186. cur_Dir_StartX = 0;
  187. cur_Dir_EndX = 0;
  188. max_RunX = -0xffff;
  189. min_RunX = 0xffff;
  190. ave_List_RunX = 0;
  191. for (int i = 0; i < list_Shoulder_X.Count; i++)
  192. {
  193. if (i == 0)
  194. {
  195. max_RunX = list_Shoulder_X[i];
  196. min_RunX = list_Shoulder_X[i];
  197. }
  198. if (i < buff_sz)
  199. {
  200. cur_Dir_StartX += list_Shoulder_X[i];
  201. }
  202. if (i >= list_Shoulder_X.Count - buff_sz)
  203. {
  204. cur_Dir_EndX += list_Shoulder_X[i];
  205. }
  206. if (list_Shoulder_X[i] > max_RunY)
  207. max_RunX = list_Shoulder_X[i];
  208. if (list_Shoulder_X[i] < min_RunY)
  209. min_RunX = list_Shoulder_X[i];
  210. ave_List_RunX += list_Shoulder_X[i];
  211. }
  212. ave_List_RunX = ave_List_RunX / list_Shoulder_X.Count;
  213. cur_DirX = (cur_Dir_StartX / buff_sz) - (cur_Dir_EndX / buff_sz);
  214. }
  215. public float time_vec = 0;
  216. /// <summary>
  217. /// 点信息
  218. /// </summary>
  219. void ZWN_Single_Vec()
  220. {
  221. for (int i = 0; i < 17; i++)
  222. {
  223. if (zwn_Single_Vec.ContainsKey(i))
  224. {
  225. zwn_Single_Vec[i] = zwn_common_data.single.zwn_original_pose[i];
  226. }
  227. else
  228. {
  229. zwn_Single_Vec.Add(i, zwn_common_data.single.zwn_original_pose[i]);
  230. }
  231. }
  232. if (zwn_Single_Vec[9] == default_vec || zwn_Single_Vec[5] == default_vec
  233. || zwn_Single_Vec[10] == default_vec || zwn_Single_Vec[6] == default_vec)
  234. {
  235. time_vec += Time.deltaTime;
  236. if (time_vec >= 0.2f)
  237. {
  238. clear();
  239. State_None();
  240. time_vec = 0;
  241. }
  242. }
  243. else
  244. {
  245. time_vec = 0;
  246. }
  247. if (zwn_Single_Vec[9] != default_vec)
  248. {
  249. hand_Right = zwn_Single_Vec[9];
  250. }
  251. if (zwn_Single_Vec[5] != default_vec)
  252. {
  253. Shoulder_Right = zwn_Single_Vec[5];
  254. }
  255. if (zwn_Single_Vec[10] != default_vec)
  256. {
  257. hand_Left = zwn_Single_Vec[10];
  258. }
  259. if (zwn_Single_Vec[6] != default_vec)
  260. {
  261. Shoulder_Left = zwn_Single_Vec[6];
  262. }
  263. //if (width != Helper.Width)
  264. // width = Helper.Width;
  265. }
  266. /// <summary>
  267. /// 右侧状态判断
  268. /// </summary>
  269. void List_Run_Right()
  270. {
  271. if (hand_Right.x != -1 && hand_Right.y != -1)
  272. {
  273. list_Hand_X_Right.Add(hand_Right.x);
  274. list_Hand_Y_Right.Add(hand_Right.y);
  275. }
  276. if (!flag_time_Right)
  277. {
  278. state_time_Right += Time.deltaTime;
  279. if (state_time_Right >= space_time)
  280. {
  281. flag_time_Right = true;
  282. state_time_Right = 0;
  283. }
  284. }
  285. if (list_Hand_X_Right.Count > hand_Count)
  286. {
  287. list_Hand_X_Right.Remove(list_Hand_X_Right[0]);
  288. list_Hand_Y_Right.Remove(list_Hand_Y_Right[0]);
  289. List_Run_Right_X();
  290. List_Run_Right_Y();
  291. ratioTmpX_Right = ave_X_Right / width;//右手整体位移X
  292. ratioTmpY_Right = ave_Y_Right / width;//右手整体位移Y
  293. //print("右手跑" + (ratioTmpX_Right > ratioTmpX * spacehand) + " " + (ratioTmpY_Right > ratioTmpX * spacehand));
  294. if (ratioTmpX_Right > ratioTmpX * spacehand
  295. || ratioTmpY_Right > ratioTmpX * spacehand
  296. )
  297. {
  298. //print("右");
  299. State_Run();
  300. }
  301. else
  302. {
  303. State_None();
  304. }
  305. }
  306. }
  307. float ave_X_Right;
  308. float ratioTmpX_Right;
  309. /// <summary>
  310. /// 求X位移差、位移比例、滑动方向
  311. /// </summary>
  312. void List_Run_Right_X()
  313. {
  314. ave_X_Right = 0;
  315. for (int i = 0; i < list_Hand_X_Right.Count; i++)
  316. {
  317. if (i + 1 < list_Hand_X_Right.Count)
  318. {
  319. ave_X_Right += Mathf.Abs(list_Hand_X_Right[i + 1] - list_Hand_X_Right[i]);
  320. }
  321. }
  322. }
  323. float ave_Y_Right;
  324. float ratioTmpY_Right;
  325. /// <summary>
  326. /// 求Y位移差与位移比例
  327. /// </summary>
  328. void List_Run_Right_Y()
  329. {
  330. ave_Y_Right = 0;
  331. for (int i = 0; i < list_Hand_Y_Right.Count; i++)
  332. {
  333. if (i + 1 < list_Hand_Y_Right.Count)
  334. {
  335. ave_Y_Right += Mathf.Abs(list_Hand_Y_Right[i + 1] - list_Hand_Y_Right[i]);
  336. }
  337. }
  338. }
  339. /// <summary>
  340. /// 左侧状态判断
  341. /// </summary>
  342. void List_Run_Left()
  343. {
  344. //print("hand_Left.x" + hand_Left.x + " hand_Left.y" + hand_Left.y);
  345. if (hand_Left.x != -1 && hand_Left.y != -1)
  346. {
  347. list_Hand_X_Left.Add(hand_Left.x);
  348. list_Hand_Y_Left.Add(hand_Left.y);
  349. }
  350. if (!flag_time_Left)
  351. {
  352. state_time_Left += Time.deltaTime;
  353. if (state_time_Left >= space_time)
  354. {
  355. flag_time_Left = true;
  356. state_time_Left = 0;
  357. }
  358. }
  359. if (list_Hand_X_Left.Count > hand_Count)
  360. {
  361. list_Hand_X_Left.Remove(list_Hand_X_Left[0]);
  362. list_Hand_Y_Left.Remove(list_Hand_Y_Left[0]);
  363. List_Run_Left_X();
  364. List_Run_Left_Y();
  365. ratioTmpX_Left = ave_X_Left / width;//右手整体位移X
  366. ratioTmpY_Left = ave_Y_Left / width;//右手整体位移Y
  367. //print("左手跑" + (ratioTmpX_Left > ratioTmpX * spacehand) + " " + (ratioTmpY_Left > ratioTmpX * spacehand) +
  368. //" " + ratioTmpX_Left + " " + ratioTmpX * spacehand + " " + ratioTmpY_Left);
  369. if (ratioTmpX_Left > ratioTmpX * spacehand
  370. || ratioTmpY_Left > ratioTmpX * spacehand
  371. )
  372. {
  373. //print("左");
  374. State_Run();
  375. }
  376. else
  377. {
  378. //State_None();
  379. List_Run_Right();
  380. }
  381. }
  382. }
  383. float ave_X_Left;
  384. float ratioTmpX_Left;
  385. /// <summary>
  386. /// 求X位移差、位移比例、滑动方向
  387. /// </summary>
  388. void List_Run_Left_X()
  389. {
  390. ave_X_Left = 0;
  391. for (int i = 0; i < list_Hand_X_Left.Count; i++)
  392. {
  393. if (i + 1 < list_Hand_X_Left.Count)
  394. {
  395. ave_X_Left += Mathf.Abs(list_Hand_X_Left[i + 1] - list_Hand_X_Left[i]);
  396. }
  397. }
  398. }
  399. float ave_Y_Left;
  400. float ratioTmpY_Left;
  401. /// <summary>
  402. /// 求Y位移差与位移比例
  403. /// </summary>
  404. void List_Run_Left_Y()
  405. {
  406. ave_Y_Left = 0;
  407. for (int i = 0; i < list_Hand_Y_Left.Count; i++)
  408. {
  409. if (i + 1 < list_Hand_Y_Left.Count)
  410. {
  411. ave_Y_Left += Mathf.Abs(list_Hand_Y_Left[i + 1] - list_Hand_Y_Left[i]);
  412. }
  413. }
  414. }
  415. /// <summary>
  416. /// 跳跃状态
  417. /// </summary>
  418. void State_Jump()
  419. {
  420. if (cur_RunState != action_run_state.Jump)
  421. {
  422. jump_num += 1;
  423. last_State();
  424. cur_RunState = action_run_state.Jump;
  425. last_RunState = cur_RunState;
  426. }
  427. }
  428. /// <summary>
  429. /// 跑步状态
  430. /// </summary>
  431. void State_Run()
  432. {
  433. /* if (cur_RunState != action_run_state.Run)
  434. {*/
  435. run_num += 1;
  436. cur_RunState = action_run_state.Run;
  437. last_State();
  438. last_RunState = cur_RunState;
  439. state_time_Right = 0;
  440. /* }*/
  441. }
  442. /// <summary>
  443. /// 空状态
  444. /// </summary>
  445. void State_None()
  446. {
  447. /* if (cur_RunState != action_run_state.None)
  448. {*/
  449. none_num += 1;
  450. cur_RunState = action_run_state.None;
  451. last_State();
  452. last_RunState = cur_RunState;
  453. //clear();
  454. /* }*/
  455. }
  456. /// <summary>
  457. /// 上一个状态提示
  458. /// </summary>
  459. void last_State()
  460. {
  461. last_state = "上一个状态:";
  462. switch (last_RunState)
  463. {
  464. case action_run_state.None:
  465. last_state += "空\n";
  466. break;
  467. case action_run_state.Jump:
  468. last_state += "跳\n";
  469. break;
  470. case action_run_state.Run:
  471. last_state += "跑\n";
  472. break;
  473. }
  474. switch (cur_RunState)
  475. {
  476. case action_run_state.None:
  477. last_state += "状态空\n";
  478. break;
  479. case action_run_state.Jump:
  480. last_state += "状态跳\n";
  481. break;
  482. case action_run_state.Run:
  483. last_state += "状态跑\n";
  484. break;
  485. }
  486. }
  487. /// <summary>
  488. /// 将存储数据清空
  489. /// </summary>
  490. void clear()
  491. {
  492. if (list_Hand_X_Right.Count > 0)
  493. {
  494. list_Hand_Y_Right.Clear();
  495. list_Hand_X_Right.Clear();
  496. }
  497. if (list_Hand_X_Left.Count > 0)
  498. {
  499. list_Hand_Y_Left.Clear();
  500. list_Hand_X_Left.Clear();
  501. }
  502. if (list_Shoulder_X.Count > 0)
  503. {
  504. list_Shoulder_X.Clear();
  505. list_Shoulder_Y.Clear();
  506. }
  507. }
  508. }