using Core.Input; using TowerDefense.UI; using TowerDefense.UI.HUD; using UnityEngine; using UnityInput = UnityEngine.Input; using State = TowerDefense.UI.HUD.EndlessGameUI.State; using KTGMGemClient; namespace TowerDefense.Input { [RequireComponent(typeof(EndlessGameUI))] public class EndlessTowerDefenseTouchInput : TouchInput { /// /// A percentage of the screen where panning occurs while dragging /// [Range(0, 0.5f)] public float panAreaScreenPercentage = 0.2f; /// /// The object that holds the confirmation buttons /// public MovingCanvas confirmationButtons; /// /// 是否处于拖动状态。 /// protected bool isInDragState = false; /// /// The object that holds the invalid selection /// public MovingCanvas invalidButtons; /// /// The attached Game UI object /// EndlessGameUI m_GameUI; /// /// Keeps track of whether or not the ghost tower is selected /// bool m_IsGhostSelected; /// /// The pointer at the edge of the screen /// TouchInfo m_DragPointer; /// /// Called by the confirm button on the UI /// public void OnTowerPlacementConfirmation() { confirmationButtons.canvasEnabled = false; if (!m_GameUI.IsGhostAtValidPosition()) { return; } m_GameUI.BuyTower(); } /// /// Called by the close button on the UI /// public void Cancel() { EndlessGameUI.instance.CancelGhostPlacement(); confirmationButtons.canvasEnabled = false; invalidButtons.canvasEnabled = false; } /// /// Register input events /// protected override void OnEnable() { base.OnEnable(); m_GameUI = GetComponent(); m_GameUI.stateChanged += OnStateChanged; m_GameUI.ghostBecameValid += OnGhostBecameValid; // Register tap event if (InputController.instanceExists) { InputController.instance.tapped += OnTap; InputController.instance.pressed += OnPressed; InputController.instance.startedDrag += OnStartDrag; } // disable pop ups if (confirmationButtons != null) { confirmationButtons.canvasEnabled = false; invalidButtons.canvasEnabled = false; } } /// /// Deregister input events /// protected override void OnDisable() { base.OnDisable(); if (confirmationButtons != null) { confirmationButtons.canvasEnabled = false; } if (invalidButtons != null) { invalidButtons.canvasEnabled = false; } if (InputController.instanceExists) { InputController.instance.tapped -= OnTap; InputController.instance.pressed -= OnPressed; InputController.instance.startedDrag -= OnStartDrag; } if (m_GameUI != null) { m_GameUI.stateChanged -= OnStateChanged; m_GameUI.ghostBecameValid -= OnGhostBecameValid; } } private void OnPressed(PointerActionInfo pointer) { m_GameUI.OnPressed(pointer); } /// /// Hide UI /// protected virtual void Awake() { if (confirmationButtons != null) { confirmationButtons.canvasEnabled = false; } if (invalidButtons != null) { invalidButtons.canvasEnabled = false; } } /// /// Decay flick /// protected override void Update() { base.Update(); // Edge pan if (m_DragPointer != null) { EdgePan(); } if (UnityInput.GetKeyDown(KeyCode.Escape)) { switch (m_GameUI.state) { case State.Normal: if (m_GameUI.isTowerSelected) { m_GameUI.DeselectTower(); } else { m_GameUI.Pause(); } break; case State.Building: m_GameUI.CancelGhostPlacement(); break; } } if (isRelease) { resetDragingTime += Time.deltaTime; if (resetDragingTime > 0.2f) { isRelease = false; resetDragingTime = 0; ResetDraging(); } } } /// /// Called on input press /// protected override void OnPress(PointerActionInfo pointer) { base.OnPress(pointer); var touchInfo = pointer as TouchInfo; // Press starts on a ghost? Then we can pick it up if (touchInfo != null) { if (m_GameUI.state == State.Building) { m_IsGhostSelected = m_GameUI.IsPointerOverGhost(pointer); if (m_IsGhostSelected) { m_DragPointer = touchInfo; } } } } float currentTimeScale = 1.0f; bool isRelease = false; float resetDragingTime; /// /// Called on input release, for flicks /// protected override void OnRelease(PointerActionInfo pointer) { //Debug.Log($"OnRelease isDraging:{isDraging} this.isInDragState:{this.isInDragState}"); //按照鼠标键盘的修改 // EndDrag 只能放置相关的GhostTower. if (isDraging) { if (this.isInDragState) { EndlessUIStart.instance.SetDarkGround(false); AudioSourceManager.Ins.Play(AudioEnum.PutTower); m_GameUI.CloseCanPlace();//关闭所有绿色底板 m_GameUI.CloseCanPlaceRenderer();//关闭所有宝石示意 m_GameUI.onEndTowerDrag(pointer); this.isInDragState = false; if (!GameConfig.IsNewbie) Time.timeScale = currentTimeScale; } Debug.Log($"延迟0.2f执行ResetDraging isDraging:{isDraging} isRelease:{isRelease}"); //Invoke("ResetDraging", 0.2f); if (!isRelease) { //Debug.Log("开始倒计时"); resetDragingTime = 0.0f; isRelease = true; } } } private void ResetDraging() { //Debug.Log("ResetDraging"); Debug.Log("延迟查询"); if (m_GameUI.HasTower) { Debug.Log("m_GameUI.HasTower!!!!"); m_GameUI.CloseCanPlace();//关闭所有绿色底板 m_GameUI.CloseCanPlaceRenderer();//关闭所有宝石示意 m_GameUI.EndDragCancelPlaceTower();//强制释放 EndlessUIStart.instance.SetDarkGround(false); this.isInDragState = false; if (!GameConfig.IsNewbie) { Time.timeScale = currentTimeScale; } //Debug.LogError("推拽已经结束了,强行恢复塔位了 , m_GameUI.HasTower:" + m_GameUI.HasTower); } if (m_GameUI.isBuilding) { //Debug.LogError("推拽已经结束了,为什么 m_GameUI.isBuilding是true????"); } isDraging = false; } /// /// Called on tap, /// calls confirmation of tower placement /// protected virtual void OnTap(PointerActionInfo pointerActionInfo) { // 点击不处理 } float dragTime = 0; bool isDraging = false; /// /// Assigns the drag pointer and sets the UI into drag mode /// /// protected virtual void OnStartDrag(PointerActionInfo pointer) { if (!isDraging) { Debug.Log("开始拖拽"); isDraging = true; if (GameConfig.IsNewbie) { if (!GameConfig.CanDragTower) { Debug.Log("新手不可以拖拽"); return; } } // select towers m_GameUI.TrySelectTower(pointer); // River: 为了开始拖动后可以直接显示GhostTower m_GameUI.TryMoveGhost(pointer, false); if (m_GameUI.HasTower) { //Debug.Log("点击到了塔,开始推拽"); EndlessUIStart.instance.SetDarkGround(true); this.isInDragState = true; AudioSourceManager.Ins.Play(AudioEnum.DragTower); //m_GameUI.CheckAllCanPlace();//检查上阵宝石有么有可以合成的位置 if (!GameConfig.IsNewbie) { //新手引导这里会把引导的速度变慢 currentTimeScale = Time.timeScale; Time.timeScale = 0.5f; } else { GuideCtrl.Ins.BeginDrag5_1(); } } } } /// /// Called when we drag /// protected override void OnDrag(PointerActionInfo pointer) { // if ((pointer != null) && (m_GameUI.isBuilding)) // { // m_GameUI.TryMoveGhost(pointer, false); // } // return; //按照鼠标键盘的修改 if (isDraging && (pointer != null) && (m_GameUI.isBuilding)) { m_GameUI.TryMoveGhost(pointer, false); //m_GameUI.CheckTowerPlace(pointer); m_GameUI.CheckTowerPlaceNew(pointer); } } /// /// Drags the ghost /// void DragGhost(TouchInfo touchInfo) { if (touchInfo.touchId == m_DragPointer.touchId) { m_GameUI.TryMoveGhost(touchInfo, false); if (invalidButtons.canvasEnabled) { invalidButtons.canvasEnabled = false; } if (confirmationButtons.canvasEnabled) { confirmationButtons.canvasEnabled = false; } } } /// /// pans at the edge of the screen /// void EdgePan() { float edgeWidth = panAreaScreenPercentage * Screen.width; PanWithScreenCoordinates(m_DragPointer.currentPosition, edgeWidth, panSpeed); } /// /// If the new state is then move the ghost to the center of the screen /// /// /// The previous the EndlessGameUI was is in /// /// /// The new state the EndlessGameUI is in /// void OnStateChanged(State previousState, State currentState) { // Early return for two reasons // 1. We are not moving into Build Mode // 2. We are not actually touching if (UnityInput.touchCount == 0) { return; } if (currentState == State.BuildingWithDrag) { m_IsGhostSelected = true; } } /// /// Displays the correct confirmation buttons when the tower has become valid /// void OnGhostBecameValid() { // this only needs to be done if the invalid buttons are already on screen if (!invalidButtons.canvasEnabled) { return; } //Vector2 screenPoint = cameraRig.cachedCamra.WorldToScreenPoint(m_GameUI.GetGhostPosition()); Vector2 screenPoint = UnityEngine.Camera.main.WorldToScreenPoint(m_GameUI.GetGhostPosition()); if (!confirmationButtons.canvasEnabled) { confirmationButtons.canvasEnabled = true; invalidButtons.canvasEnabled = false; confirmationButtons.TryMove(screenPoint); } } } }