Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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("");
        }
Пример #4
0
        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
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
        }
Пример #7
0
 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);
                 }
             }
         }
     }
 }
Пример #8
0
        //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);
        }
Пример #9
0
        //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);
        }
Пример #10
0
        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);
        }
Пример #11
0
        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);
        }