using Assets.MyGame.Scripts.Net; using Assets.MyGame.Scripts.Net.API; using Assets.MyGame.Scripts.Net.APIResponses.Enum; using Assets.MyGame.Scripts.Net.WebResponses; using DG.Tweening; using Newtonsoft.Json; using Spine.Unity; using System; using System.Collections; using System.Collections.Generic; using System.Threading.Tasks; using TMPro; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.EventSystems; using UnityEngine.InputSystem; using UnityEngine.SceneManagement; using UnityEngine.UI; using static UnityEngine.AddressableAssets.Addressables; public class GameMainPanel_FishBase : GameMainPanel_Base { [Header("游戏场景")] public string sceneName; public GameTypeEnum gameType; [Header("设置")] protected bool isOpenSetting; public Button btn_SettingList; public Transform SittingListParent; [Header("我在这")] public GameObject mySitAnim; [Header("Skill")] public Dictionary dic_Skill_Toggle = new Dictionary();//开关型技能 public Toggle toggle_SkillAuto; public Toggle toggle_Lock; public Toggle toggle_Three; public Toggle toggle_Shuang; public List list_Sits = new List(); public SitPosData currSitData; [Header("攻击参数")] public float attackTime = 0.5f; float clickTime = 0; public GameObject bullet_Test; public GameObject bulletParent; float changeTurretTime = 0f; bool isChangingTurret = false; int bulletCount = 0; public GameObject boardCast_Boss; AudioClip bulletClip; public async override void Awake() { base.Awake(); EventCenter.Instance.AddEventListener(ConstEventString.SyncGameData_Rotate, SyncGameData_Rotate); EventCenter.Instance.AddEventListener(ConstEventString.SyncGameData_FireBullet, SyncGameData_FireBullit); EventCenter.Instance.AddEventListener(ConstEventString.SyncGameData_ChangeTargetMonster, SyncGameData_ChangeTargetMonster); EventCenter.Instance.AddEventListener(ConstEventString.SyncGameData_RendromDieFish, SyncGameData_RendromDieFish); subUIManager.boardCast_Boss = boardCast_Boss; FishResourcesData.LoadFishAssetsData(); MonsterMoveLine.LoadBezier();//初始化加载路线 AudioResourcesData.LoadAudioGame(); await Addressables.LoadAssetsAsync("Audio", clip => { Debug.Log("clipName" + clip.name); if (clip.name == "PW_Shoot") { bulletClip = clip; } }).Task; } public virtual void OnDestroy() { EventCenter.Instance.RemoveEventListener(ConstEventString.SyncGameData_Rotate, SyncGameData_Rotate); EventCenter.Instance.RemoveEventListener(ConstEventString.SyncGameData_FireBullet, SyncGameData_FireBullit); EventCenter.Instance.RemoveEventListener(ConstEventString.SyncGameData_ChangeTargetMonster, SyncGameData_ChangeTargetMonster); EventCenter.Instance.RemoveEventListener(ConstEventString.SyncGameData_RendromDieFish, SyncGameData_RendromDieFish); } public virtual void Start() { btn_SettingList.onClick.AddListener(() => { if (isOpenSetting) { StartCoroutine(CloseSettingList()); } else { StartCoroutine(OpenSettingList()); } }); if (toggle_Lock != null) toggle_Lock.onValueChanged.AddListener((a) => { if (!a) { { SyncGameData sgd = new SyncGameData { sitPos = currSitData.posID, frameType = FrameDataType.changeAutoTarget, time = BeijingTimeManager.Instance.CurrentTimestampMs, frameData = new FrameData_ChangeAutoTarget { targetGuid = null, } }; WebSocketSendList.SyncGameData(sgd); } } }); CreateFishManager.Instance.EnterRoom(gameType); } public void TuiChuHHWK() { UIManager.Instance.Close(UIPanel.MainGamePanelHHWK); //等待界面添加 UIManager.Instance.ShowAsync(UIPanel.HomeMainPanel, UIPanel.MainGamePanelHHWK); } public virtual void Update() { if (bulletCount >= 100) { SendBullet(); } if (Touchscreen.current?.primaryTouch != null) { if (Touchscreen.current.primaryTouch.press.wasPressedThisFrame) { clickTime = attackTime; if (mySitAnim.gameObject.activeSelf) { mySitAnim.gameObject.SetActive(false); } } #region 换炮台 //Change Turret if (Touchscreen.current.primaryTouch.press.wasPressedThisFrame) { PointerEventData pointerData = new PointerEventData(EventSystem.current); pointerData.position = Touchscreen.current.primaryTouch.position.ReadValue(); List results = new List(); EventSystem.current.RaycastAll(pointerData, results); foreach (RaycastResult result in results) { if (result.gameObject.tag == "ChangeTurret") { if (result.gameObject.GetComponentInParent() == currSitData) { isChangingTurret = true; return; } } } } if (Touchscreen.current.primaryTouch.press.isPressed) { if (isChangingTurret) { changeTurretTime += Time.deltaTime; if (changeTurretTime > 1f) { if (!currSitData.changeTurretList.activeSelf) { //切换炮台面板 currSitData.changeTurretList.SetActive(true); } } return; } } if (Touchscreen.current.primaryTouch.press.wasReleasedThisFrame) { if (isChangingTurret) { changeTurretTime = 0; isChangingTurret = false; return; } } #endregion #region 锁定 foreach (var item in list_Sits) { if (item.isLock) { if (item.monCotl_Lock == null) { CancelLock(item); item.isLock = false; } else { if (!item.lockFX.gameObject.activeSelf) { item.lockFX.gameObject.SetActive(true); } Vector2 v2 = item.monCotl_Lock.transform.position; item.lockFX.transform.position = v2; //FireBullit(); } } } #endregion foreach (var item in list_Sits) { if (item.monCotl_Lock != null) { SetSitRotate(item); Vector2 v2 = item.monCotl_Lock.transform.position; item.lockFX.transform.position = v2; //FireBullit(); } else { CancelLock(item); } } if (toggle_Lock.isOn) { //发射射线检测 //发射完成后根据要求已有的子弹拐弯 //射线检测 if (Touchscreen.current.primaryTouch.press.wasPressedThisFrame) { Vector2 worldPos = Camera.main.ScreenToWorldPoint(Touchscreen.current.primaryTouch.position.ReadValue()); RaycastHit2D hit = Physics2D.Raycast(worldPos, Vector2.zero, 50, LayerMask.GetMask("Fish")); currSitData.monCotl_Lock = hit.transform?.GetComponentInParent(); if (currSitData.monCotl_Lock != null && currSitData.monCotl_Lock.gameObject.activeSelf) //这里为之后加对象池铺垫 { foreach (BullitMove item in bulletParent.GetComponentsInChildren()) { item.Lock(currSitData.monCotl_Lock); } { SyncGameData sgd = new SyncGameData { sitPos = currSitData.posID, frameType = FrameDataType.changeAutoTarget, time = BeijingTimeManager.Instance.CurrentTimestampMs, frameData = new FrameData_ChangeAutoTarget { targetGuid = currSitData.monCotl_Lock.guid, } }; WebSocketSendList.SyncGameData(sgd); } if (!currSitData.lockFX.activeSelf) { currSitData.lockFX.SetActive(true); } } else //没有射到目标取消显示fx { { SyncGameData sgd = new SyncGameData { sitPos = currSitData.posID, frameType = FrameDataType.changeAutoTarget, time = BeijingTimeManager.Instance.CurrentTimestampMs, frameData = new FrameData_ChangeAutoTarget { targetGuid = null, } }; WebSocketSendList.SyncGameData(sgd); } CancelLock(); } } //这里锁定的旋转有问题 //if (currSitData.monCotl_Lock != null) //{ // SelfPaoTaRotate(); // LockFX.transform.position = currSitData.monCotl_Lock.transform.position; // //FireBullit(); //} } else { if (Touchscreen.current.primaryTouch.press.isPressed) { //FireBullit(); if (!toggle_SkillAuto.isOn) { SelfPaoTaRotate(); } } } if (Touchscreen.current.primaryTouch.press.wasReleasedThisFrame) { SendBullet(); } } if (toggle_SkillAuto.isOn && toggle_Lock.isOn == false) { SelfPaoTaRotate(); } } public void JoinGame(int sitNum, long goldNum, long consumeGlod, int currentTurretID, string user = null) { foreach (var item in list_Sits) { if (item.posID == sitNum) { item.gameObject.SetActive(true); if (user == null) { user = GameManager.Instance.user.id; } item.user = user; item.goldNum = goldNum; item.consumeGoldNum = consumeGlod; item.tMP_GoldNum.text = goldNum.ToString(); item.ChangeTurret(currentTurretID); item.tMP_TurretConsumeNum.text = consumeGlod.ToString(); } } } #region 打开关闭右上角设置选项 public virtual IEnumerator OpenSettingList() { RectTransform tran = SittingListParent.GetComponent(); tran.gameObject.SetActive(true); tran.DOSizeDelta(new Vector2(466, 143), 0.2f); isOpenSetting = true; Vector3 v3 = btn_SettingList.transform.localScale; v3.x = Mathf.Abs(v3.x) * -1; btn_SettingList.transform.localScale = v3; yield break; } public virtual IEnumerator CloseSettingList() { RectTransform tran = SittingListParent.GetComponent(); Vector3 v3 = btn_SettingList.transform.localScale; v3.x = Mathf.Abs(v3.x); btn_SettingList.transform.localScale = v3; tran.DOSizeDelta(new Vector2(0, 143), 0.2f).OnComplete(() => { tran.gameObject.SetActive(false); }); isOpenSetting = false; yield break; } #endregion private void SendBullet() { //if (bulletCount > 0) // WebSocketSendList.ShootBullet(GameManager.Instance.gameData.currRoomData.roomId, currSitData.user.id, currSitData.consumeGlodNum, bulletCount); bulletCount = 0; } private void SelfPaoTaRotate() { #region 计算点击方向 Vector2 touchPos; // 获取触摸位置(屏幕坐标) touchPos = Touchscreen.current.primaryTouch.position.ReadValue(); // 转换Canvas坐标 Vector2 worldPos; RectTransformUtility.ScreenPointToLocalPointInRectangle(currSitData.tra_CurrTurret.transform.parent as RectTransform, touchPos, null, out worldPos); // 计算方向 Vector2 dir = worldPos - currSitData.tra_CurrTurret.GetComponent().anchoredPosition; // 计算角度 float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg - 90f; SetSitTurretRotame(currSitData, angle); } private void SetSitRotate(SitPosData sitPosData) { if (sitPosData.monCotl_Lock != null) { Vector2 touchPos = Camera.main.WorldToScreenPoint(sitPosData.monCotl_Lock.transform.position); // 转换Canvas坐标 Vector2 worldPos; RectTransformUtility.ScreenPointToLocalPointInRectangle(sitPosData.tra_CurrTurret.transform.parent as RectTransform, touchPos, null, out worldPos); // 计算方向 Vector2 dir = worldPos - sitPosData.tra_CurrTurret.GetComponent().anchoredPosition; // 计算角度 float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg - 90f; SetSitTurretRotame(sitPosData, angle); } } public void SyncGameData_Rotate(SyncGameData syncGameData) { if (syncGameData.sitPos != currSitData.posID) { var rotateData = JsonConvert.DeserializeObject(syncGameData.frameData.ToString()); SetSitTurretRotame(list_Sits[syncGameData.sitPos], rotateData.angle, false); } } float frameTime = 0; //IEnumerator RotateIE(SitPosData sitPosData, Quaternion qua) //{ // while (true) // { // yield return null; // sitPosData.tra_CurrTurret.transform.rotation =Quaternion.Lerp(sitPosData.tra_CurrTurret.transform.rotation,qua,0.6f); // } //} IEnumerator RotateIE_Angle(SitPosData sitPosData, Quaternion qua) { // 设置一个较小的阈值,判断是否旋转到位 float angleThreshold = 0.1f; // 当角度差小于0.1度时停止 while (true) { // 计算当前旋转和目标旋转之间的角度差 float angleDifference = Quaternion.Angle(sitPosData.tra_CurrTurret.transform.rotation, qua); // 如果角度差很小,认为旋转完成 if (angleDifference <= angleThreshold) { // 强制设置最终旋转,避免微小误差 sitPosData.tra_CurrTurret.transform.rotation = qua; break; // 退出循环 } // 执行旋转插值 sitPosData.tra_CurrTurret.transform.rotation = Quaternion.Lerp( sitPosData.tra_CurrTurret.transform.rotation, qua, 0.6f // 这个系数决定了旋转速度 ); yield return null; // 等待下一帧 } Debug.Log("旋转完成"); } IEnumerator RotateIE_Time(SitPosData sitPosData, Quaternion qua) { float rotateDuration = 0.3f; // 旋转持续时间 float elapsedTime = 0f; Quaternion startRotation = sitPosData.tra_CurrTurret.transform.rotation; while (elapsedTime < rotateDuration) { elapsedTime += Time.deltaTime; float t = elapsedTime / rotateDuration; // 使用Slerp进行更平滑的球面插值 sitPosData.tra_CurrTurret.transform.rotation = Quaternion.Slerp( startRotation, qua, t ); yield return null; } // 确保最终旋转精确 sitPosData.tra_CurrTurret.transform.rotation = qua; } private Coroutine currentRotateCoroutine; private void SetSitTurretRotame(SitPosData sitPosData, float angle, bool isSelf = true) { if (isSelf == false) { Vector3 v3 = Vector3.forward * angle; // 如果已有协程在运行,先停止它 if (currentRotateCoroutine != null) { StopCoroutine(currentRotateCoroutine); currentRotateCoroutine = null; } // 启动新的协程并保存引用 currentRotateCoroutine = StartCoroutine(RotateIE_Angle(sitPosData, Quaternion.Euler(v3))); //StartCoroutine(RotateIE(sitPosData,)); return; } else { sitPosData.tra_CurrTurret.transform.rotation = Quaternion.Euler(Vector3.forward * angle); frameTime += Time.deltaTime; if (frameTime > 0.1f) { { SyncGameData sgd = new SyncGameData { sitPos = currSitData.posID, frameType = FrameDataType.rotateTurrect, time = BeijingTimeManager.Instance.CurrentTimestampMs, frameData = new FrameData_Rotate { angle = angle, } }; WebSocketSendList.SyncGameData(sgd); } } } #endregion clickTime += Time.deltaTime; if (clickTime > attackTime) { clickTime = 0; } else { return; } FireBullit(currSitData, angle, toggle_Three.isOn, toggle_SkillAuto.isOn, toggle_Lock.isOn, toggle_Shuang.isOn); { SyncGameData sgd = new SyncGameData { sitPos = currSitData.posID, frameType = FrameDataType.fireBullet, time = BeijingTimeManager.Instance.CurrentTimestampMs, frameData = new FrameData_FireBullit { angle = angle, gold = currSitData.goldNum, isSanShe = toggle_Three.isOn, twoRTruuect = toggle_Shuang.isOn, isSuoDing = toggle_Lock.isOn, auto = toggle_SkillAuto.isOn } }; WebSocketSendList.SyncGameData(sgd); } } private void CancelLock(SitPosData posData) { posData.monCotl_Lock = null; posData.lockFX.gameObject.SetActive(false); } private void CancelLock() { currSitData.monCotl_Lock = null; currSitData.lockFX.gameObject.SetActive(false); } public void SyncGameData_FireBullit(SyncGameData syncGameData) { if (syncGameData.sitPos != currSitData.posID) { var fireBullet = JsonConvert.DeserializeObject(syncGameData.frameData.ToString()); FireBullit(list_Sits[syncGameData.sitPos], fireBullet.angle, fireBullet.isSanShe, fireBullet.auto, fireBullet.isSuoDing, fireBullet.twoRTruuect, false); } } public void SyncGameData_ChangeTargetMonster(SyncGameData syncGameData) { if (syncGameData.sitPos != currSitData.posID) { var fireBullet = JsonConvert.DeserializeObject(syncGameData.frameData.ToString()); list_Sits[syncGameData.sitPos].monCotl_Lock = CreateFishManager.Instance.fishDatas_hashCodekey[fireBullet.targetGuid]; list_Sits[syncGameData.sitPos].isLock = true; } } public void SyncGameData_RendromDieFish(SyncGameData syncGameData) { var fireBullet = JsonConvert.DeserializeObject(syncGameData.frameData.ToString()); CreateFishManager.Instance.Id_DieListFish_FX(fireBullet.guids, fireBullet.coinNum, new Vector3(fireBullet.x, fireBullet.y, fireBullet.z)); } private async Task FireBullit(SitPosData sitPosData, float angle, bool isSanShe, bool auto, bool isSuoDing, bool twoRTruuect, bool isSelf = true) { //计算方向 Vector2 startV2; startV2 = CoordinateTransformation.AnchoredPos_ToCanvas(sitPosData.currentTurret.tra_BulletStartPosition.GetComponent(), UIManager.Instance.uiRoot.GetComponent()); startV2 = CoordinateTransformation.CanvasToWorld(startV2, UIManager.Instance.uiRoot.GetComponent(), Camera.main); //Vector2 endV2 = touchPos; //var vectorTarget = endV2 - startV2; //var a = Mathf.Atan2(vectorTarget.y, vectorTarget.x) * Mathf.Rad2Deg; //obj_CurrTurret.GetComponent() if (isSanShe) { BullitMove bulletMove1 = CreateBullet(angle - 20, startV2, sitPosData, Guid.NewGuid().ToString(), twoRTruuect); BullitMove bulletMove2 = CreateBullet(angle, startV2, sitPosData, Guid.NewGuid().ToString(), twoRTruuect); BullitMove bulletMove3 = CreateBullet(angle + 20, startV2, sitPosData, Guid.NewGuid().ToString(), twoRTruuect); if (isSuoDing) { bulletMove1?.Lock(sitPosData.monCotl_Lock); bulletMove2?.Lock(sitPosData.monCotl_Lock); bulletMove3?.Lock(sitPosData.monCotl_Lock); } } else { BullitMove bulletMove = CreateBullet(angle, startV2, sitPosData, Guid.NewGuid().ToString(), twoRTruuect); if (isSuoDing) { bulletMove?.Lock(sitPosData.monCotl_Lock); } } AudioManager.Instance.PlayFX(bulletClip); } public string turretAttack; private BullitMove CreateBullet(float angle, Vector2 startV2, SitPosData roomJoinNotice, string guid, bool twoRTruuect) { GameObject bulletPrefab; //这里有双倍炮台的需求 if (twoRTruuect) { bulletPrefab = roomJoinNotice.currentTurret.bulletPrefab_Two; if (!roomJoinNotice.ConsumeGold(2)) { return null; } } else { bulletPrefab = roomJoinNotice.currentTurret.bulletPrefab; if (!roomJoinNotice.ConsumeGold()) { return null; } } var bulletMove = Instantiate(bulletPrefab, startV2, Quaternion.Euler(Vector3.forward * angle), bulletParent.transform).GetComponent(); bulletMove.userid = roomJoinNotice.user; bulletMove.playerID = roomJoinNotice.user; bulletMove.bulletID = guid; if (roomJoinNotice.skeletonAnimation != null) { roomJoinNotice.skeletonAnimation.AnimationState.SetAnimation(0, turretAttack, false); } if (roomJoinNotice.old_CurrAnimation != null) { roomJoinNotice.old_CurrAnimation.Play(turretAttack); } bulletCount++; return bulletMove; } bool isfirstShow = true; protected override void OnShow(object args = null) { base.OnShow(args); //UIManager.Instance.ShowBoard("太好看了"); var v = JsonConvert.DeserializeObject>(args.ToString()); if (v.arguments.Count > 0) { RoomJoinNotice roomJoinNotice = v.arguments[0]; if (isfirstShow) { foreach (var item in GameManager.Instance.gameData.currRoomData.players) { JoinGame(item.position, item.gold, item.cannonMultiple, 0, item.userId); } GameManager.Instance.gameData.roomJoinNotice = v.arguments[0]; isfirstShow = false; currSitData = list_Sits[roomJoinNotice.position]; //currSitData.ChangeTurret(1); currSitData.lockFX.transform.GetChild(0).gameObject.SetActive(false); currSitData.lockFX.transform.GetChild(1).gameObject.SetActive(true); mySitAnim.GetComponent().anchoredPosition = currSitData.currentTurret.GetComponent().anchoredPosition; } else { JoinGame(roomJoinNotice.position, roomJoinNotice.gold, roomJoinNotice.cannonMultiple, 0, roomJoinNotice.userId); } } else { UIManager.Instance.ShowBoardError("获取信息失败"); } } protected override void OnHide() { base.OnHide(); WebSocketSendList.LeaveRoom(GameManager.Instance.gameData.currRoomData.roomId, currSitData.user); CreateFishManager.Instance.ExitRoom(); SceneManager.UnloadSceneAsync(sceneName); WebSocketManager.Instance.Close(SocketType.game); } }