using Cysharp.Threading.Tasks; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; namespace WS { [ObjectSystem] public class ProgressPopControllerUpdateSystem : UpdateSystem { public override void Update(ProgressPopController self) { //self.LateUpdate(); ////侧面布局 //if (FacadeComponent.Instance.GetController() != null) //{ // self.playerPos = Player.instance.transform.position; // float angle = Mathf.DeltaAngle(self.VRCameraRotY, Player.instance.hmdTransform.localEulerAngles.y); // float num = Mathf.Abs(angle) / self.angle; // if (num > 1) // { // self.VRCameraRotY += (int)num * 2 * self.angle * Mathf.Sign(angle); // if (self.VRCameraRotY > 360) // { // self.VRCameraRotY -= 360; // } // Vector3 uiToPlayer = self.GetUITranfrom().position - self.playerPos; // self.startDir = Quaternion.Euler(0, Mathf.Sign(angle) * 2 * self.angle, 0) * uiToPlayer; // self.uiRot = Quaternion.Euler(0, self.GetUITranfrom().rotation.eulerAngles.y + 2 * self.angle * Mathf.Sign(angle), 0); // } // else // { // if (self.startRotY != Player.instance.transform.localEulerAngles.y) // { // self.GetUITranfrom().LookAt(self.playerPos); // float angleValue = Mathf.DeltaAngle(self.startRotY, Player.instance.transform.localEulerAngles.y); // self.startDir = Quaternion.Euler(0, angleValue, 0) * self.startDir; // float uiAngle = self.uiRot.eulerAngles.y + angleValue; // if (uiAngle >= 180) // { // uiAngle -= 360; // } // self.uiRot = Quaternion.Euler(new Vector3(0, uiAngle, 0)); // self.startRotY = Player.instance.transform.localEulerAngles.y; // } // else // { // self.uiRot = self.GetUITranfrom().localRotation; // } // } // self.uiPos = self.startDir + self.playerPos; // self.SetView(self.uiPos / self.canvasScale, self.uiRot); //} } } [ObjectSystem] public class ProgressPopControllerLateUpdateSystem : LateUpdateSystem { public override void LateUpdate(ProgressPopController self) { self.LateUpdate(); } } public class ProgressPopController : Controller { ProcessManager processMgr; /// 限制角度 public float limitAngle = 90; /// VR相机Y轴旋转 public float VRCameraRotY; /// Y轴距离 public float uiDistanceY = 500; /// Z轴距离 public float uiDistanceZ = 800; /// ui到玩家的向量 public Vector3 startDir; /// UI位置 public Vector3 uiPos; /// UI旋转 public Quaternion uiRot; /// 画布缩放(用于计算世界坐标) public float canvasScale = 0.001f; /// 玩家位置 public Vector3 playerPos; /// 玩家初始旋转 public float startRotY; /// UI页面是否隐藏 public bool isHide; /// 页面禁用 public bool isForbidden = false; /// 快捷键提示页 //private NoticeViewController noticeView; /// 当前任务分数 public float currentTaskScore; protected override void BindingViewModel() { //_Model.Bind(_View.ifJump, _Model.InputPassWord, (a) => //{ // if (int.TryParse(a, out int r)) // { // PlayerPrefs.SetInt("Test_Jump", r); // string str = $"增加{r}步"; // _View.TestJumpBtn.GetComponentInChildren().text = str; // } //}); _Model.Bind(_View.TestJumpBtn, TestJumpBtnClick); _Model.Bind(_View.ReturnBtn, ReturnBtnClick); _Model.Bind(_View.LastBtn, LastBtnClick); _Model.Bind(_View.NextBtn, NextBtnClick); _Model.Bind(_View.HintBtn, HintBtnClick); _Model.Bind(_View.Progress, _Model.Progress); _Model.Bind(_View.Message, _Model.Message); } public override void OpenView() { base.OpenView(); isHide = false; isForbidden = false; //noticeView = FacadeComponent.Instance.CreateController(); //noticeView.OpenView(); processMgr = GameManager.Instance.ProcessManager; _Model.WSTaskLists = processMgr.GetVTaskList(); RefreshMessage(0); processMgr.OnCompleteVTaskCallback += RefreshMessage; processMgr.OnEndProcessCallback += OnProcessCompletCallBack; currentTaskScore = processMgr.GetVTask(processMgr.GetCurrentModule().VTaskId).Score; VRCameraRotY = 0; startRotY = 0; var playerPos = Player.Inst.transform.position; uiPos = playerPos / canvasScale + new Vector3(0, uiDistanceY, uiDistanceZ); var Z = Player.Inst.transform.forward * uiDistanceZ; var Y = Player.Inst.transform.up * uiDistanceY; uiRot = Quaternion.Euler(new Vector3(70, 0, 0)); _View.SetPosition(uiPos, uiRot); startDir = _View.UIGameObject.transform.position - playerPos; } public override void Dispose() { processMgr.OnCompleteVTaskCallback -= RefreshMessage; processMgr.OnEndProcessCallback -= OnProcessCompletCallBack; //noticeView?.CloseView(); base.Dispose(); } public void LateUpdate() { ViewLayout(); //if (VRInputComponent.Instance.GetKeyDown(VRKey.侧卧, VRHand.右) && !isForbidden) //{ // isHide = !isHide; // ViewStatus(isHide); //} SetNoticeView(); } /// 页面位置布局 private void ViewLayout() { //正面布局 if (FacadeComponent.Instance.GetController() != null) { playerPos = Player.Inst.transform.position; float angle = Mathf.DeltaAngle( VRCameraRotY, Player.Inst.hmdTransform.localEulerAngles.y ); float num = Mathf.Abs(angle) / limitAngle; if (num > 1) { VRCameraRotY += (int)num * 2 * limitAngle * Mathf.Sign(angle); if (VRCameraRotY > 360) { VRCameraRotY -= 360; } startDir = Quaternion.Euler(0, Mathf.Sign(angle) * 2 * limitAngle, 0) * startDir; uiRot = Quaternion.Euler( 70, GetUITranfrom().rotation.eulerAngles.y + 2 * limitAngle * Mathf.Sign(angle), 0 ); } else { if (startRotY != Player.Inst.transform.localEulerAngles.y) { GetUITranfrom().LookAt(playerPos); float angleValue = Mathf.DeltaAngle( startRotY, Player.Inst.transform.localEulerAngles.y ); startDir = Quaternion.Euler(0, angleValue, 0) * startDir; float uiAngle = uiRot.eulerAngles.y + angleValue; if (uiAngle >= 180) { uiAngle -= 360; } uiRot = Quaternion.Euler(new Vector3(70, uiAngle, 0)); startRotY = Player.Inst.transform.localEulerAngles.y; } else { uiRot = GetUITranfrom().localRotation; } } uiPos = startDir + playerPos; SetView(uiPos / canvasScale, uiRot); } } /// 流程结束回调 private void OnProcessCompletCallBack() { EndTeachController endTeach = FacadeComponent.Instance.CreateController(); endTeach.OpenView(); bool isReturnMain; if ( GameManager.Instance.Data.Pattern == PatternType.教学 || GameManager.Instance.Data.Pattern == PatternType.引导 ) { isReturnMain = true; } else { isReturnMain = false; } endTeach.SetViewMesg("检查以上操作无误,汇报操作完毕", false, isReturnMain); SceneDataSaveComponent.Instance.RestAllScene(); CloseView(); } /// 获取UI的Transform public Transform GetUITranfrom() { return _View.UIGameObject.transform; } /// 设置UI页面 public void SetView(Vector3 pos, Quaternion quaternion) { _View.SetPosition(pos, quaternion); } /// 返回 public void ReturnBtnClick() { isForbidden = true; ViewStatus(isForbidden); EndTeachController endTeach = FacadeComponent.Instance.CreateController(); endTeach.OpenView(); bool isReturnMain; if ( GameManager.Instance.Data.Pattern == PatternType.教学 || GameManager.Instance.Data.Pattern == PatternType.引导 ) { isReturnMain = true; } else { isReturnMain = false; } endTeach.SetViewMesg( $"您还未完成操作{GameManager.Instance.Data.Pattern},现在退出不保留操作进度,是否确定退出", true, isReturnMain ); } /// 设置进度栏显隐 public void ViewStatus(bool active) { _View.UIGameObject.SetActive(!active); } /// 手臂提示 private void SetNoticeView() { //Vector3 pos = Player.Inst.rightHand.transform.position / canvasScale; //Quaternion quaternion = // Player.Inst.rightHand.transform.rotation // * Quaternion.Euler(new Vector3(70, 0, 0)); //noticeView.SetView(pos, quaternion); } /// 警告提示 public async void WarningHint() { _View.WarningHint.gameObject.SetActive(true); await TimerComponent.Instance.WaitAsync(1.5f); _View.WarningHint.gameObject.SetActive(false); } public async void TestJumpBtnClick() { int len = PlayerPrefs.GetInt("Test_Jump", 0); for (int i = 0; i < len; i++) { var isscne = processMgr.IsScene(); await processMgr.NextProcess(); if (isscne) { await TimerComponent.Instance.WaitAsync(1); } } } /// 上一步按钮 public async void LastBtnClick() { await processMgr.LastProcess(); RefreshMessage(processMgr.GetCurrentModule().VTaskId - 1); } /// 下一步按钮 public async void NextBtnClick() { await processMgr.NextProcess(); } /// 提示按钮 public void HintBtnClick() { _View.Message.gameObject.SetActive(true); currentTaskScore = 0; processMgr.GetCurrentModule().Prompt(); } /// 刷新页面上的任务信息 public void RefreshMessage(int taskId) { taskId += 1; WSTaskList record = _Model.WSTaskLists.Find(t => t.Id == taskId); if (record == null) { Log.LogError($"任务{taskId}为空"); return; } currentTaskScore = processMgr.GetVTaskRecord(taskId).Score; _Model.Progress.Value = "大岗山10kV厂用电系统I段停电检修做措施" + $"({record.Id}/{processMgr.GetAllVTaskRecord().Count})"; switch (GameManager.Instance.Data.Pattern) { case PatternType.教学: _Model.Message.Value = record.Name.Replace(" ", "\u00A0").Replace("\\n", "\n"); _View.LastBtn.interactable = (taskId == 1) ? false : true; _View.NextBtn.interactable = (taskId == processMgr.GetVTaskList().Count) ? false : true; _View.HintBtn.gameObject.SetActive(false); break; case PatternType.练习: _Model.Message.Value = record.Name.Replace(" ", "\u00A0").Replace("\\n", "\n"); _View.Message.gameObject.SetActive(false); _View.LastBtn.gameObject.SetActive(false); _View.NextBtn.gameObject.SetActive(false); _View.HintBtn.gameObject.SetActive(true); break; case PatternType.考核: _View.LastBtn.gameObject.SetActive(false); _View.NextBtn.gameObject.SetActive(false); _View.HintBtn.gameObject.SetActive(false); break; } } /// /// 结果提示 /// /// 操作是否正确 public async UniTask ResultHint(bool isSuccess) { if (isSuccess) { GameManager.Instance.currentAllScore += currentTaskScore; } else { currentTaskScore = 0; } _View.SuccessIcon.gameObject.SetActive(isSuccess); _View.FailIcon.gameObject.SetActive(!isSuccess); await TimerComponent.Instance.WaitAsync(2); _View.SuccessIcon.gameObject.SetActive(false); _View.FailIcon.gameObject.SetActive(false); } } public class ProgressPopView : View { public InputField ifJump; public Button TestJumpBtn; public Button ReturnBtn; public Button LastBtn; public Button NextBtn; public Button HintBtn; public Text Progress; public Text Message; public Text WarningHint; public Image FailIcon; public Image SuccessIcon; public override void LoadInit() { ShowModeType = ViewShowModeType.World; ReferenceCollector rc = UIGameObject.GetComponent(); ifJump = rc.GetComponent("ifJump"); ReturnBtn = rc.GetComponent