/// <summary> /// Selects a tower beneath the given pointer if there is one /// </summary> /// <param name="info"> /// The pointer information concerning the selector of the pointer /// </param> /// <exception cref="InvalidOperationException"> /// Throws an exception when not in <see cref="State.Normal"/> /// </exception> public void TrySelectTower(PointerInfo info) { if (state != State.Normal) { throw new InvalidOperationException( "Trying to select towers outside of Normal state"); } UIPointer uiPointer = WrapPointer(info); RaycastHit output; bool hasHit = Physics.Raycast(uiPointer.ray, out output, float.MaxValue, towerSelectionLayer); if (!hasHit || uiPointer.overUI) { return; } var controller = output.collider.GetComponent <TowerYfb>(); if (controller != null) { SelectTower(controller); } }
/// <summary> /// Place the ghost at the pointer's position /// </summary> /// <param name="pointer">The pointer to place the ghost at</param> /// <exception cref="InvalidOperationException">If we're not in the correct state</exception> protected void PlaceGhost(UIPointer pointer) { if (m_CurrentTower == null || !isBuilding) { throw new InvalidOperationException( "Trying to position a tower ghost while the UI is not currently in a building state."); } MoveGhost(pointer); if (m_CurrentArea != null) { TowerFitStatus fits = m_CurrentArea.Fits(m_GridPosition, m_CurrentTower.controller.dimensions); if (fits == TowerFitStatus.Fits) { // Place the ghost Tower controller = m_CurrentTower.controller; Tower createdTower = Instantiate(controller); createdTower.Initialize(m_CurrentArea, m_GridPosition); CancelGhostPlacement(); } } }
/// <summary> /// Used to buy the tower during the build phase /// Checks currency and calls <see cref="PlaceGhost" /> /// <exception cref="InvalidOperationException"> /// Throws exception when not in a build mode or when tower is not a valid position /// </exception> /// </summary> public void BuyTower(UIPointer pointer) { if (!isBuilding) { throw new InvalidOperationException( "Trying to buy towers when not in a Build Mode"); } if (m_CurrentTower == null || !IsGhostAtValidPosition()) { return; } PlacementAreaRaycast(ref pointer); if (!pointer.raycast.HasValue || pointer.raycast.Value.collider == null) { CancelGhostPlacement(); return; } int cost = m_CurrentTower.controller.purchaseCost; bool successfulPurchase = LevelManagerYfb.instance.currency.TryPurchase(cost); if (successfulPurchase) { PlaceGhost(pointer); } }
/// <summary> /// Calculates whether the given pointer is over the current tower ghost /// </summary> /// <param name="pointerInfo"> /// The information used to check against the <see cref="m_CurrentTower"/> /// </param> /// <exception cref="InvalidOperationException"> /// Throws an exception if not in Build Mode /// </exception> public bool IsPointerOverGhost(PointerInfo pointerInfo) { if (state != State.Building) { throw new InvalidOperationException("Trying to tap on ghost tower when not in Build Mode"); } UIPointer uiPointer = WrapPointer(pointerInfo); RaycastHit hit; return(m_CurrentTower.ghostCollider.Raycast(uiPointer.ray, out hit, float.MaxValue)); }
/// <summary> /// Attempt to position a tower at the given location /// </summary> /// <param name="pointerInfo">The pointer we're using to position the tower</param> public void TryPlaceTower(PointerInfo pointerInfo) { UIPointer pointer = WrapPointer(pointerInfo); // Do nothing if we're over UI if (pointer.overUI) { return; } BuyTower(pointer); }
/// <summary> /// Position the ghost tower at the given pointer /// </summary> /// <param name="pointerInfo">The pointer we're using to position the tower</param> /// <param name="hideWhenInvalid">Optional parameter for configuring if the ghost is hidden when in an invalid location</param> public void TryMoveGhost(PointerInfo pointerInfo, bool hideWhenInvalid = true) { if (m_CurrentTower == null) { throw new InvalidOperationException("Trying to move the tower ghost when we don't have one"); } UIPointer pointer = WrapPointer(pointerInfo); // Do nothing if we're over UI if (pointer.overUI && hideWhenInvalid) { m_CurrentTower.Hide(); return; } MoveGhost(pointer, hideWhenInvalid); }
/// <summary> /// Subscribe to the level manager /// </summary> //protected virtual void OnEnable() //{ // if (LevelManager.instanceExists) // { // LevelManager.instance.currency.currencyChanged += OnCurrencyChanged; // } //} /// <summary> /// Unsubscribe from the level manager /// </summary> //protected virtual void OnDisable() //{ // if (LevelManager.instanceExists) // { // LevelManager.instance.currency.currencyChanged -= OnCurrencyChanged; // } //} /// <summary> /// Creates a new UIPointer holding data object /// for the given pointer position /// </summary> protected UIPointer WrapPointer(PointerInfo pointerInfo) { UIPointer temp = new UIPointer(); temp.pointer = pointerInfo; temp.ray = m_Camera.ScreenPointToRay(pointerInfo.currentPosition); temp.overUI = IsOverUI(pointerInfo); return(temp); //return new UIPointer //{ // pointer = pointerInfo, // ray = m_Camera.ScreenPointToRay(pointerInfo.currentPosition), // overUI = IsOverUI(pointerInfo) //}; }
/// <summary> /// Raycast onto tower placement areas /// </summary> /// <param name="pointer">The pointer we're testing</param> protected void PlacementAreaRaycast(ref UIPointer pointer) { pointer.raycast = null; if (pointer.overUI) { // Pointer is over UI, so no valid position return; } // Raycast onto placement area layer RaycastHit hit; if (Physics.Raycast(pointer.ray, out hit, float.MaxValue, placementAreaMask)) { pointer.raycast = hit; } }
/// <summary> /// Move the ghost to the pointer's position /// </summary> /// <param name="pointer">The pointer to place the ghost at</param> /// <param name="hideWhenInvalid">Optional parameter for whether the ghost should be hidden or not</param> /// <exception cref="InvalidOperationException">If we're not in the correct state</exception> protected void MoveGhost(UIPointer pointer, bool hideWhenInvalid = true) { if (m_CurrentTower == null || !isBuilding) { throw new InvalidOperationException( "Trying to position a tower ghost while the UI is not currently in the building state."); } // Raycast onto placement layer PlacementAreaRaycast(ref pointer); if (pointer.raycast != null) { MoveGhostWithRaycastHit(pointer.raycast.Value); } else { MoveGhostOntoWorld(pointer.ray, hideWhenInvalid); } }
/// <summary> /// Position the ghost tower at the given pointer /// </summary> /// <param name="pointerInfo">The pointer we're using to position the tower</param> /// <param name="hideWhenInvalid">Optional parameter for configuring if the ghost is hidden when in an invalid location</param> public void TryMoveGhost(PointerInfo info, bool hideWhenInvalid = true) { if (m_CurrentTower == null) { throw new InvalidOperationException("Trying to move the tower ghost when we don't have one"); } UIPointer pointer = WrapPointer(info); /* * LineRenderer lineRenderer = GetComponentInChildren<LineRenderer>(); * lineRenderer.SetPosition(0, pointer.ray.origin); * lineRenderer.SetPosition(1, pointer.ray.direction * 1000); */ // Do nothing if we're over UI if (pointer.overUI && hideWhenInvalid) { m_CurrentTower.Hide(); return; } MoveGhost(pointer, hideWhenInvalid); }