using Core.Input; using TowerDefense.UI; using TowerDefense.UI.HUD; using UnityEngine; using UnityInput = UnityEngine.Input; using State = TowerDefense.UI.HUD.GameUI.State; namespace TowerDefense.Input { [RequireComponent(typeof(GameUI))] public class TowerDefenseTouchInput : 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 /// GameUI 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() { GameUI.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.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.startedDrag -= OnStartDrag; } if (m_GameUI != null) { m_GameUI.stateChanged -= OnStateChanged; m_GameUI.ghostBecameValid -= OnGhostBecameValid; } } /// /// 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; } } } /// /// 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; } } } } /// /// Called on input release, for flicks /// protected override void OnRelease(PointerActionInfo pointer) { // EndDrag 只能放置相关的GhostTower. if (this.isInDragState) m_GameUI.onEndTowerDrag(pointer); //m_GameUI.TryPlaceTower(pointer); this.isInDragState = false; return; } /// /// Called on tap, /// calls confirmation of tower placement /// protected virtual void OnTap(PointerActionInfo pointerActionInfo) { return; var touchInfo = pointerActionInfo as TouchInfo; if (touchInfo != null) { if (m_GameUI.state == State.Normal && !touchInfo.startedOverUI) { m_GameUI.TrySelectTower(touchInfo); } else if (m_GameUI.state == State.Building && !touchInfo.startedOverUI) { m_GameUI.TryMoveGhost(touchInfo, false); if (m_GameUI.IsGhostAtValidPosition() && m_GameUI.IsValidPurchase()) { confirmationButtons.canvasEnabled = true; invalidButtons.canvasEnabled = false; confirmationButtons.TryMove(touchInfo.currentPosition); } else { invalidButtons.canvasEnabled = true; invalidButtons.TryMove(touchInfo.currentPosition); confirmationButtons.canvasEnabled = false; } } } } /// /// Assigns the drag pointer and sets the UI into drag mode /// /// protected virtual void OnStartDrag(PointerActionInfo pointer) { //Debug.Log("TouchInput StartDraged."); // select towers m_GameUI.TrySelectTower(pointer); // River: 为了开始拖动后可以直接显示GhostTower m_GameUI.TryMoveGhost(pointer, false); this.isInDragState = true; } /// /// Called when we drag /// protected override void OnDrag(PointerActionInfo pointer) { if ((pointer != null) && (m_GameUI.isBuilding)) { m_GameUI.TryMoveGhost(pointer, false); } return; } /// /// 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 GameUI was is in /// /// /// The new state the GameUI 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; } /* // River mod ATTENTION TO OPP: 用于解决游戏内点击就出错的Bug if (currentState == State.Building && previousState != State.BuildingWithDrag) { m_GameUI.MoveGhostToCenter(); confirmationButtons.canvasEnabled = false; invalidButtons.canvasEnabled = false; }*/ 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); } } } }