public static List <Vector3> SmoothPath(List <Vector3> p) { if (instance.pathSmoothing == _PathSmoothing.Mean) { p = MeanSmoothPath(p); } else if (instance.pathSmoothing == _PathSmoothing.LOS) { p = instance.LOSPathSmoothingBackward(p); p = instance.LOSPathSmoothingForward(p); //recreate the path by sampling the path with the spacing of gridSize //this is done so when checking if a new build point cross this path, it can be detected float gridSize = BuildManager.GetGridSize(); List <Vector3> newP = new List <Vector3> { p[0] }; // newP.Add( p[0] ); for (int i = 1; i < p.Count; i++) { while (Vector3.Distance(newP[newP.Count - 1], p[i]) > gridSize) { newP.Add(newP[newP.Count - 1] + (p[i] - p[i - 1]).normalized * gridSize); } newP.Add(p[i]); } p = newP; } return(p); }
public bool CheckForBlock(Vector3 pos) { float gridSize = BuildManager.GetGridSize(); NodeTD targetNode = PathFinder.GetNearestNode(pos, nodeGraph); for (int i = 0; i < subPathList.Count; i++) { SubPath subPath = subPathList[i]; if (Vector3.Distance(pos, subPath.startN.pos) < gridSize / 2) { return(true); } if (Vector3.Distance(pos, subPath.endN.pos) < gridSize / 2) { return(true); } if (subPath.IsNodeInPath(targetNode)) { subPath.altPath = PathFinder.ForceSearch(subPath.startN, subPath.endN, targetNode, nodeGraph); if (subPath.altPath.Count == 0) { return(true); } } } nextBuildNode = targetNode; return(false); }
public string _SelectAbility(int ID) { Ability ab = abilityList[ID]; Debug.Log(ab.name); string exception = ab.IsAvailable(); if (exception != "") { return(exception); } if (!ab.requireTargetSelection) { ActivateAbility(ab); //no target selection required, fire it away } else { if (onTargetSelectModeE != null) { onTargetSelectModeE(true); //enter target selection phase } inTargetSelectMode = true; validTarget = false; selectedAbilityID = ID; if (ab.indicator != null) { currentIndicator = ab.indicator; } else { currentIndicator = defaultIndicator; if (ab.autoScaleIndicator) { if (ab.singleUnitTargeting) { float gridSize = BuildManager.GetGridSize(); currentIndicator.localScale = new Vector3(gridSize, 1, gridSize); } else { currentIndicator.localScale = new Vector3(ab.GetAOERadius() * 2, 1, ab.GetAOERadius() * 2); } } } currentIndicator.gameObject.SetActive(true); } return(""); }
public void Init() { instance = this; thisT = transform; float gridSize = BuildManager.GetGridSize(); if (indicatorSelected != null) { indicatorSelected = (Transform)Instantiate(indicatorSelected); indicatorSelected.localScale = new Vector3(gridSize, gridSize, gridSize); indicatorSelected.parent = thisT; indicatorSelected.name = "TileIndicator_Selected"; indicatorSelectedRenderer = indicatorSelected.GetChild(0).GetComponent <Renderer>(); indicatorSelectedObj = indicatorSelected.gameObject; indicatorSelectedObj.SetActive(false); } if (indicatorCursor != null) { indicatorCursor = (Transform)Instantiate(indicatorCursor); indicatorCursor.localScale = new Vector3(gridSize, gridSize, gridSize); indicatorCursor.parent = thisT; indicatorCursor.name = "TileIndicator_Cursor"; indicatorCursorObj = indicatorCursor.gameObject; indicatorCursorObj.SetActive(false); } if (rangeIndicator != null) { rangeIndicator = (Transform)Instantiate(rangeIndicator); rangeIndicator.parent = thisT; rangeIndicatorObj = rangeIndicator.gameObject; } if (rangeIndicatorCone != null) { rangeIndicatorCone = (Transform)Instantiate(rangeIndicatorCone); rangeIndicatorCone.parent = thisT; rangeIndicatorConeObj = rangeIndicatorCone.gameObject; } _ClearRangeIndicator(); //~ #if !UNITY_STANDALONE_WIN && UNITY_STANDALONE_LINUX && UNITY_STANDALONE && UNITY_WEBPLAYER //~ disableCursorIndicator=true; //~ #endif }
public bool IsNodeInPath(NodeTD node) { float gridSize = BuildManager.GetGridSize(); for (int i = 0; i < path.Count; i++) { float dist = Vector3.Distance(node.pos, path[i]); if (dist < gridSize * .85f) { return(true); } } return(false); }
void ResetSubPath(SubPath platformSubPath) { if (dummyT == null) { dummyT = new GameObject().transform; } Quaternion rot = Quaternion.LookRotation(subPath[subWaypointID] - thisT.position); dummyT.rotation = rot; dummyT.position = thisT.position; Vector3 pos = dummyT.TransformPoint(0, 0, BuildManager.GetGridSize() / 2); NodeTD startN = PathFinder.GetNearestNode(pos, platformSubPath.parentPlatform.GetNodeGraph()); PathFinder.GetPath(startN, platformSubPath.endN, platformSubPath.parentPlatform.GetNodeGraph(), this.SetSubPath); }
void OnDrawGizmos() { if (GizmoShowNodes) { if (nodeGraph != null && nodeGraph.Length > 0) { foreach (NodeTD node in nodeGraph) { if (!node.walkable) { Gizmos.color = Color.red; Gizmos.DrawSphere(node.pos, BuildManager.GetGridSize() * .15f); } else { Gizmos.color = Color.white; Gizmos.DrawSphere(node.pos, BuildManager.GetGridSize() * .15f); } } } } }
//pathSmoothing backward private List <Vector3> LOSPathSmoothingBackward(List <Vector3> p) { float gridSize = BuildManager.GetGridSize(); int num = p.Count - 1; float allowance = gridSize * 0.4f; while (num > 1) { bool decrease = false; Vector3 p1 = p[num]; Vector3 p2 = p[num - 2]; RaycastHit hit; Vector3 dir = p2 - p1; if (!Physics.SphereCast(p1, allowance, dir, out hit, Vector3.Distance(p2, p1))) { if (p1.y == p2.y) { p.RemoveAt(num - 1); } else { decrease = true; } } else { decrease = true; } num -= 1; if (decrease) { num -= 1; } } return(p); }
//pathSmoothing forward private List <Vector3> LOSPathSmoothingForward(List <Vector3> p) { float gridSize = BuildManager.GetGridSize(); int num = 0; float allowance = gridSize * 0.4f; while (num + 2 < p.Count) { bool increase = false; Vector3 p1 = p[num]; Vector3 p2 = p[num + 2]; RaycastHit hit; Vector3 dir = p2 - p1; LayerMask mask = 1 << TDTK.GetLayerTerrain(); if (!Physics.SphereCast(p1, allowance, dir, out hit, Vector3.Distance(p2, p1), ~mask)) { if (p1.y == p2.y) { p.RemoveAt(num + 1); } else { increase = true; } } else { increase = true; } if (increase) { num += 1; } } return(p); }
public static NodeTD[] GenerateNode(PlatformTD platform, float heightOffset) { if (instance == null) { Init(); } Transform platformT = platform.thisT; float gridSize = BuildManager.GetGridSize(); float scaleX = platform.thisT.localScale.x; float scaleZ = platform.thisT.localScale.z; int countX = (int)(scaleX / gridSize); int countZ = (int)(scaleZ / gridSize); float x = -scaleX / 2 / scaleX; float z = -scaleZ / 2 / scaleZ; Vector3 point = platformT.TransformPoint(new Vector3(x, 0, z)); thisT.position = point; thisT.rotation = platformT.rotation; thisT.position = thisT.TransformPoint(new Vector3(gridSize / 2, heightOffset, gridSize / 2)); NodeTD[] nodeGraph = new NodeTD[countZ * countX]; int counter = 0; for (int i = 0; i < countZ; i++) { for (int j = 0; j < countX; j++) { Vector3 pos = thisT.position; pos.y = pos.y + 5000; LayerMask mask = 1 << TDTK.GetLayerTower(); RaycastHit hit1; if (Physics.Raycast(pos, Vector3.down, out hit1, Mathf.Infinity, ~mask)) { nodeGraph[counter] = new NodeTD(new Vector3(pos.x, hit1.point.y + heightOffset, pos.z), counter); } else { nodeGraph[counter] = new NodeTD(pos, counter); nodeGraph[counter].walkable = false; } counter += 1; thisT.position = thisT.TransformPoint(new Vector3(gridSize, 0, 0)); } thisT.position = thisT.TransformPoint(new Vector3(-(countX) * gridSize, 0, gridSize)); } thisT.position = Vector3.zero; thisT.rotation = Quaternion.identity; counter = 0; foreach (NodeTD cNode in nodeGraph) { if (cNode.walkable) { //check if there's anything within the point LayerMask mask = 1 << TDTK.GetLayerPlatform(); mask |= 1 << TDTK.GetLayerTower(); if (TDTK.GetLayerTerrain() >= 0) { mask |= 1 << TDTK.GetLayerTerrain(); } Collider[] cols = Physics.OverlapSphere(cNode.pos, gridSize * 0.45f, ~mask); if (cols.Length > 0) { cNode.walkable = false; counter += 1; } } } float neighbourDistance = 0; float neighbourRange; if (instance.connectDiagonalNeighbour) { neighbourRange = gridSize * 1.5f; } else { neighbourRange = gridSize * 1.1f; } counter = 0; //assign the neighouring node for each node in the grid foreach (NodeTD currentNode in nodeGraph) { //only if that node is walkable if (currentNode.walkable) { //create an empty array List <NodeTD> neighbourNodeList = new List <NodeTD>(); List <float> neighbourCostList = new List <float>(); NodeTD[] neighbour = new NodeTD[8]; int id = currentNode.ID; if (id > countX - 1 && id < countX * countZ - countX) { //print("middle rows"); if (id != countX) { neighbour[0] = nodeGraph[id - countX - 1]; } neighbour[1] = nodeGraph[id - countX]; neighbour[2] = nodeGraph[id - countX + 1]; neighbour[3] = nodeGraph[id - 1]; neighbour[4] = nodeGraph[id + 1]; neighbour[5] = nodeGraph[id + countX - 1]; neighbour[6] = nodeGraph[id + countX]; if (id != countX * countZ - countX - 1) { neighbour[7] = nodeGraph[id + countX + 1]; } } else if (id <= countX - 1) { //print("first row"); if (id != 0) { neighbour[0] = nodeGraph[id - 1]; } if (nodeGraph.Length > id + 1) { neighbour[1] = nodeGraph[id + 1]; } if (countZ > 0) { if (nodeGraph.Length > id + countX - 1) { neighbour[2] = nodeGraph[id + countX - 1]; } if (nodeGraph.Length > id + countX) { neighbour[3] = nodeGraph[id + countX]; } if (nodeGraph.Length > id + countX + 1) { neighbour[4] = nodeGraph[id + countX + 1]; } } } else if (id >= countX * countZ - countX) { //print("last row"); neighbour[0] = nodeGraph[id - 1]; if (id != countX * countZ - 1) { neighbour[1] = nodeGraph[id + 1]; } if (id != countX * (countZ - 1)) { neighbour[2] = nodeGraph[id - countX - 1]; } neighbour[3] = nodeGraph[id - countX]; neighbour[4] = nodeGraph[id - countX + 1]; } //scan through all the node in the grid foreach (NodeTD node in neighbour) { //if this the node is not currentNode if (node != null && node.walkable) { //if this node is within neighbour node range neighbourDistance = GetHorizontalDistance(currentNode.pos, node.pos); if (neighbourDistance < neighbourRange) { //if nothing's in the way between these two LayerMask mask = 1 << TDTK.GetLayerPlatform(); mask |= 1 << TDTK.GetLayerTower(); if (!Physics.Linecast(currentNode.pos, node.pos, ~mask)) { //if the slop is not too steep //if(Mathf.Abs(GetSlope(currentNode.pos, node.pos))<=maxSlope){ //add to list //if(!node.walkable) Debug.Log("error"); neighbourNodeList.Add(node); neighbourCostList.Add(neighbourDistance); //}//else print("too steep"); } //else print("something's in the way"); } //else print("out of range "+neighbourDistance); } //else print("unwalkable"); } //set the list as the node neighbours array currentNode.SetNeighbour(neighbourNodeList, neighbourCostList); //if(neighbourNodeList.Count==0) //Debug.Log("no heighbour. node number "+counter+" "+neighbourNodeList.Count); } counter += 1; } return(nodeGraph); }
IEnumerator SelectAbilityTargetRoutine(Ability ability, int pointerID = -1) { yield return(null); Vector3 cursorPos = Vector3.zero; Unit targetUnit = null; LayerMask mask = maskAOE; if (ability.singleUnitTargeting) { if (ability.targetType == Ability._TargetType.Hybrid) { mask |= 1 << TDTK.GetLayerTower() | 1 << TDTK.GetLayerCreep(); } else if (ability.targetType == Ability._TargetType.Friendly) { mask |= 1 << TDTK.GetLayerTower(); } else if (ability.targetType == Ability._TargetType.Hostile) { mask |= 1 << TDTK.GetLayerCreep(); } } Transform indicator = ability.indicator; if (indicator == null) { indicator = defaultIndicator; float scale = ability.singleUnitTargeting ? BuildManager.GetGridSize() : ability.GetAOERadius() * 2; indicator.localScale = new Vector3(scale, scale, scale); } //TDTK.OnGameMessage("SelectAbilityTargetRoutine "+pointerID); isSelectingTarget = true; TDTK.OnAbilityTargetSelectModeE(true); if (pointerID >= 0) { while (true) { if (TDTK.IsTouchStarting(pointerID)) { break; } yield return(null); } } bool cursorOnUI = true; while (isSelectingTarget) { if (Input.GetKeyDown(KeyCode.Escape)) { break; } bool invalidCursor = false; bool invalidTarget = false; if (pointerID < 0) { cursorPos = Input.mousePosition; } else { cursorPos = TDTK.GetTouchPosition(pointerID); } if (cursorPos.magnitude < 0) { invalidCursor = true; } if (!invalidCursor && !cursorOnUI) { Ray ray = Camera.main.ScreenPointToRay(cursorPos); RaycastHit hit; if (Physics.Raycast(ray, out hit, Mathf.Infinity, mask)) { indicator.position = hit.point; targetUnit = null; if (ability.singleUnitTargeting) { targetUnit = hit.transform.GetComponent <Unit>(); if (targetUnit != null) { indicator.position = targetUnit.thisT.position; } else { invalidTarget = true; } } } } indicator.gameObject.SetActive(!invalidCursor); if (pointerID == -1) { if (Input.GetMouseButtonDown(0)) { if (cursorOnUI) { break; } if (!invalidTarget) { ActivateAbility(ability, indicator.position, targetUnit); } else { TDTK.OnGameMessage("Invalid target for ability"); } break; } if (Input.GetMouseButtonDown(1)) { break; } } else { if (TDTK.IsTouchEnding(pointerID)) { //TDTK.OnGameMessage("SelectAbilityTargetRoutine "+pointerID+" "+UI.IsCursorOnUI(pointerID)); if (cursorOnUI) { break; } if (!invalidTarget) { ActivateAbility(ability, indicator.position, targetUnit); } else { TDTK.OnGameMessage("Invalid target for ability"); } break; } } //check in previous frame cause IsCursorOnUI wont return true if the touch is ending cursorOnUI = UI.IsCursorOnUI(pointerID); yield return(null); } yield return(null); indicator.gameObject.SetActive(false); isSelectingTarget = false; TDTK.OnAbilityTargetSelectModeE(false); }