ProgressPopController.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. using Cysharp.Threading.Tasks;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5. namespace WS
  6. {
  7. [ObjectSystem]
  8. public class ProgressPopControllerUpdateSystem : UpdateSystem<ProgressPopController>
  9. {
  10. public override void Update(ProgressPopController self)
  11. {
  12. //self.LateUpdate();
  13. ////侧面布局
  14. //if (FacadeComponent.Instance.GetController<ProgressPopController>() != null)
  15. //{
  16. // self.playerPos = Player.instance.transform.position;
  17. // float angle = Mathf.DeltaAngle(self.VRCameraRotY, Player.instance.hmdTransform.localEulerAngles.y);
  18. // float num = Mathf.Abs(angle) / self.angle;
  19. // if (num > 1)
  20. // {
  21. // self.VRCameraRotY += (int)num * 2 * self.angle * Mathf.Sign(angle);
  22. // if (self.VRCameraRotY > 360)
  23. // {
  24. // self.VRCameraRotY -= 360;
  25. // }
  26. // Vector3 uiToPlayer = self.GetUITranfrom().position - self.playerPos;
  27. // self.startDir = Quaternion.Euler(0, Mathf.Sign(angle) * 2 * self.angle, 0) * uiToPlayer;
  28. // self.uiRot = Quaternion.Euler(0, self.GetUITranfrom().rotation.eulerAngles.y + 2 * self.angle * Mathf.Sign(angle), 0);
  29. // }
  30. // else
  31. // {
  32. // if (self.startRotY != Player.instance.transform.localEulerAngles.y)
  33. // {
  34. // self.GetUITranfrom().LookAt(self.playerPos);
  35. // float angleValue = Mathf.DeltaAngle(self.startRotY, Player.instance.transform.localEulerAngles.y);
  36. // self.startDir = Quaternion.Euler(0, angleValue, 0) * self.startDir;
  37. // float uiAngle = self.uiRot.eulerAngles.y + angleValue;
  38. // if (uiAngle >= 180)
  39. // {
  40. // uiAngle -= 360;
  41. // }
  42. // self.uiRot = Quaternion.Euler(new Vector3(0, uiAngle, 0));
  43. // self.startRotY = Player.instance.transform.localEulerAngles.y;
  44. // }
  45. // else
  46. // {
  47. // self.uiRot = self.GetUITranfrom().localRotation;
  48. // }
  49. // }
  50. // self.uiPos = self.startDir + self.playerPos;
  51. // self.SetView(self.uiPos / self.canvasScale, self.uiRot);
  52. //}
  53. }
  54. }
  55. [ObjectSystem]
  56. public class ProgressPopControllerLateUpdateSystem : LateUpdateSystem<ProgressPopController>
  57. {
  58. public override void LateUpdate(ProgressPopController self)
  59. {
  60. self.LateUpdate();
  61. }
  62. }
  63. public class ProgressPopController : Controller<ProgressPopView, ProgressPopModel>
  64. {
  65. ProcessManager processMgr;
  66. /// <summary> 限制角度 </summary>
  67. public float limitAngle = 90;
  68. /// <summary> VR相机Y轴旋转 </summary>
  69. public float VRCameraRotY;
  70. /// <summary> Y轴距离 </summary>
  71. public float uiDistanceY = 500;
  72. /// <summary> Z轴距离 </summary>
  73. public float uiDistanceZ = 800;
  74. /// <summary> ui到玩家的向量 </summary>
  75. public Vector3 startDir;
  76. /// <summary> UI位置 </summary>
  77. public Vector3 uiPos;
  78. /// <summary> UI旋转 </summary>
  79. public Quaternion uiRot;
  80. /// <summary> 画布缩放(用于计算世界坐标) </summary>
  81. public float canvasScale = 0.001f;
  82. /// <summary> 玩家位置 </summary>
  83. public Vector3 playerPos;
  84. /// <summary> 玩家初始旋转 </summary>
  85. public float startRotY;
  86. /// <summary> UI页面是否隐藏 </summary>
  87. public bool isHide;
  88. /// <summary> 页面禁用 </summary>
  89. public bool isForbidden = false;
  90. /// <summary> 快捷键提示页 </summary>
  91. //private NoticeViewController noticeView;
  92. /// <summary> 当前任务分数 </summary>
  93. public float currentTaskScore;
  94. protected override void BindingViewModel()
  95. {
  96. //_Model.Bind(_View.ifJump, _Model.InputPassWord, (a) =>
  97. //{
  98. // if (int.TryParse(a, out int r))
  99. // {
  100. // PlayerPrefs.SetInt("Test_Jump", r);
  101. // string str = $"增加{r}步";
  102. // _View.TestJumpBtn.GetComponentInChildren<Text>().text = str;
  103. // }
  104. //});
  105. _Model.Bind(_View.TestJumpBtn, TestJumpBtnClick);
  106. _Model.Bind(_View.ReturnBtn, ReturnBtnClick);
  107. _Model.Bind(_View.LastBtn, LastBtnClick);
  108. _Model.Bind(_View.NextBtn, NextBtnClick);
  109. _Model.Bind(_View.HintBtn, HintBtnClick);
  110. _Model.Bind(_View.Progress, _Model.Progress);
  111. _Model.Bind(_View.Message, _Model.Message);
  112. }
  113. public override void OpenView()
  114. {
  115. base.OpenView();
  116. isHide = false;
  117. isForbidden = false;
  118. //noticeView = FacadeComponent.Instance.CreateController<NoticeViewController>();
  119. //noticeView.OpenView();
  120. processMgr = GameManager.Instance.ProcessManager;
  121. _Model.WSTaskLists = processMgr.GetVTaskList();
  122. RefreshMessage(0);
  123. processMgr.OnCompleteVTaskCallback += RefreshMessage;
  124. processMgr.OnEndProcessCallback += OnProcessCompletCallBack;
  125. currentTaskScore = processMgr.GetVTask(processMgr.GetCurrentModule().VTaskId).Score;
  126. VRCameraRotY = 0;
  127. startRotY = 0;
  128. var playerPos = Player.Inst.transform.position;
  129. uiPos = playerPos / canvasScale + new Vector3(0, uiDistanceY, uiDistanceZ);
  130. var Z = Player.Inst.transform.forward * uiDistanceZ;
  131. var Y = Player.Inst.transform.up * uiDistanceY;
  132. uiRot = Quaternion.Euler(new Vector3(70, 0, 0));
  133. _View.SetPosition(uiPos, uiRot);
  134. startDir = _View.UIGameObject.transform.position - playerPos;
  135. }
  136. public override void Dispose()
  137. {
  138. processMgr.OnCompleteVTaskCallback -= RefreshMessage;
  139. processMgr.OnEndProcessCallback -= OnProcessCompletCallBack;
  140. //noticeView?.CloseView();
  141. base.Dispose();
  142. }
  143. public void LateUpdate()
  144. {
  145. ViewLayout();
  146. //if (VRInputComponent.Instance.GetKeyDown(VRKey.侧卧, VRHand.右) && !isForbidden)
  147. //{
  148. // isHide = !isHide;
  149. // ViewStatus(isHide);
  150. //}
  151. SetNoticeView();
  152. }
  153. /// <summary> 页面位置布局 </summary>
  154. private void ViewLayout()
  155. {
  156. //正面布局
  157. if (FacadeComponent.Instance.GetController<ProgressPopController>() != null)
  158. {
  159. playerPos = Player.Inst.transform.position;
  160. float angle = Mathf.DeltaAngle(
  161. VRCameraRotY,
  162. Player.Inst.hmdTransform.localEulerAngles.y
  163. );
  164. float num = Mathf.Abs(angle) / limitAngle;
  165. if (num > 1)
  166. {
  167. VRCameraRotY += (int)num * 2 * limitAngle * Mathf.Sign(angle);
  168. if (VRCameraRotY > 360)
  169. {
  170. VRCameraRotY -= 360;
  171. }
  172. startDir =
  173. Quaternion.Euler(0, Mathf.Sign(angle) * 2 * limitAngle, 0) * startDir;
  174. uiRot = Quaternion.Euler(
  175. 70,
  176. GetUITranfrom().rotation.eulerAngles.y + 2 * limitAngle * Mathf.Sign(angle),
  177. 0
  178. );
  179. }
  180. else
  181. {
  182. if (startRotY != Player.Inst.transform.localEulerAngles.y)
  183. {
  184. GetUITranfrom().LookAt(playerPos);
  185. float angleValue = Mathf.DeltaAngle(
  186. startRotY,
  187. Player.Inst.transform.localEulerAngles.y
  188. );
  189. startDir = Quaternion.Euler(0, angleValue, 0) * startDir;
  190. float uiAngle = uiRot.eulerAngles.y + angleValue;
  191. if (uiAngle >= 180)
  192. {
  193. uiAngle -= 360;
  194. }
  195. uiRot = Quaternion.Euler(new Vector3(70, uiAngle, 0));
  196. startRotY = Player.Inst.transform.localEulerAngles.y;
  197. }
  198. else
  199. {
  200. uiRot = GetUITranfrom().localRotation;
  201. }
  202. }
  203. uiPos = startDir + playerPos;
  204. SetView(uiPos / canvasScale, uiRot);
  205. }
  206. }
  207. /// <summary> 流程结束回调 </summary>
  208. private void OnProcessCompletCallBack()
  209. {
  210. EndTeachController endTeach =
  211. FacadeComponent.Instance.CreateController<EndTeachController>();
  212. endTeach.OpenView();
  213. bool isReturnMain;
  214. if (
  215. GameManager.Instance.Data.Pattern == PatternType.教学
  216. || GameManager.Instance.Data.Pattern == PatternType.引导
  217. )
  218. {
  219. isReturnMain = true;
  220. }
  221. else
  222. {
  223. isReturnMain = false;
  224. }
  225. endTeach.SetViewMesg("检查以上操作无误,汇报操作完毕", false, isReturnMain);
  226. SceneDataSaveComponent.Instance.RestAllScene();
  227. CloseView();
  228. }
  229. /// <summary> 获取UI的Transform </summary>
  230. public Transform GetUITranfrom()
  231. {
  232. return _View.UIGameObject.transform;
  233. }
  234. /// <summary> 设置UI页面 </summary>
  235. public void SetView(Vector3 pos, Quaternion quaternion)
  236. {
  237. _View.SetPosition(pos, quaternion);
  238. }
  239. /// <summary>返回 </summary>
  240. public void ReturnBtnClick()
  241. {
  242. isForbidden = true;
  243. ViewStatus(isForbidden);
  244. EndTeachController endTeach =
  245. FacadeComponent.Instance.CreateController<EndTeachController>();
  246. endTeach.OpenView();
  247. bool isReturnMain;
  248. if (
  249. GameManager.Instance.Data.Pattern == PatternType.教学
  250. || GameManager.Instance.Data.Pattern == PatternType.引导
  251. )
  252. {
  253. isReturnMain = true;
  254. }
  255. else
  256. {
  257. isReturnMain = false;
  258. }
  259. endTeach.SetViewMesg(
  260. $"您还未完成操作{GameManager.Instance.Data.Pattern},现在退出不保留操作进度,是否确定退出",
  261. true,
  262. isReturnMain
  263. );
  264. }
  265. /// <summary> 设置进度栏显隐 </summary>
  266. public void ViewStatus(bool active)
  267. {
  268. _View.UIGameObject.SetActive(!active);
  269. }
  270. /// <summary> 手臂提示 </summary>
  271. private void SetNoticeView()
  272. {
  273. //Vector3 pos = Player.Inst.rightHand.transform.position / canvasScale;
  274. //Quaternion quaternion =
  275. // Player.Inst.rightHand.transform.rotation
  276. // * Quaternion.Euler(new Vector3(70, 0, 0));
  277. //noticeView.SetView(pos, quaternion);
  278. }
  279. /// <summary> 警告提示 </summary>
  280. public async void WarningHint()
  281. {
  282. _View.WarningHint.gameObject.SetActive(true);
  283. await TimerComponent.Instance.WaitAsync(1.5f);
  284. _View.WarningHint.gameObject.SetActive(false);
  285. }
  286. public async void TestJumpBtnClick()
  287. {
  288. int len = PlayerPrefs.GetInt("Test_Jump", 0);
  289. for (int i = 0; i < len; i++)
  290. {
  291. var isscne = processMgr.IsScene();
  292. await processMgr.NextProcess();
  293. if (isscne)
  294. {
  295. await TimerComponent.Instance.WaitAsync(1);
  296. }
  297. }
  298. }
  299. /// <summary> 上一步按钮 </summary>
  300. public async void LastBtnClick()
  301. {
  302. await processMgr.LastProcess();
  303. RefreshMessage(processMgr.GetCurrentModule().VTaskId - 1);
  304. }
  305. /// <summary>下一步按钮</summary>
  306. public async void NextBtnClick()
  307. {
  308. await processMgr.NextProcess();
  309. }
  310. /// <summary>提示按钮</summary>
  311. public void HintBtnClick()
  312. {
  313. _View.Message.gameObject.SetActive(true);
  314. currentTaskScore = 0;
  315. processMgr.GetCurrentModule().Prompt();
  316. }
  317. /// <summary> 刷新页面上的任务信息</summary>
  318. public void RefreshMessage(int taskId)
  319. {
  320. taskId += 1;
  321. WSTaskList record = _Model.WSTaskLists.Find(t => t.Id == taskId);
  322. if (record == null)
  323. {
  324. Log.LogError($"任务{taskId}为空");
  325. return;
  326. }
  327. currentTaskScore = processMgr.GetVTaskRecord(taskId).Score;
  328. _Model.Progress.Value =
  329. "大岗山10kV厂用电系统I段停电检修做措施"
  330. + $"(<size=32>{record.Id}</size>/{processMgr.GetAllVTaskRecord().Count})";
  331. switch (GameManager.Instance.Data.Pattern)
  332. {
  333. case PatternType.教学:
  334. _Model.Message.Value = record.Name.Replace(" ", "\u00A0").Replace("\\n", "\n");
  335. _View.LastBtn.interactable = (taskId == 1) ? false : true;
  336. _View.NextBtn.interactable =
  337. (taskId == processMgr.GetVTaskList().Count) ? false : true;
  338. _View.HintBtn.gameObject.SetActive(false);
  339. break;
  340. case PatternType.练习:
  341. _Model.Message.Value = record.Name.Replace(" ", "\u00A0").Replace("\\n", "\n");
  342. _View.Message.gameObject.SetActive(false);
  343. _View.LastBtn.gameObject.SetActive(false);
  344. _View.NextBtn.gameObject.SetActive(false);
  345. _View.HintBtn.gameObject.SetActive(true);
  346. break;
  347. case PatternType.考核:
  348. _View.LastBtn.gameObject.SetActive(false);
  349. _View.NextBtn.gameObject.SetActive(false);
  350. _View.HintBtn.gameObject.SetActive(false);
  351. break;
  352. }
  353. }
  354. /// <summary>
  355. /// 结果提示
  356. /// </summary>
  357. /// <param name="isSuccess">操作是否正确</param>
  358. public async UniTask ResultHint(bool isSuccess)
  359. {
  360. if (isSuccess)
  361. {
  362. GameManager.Instance.currentAllScore += currentTaskScore;
  363. }
  364. else
  365. {
  366. currentTaskScore = 0;
  367. }
  368. _View.SuccessIcon.gameObject.SetActive(isSuccess);
  369. _View.FailIcon.gameObject.SetActive(!isSuccess);
  370. await TimerComponent.Instance.WaitAsync(2);
  371. _View.SuccessIcon.gameObject.SetActive(false);
  372. _View.FailIcon.gameObject.SetActive(false);
  373. }
  374. }
  375. public class ProgressPopView : View
  376. {
  377. public InputField ifJump;
  378. public Button TestJumpBtn;
  379. public Button ReturnBtn;
  380. public Button LastBtn;
  381. public Button NextBtn;
  382. public Button HintBtn;
  383. public Text Progress;
  384. public Text Message;
  385. public Text WarningHint;
  386. public Image FailIcon;
  387. public Image SuccessIcon;
  388. public override void LoadInit()
  389. {
  390. ShowModeType = ViewShowModeType.World;
  391. ReferenceCollector rc = UIGameObject.GetComponent<ReferenceCollector>();
  392. ifJump = rc.GetComponent<InputField>("ifJump");
  393. ReturnBtn = rc.GetComponent<Button>("ReturnBtn");
  394. TestJumpBtn = rc.GetComponent<Button>("TestJumpBtn");
  395. LastBtn = rc.GetComponent<Button>("LastBtn");
  396. NextBtn = rc.GetComponent<Button>("NextBtn");
  397. HintBtn = rc.GetComponent<Button>("HintBtn");
  398. Progress = rc.GetComponent<Text>("Progress");
  399. Message = rc.GetComponent<Text>("Message");
  400. WarningHint = rc.GetComponent<Text>("WarningHint");
  401. FailIcon = rc.GetComponent<Image>("FailIcon");
  402. SuccessIcon = rc.GetComponent<Image>("SuccessIcon");
  403. }
  404. }
  405. public class ProgressPopModel : Model
  406. {
  407. public BindableProperty<string> Progress;
  408. public BindableProperty<string> Message;
  409. public BindableProperty<string> InputPassWord;
  410. /// <summary> 任务列表 </summary>
  411. public List<WSTaskList> WSTaskLists;
  412. /// <summary> 转头角度 </summary>
  413. public float angle = 90;
  414. public override void InitProperty()
  415. {
  416. Progress = CreateProperty<string>();
  417. Message = CreateProperty<string>();
  418. InputPassWord = CreateProperty<string>();
  419. }
  420. }
  421. }