コード例 #1
0
ファイル: GameControl.cs プロジェクト: wattson-coder/TD
        public static Vector3 ClickOnTerrain(Vector3 pointer)
        {
            int layer = LayerManager.LayerTower();

            LayerMask  mask = 1 << LayerManager.LayerTerrain();
            Ray        ray  = Camera.main.ScreenPointToRay(pointer);
            RaycastHit hit;

            if (!Physics.Raycast(ray, out hit, Mathf.Infinity, mask))
            {
                return(Vector3.zero);
            }

            return(hit.point);
        }
コード例 #2
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 << LayerManager.LayerTerrain();
                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);
        }
コード例 #3
0
ファイル: BuildManager.cs プロジェクト: wattson-coder/TD
        public _TileStatus _CheckBuildPoint(Vector3 pointer, int footprint = -1, int ID = -1)
        {
            _TileStatus status       = _TileStatus.Available;
            BuildInfo   newBuildInfo = new BuildInfo();

            //disable indicator first (for dragNdrop mode), it will be re-enable if the build-point is valid
            indicatorBuildPoint.SetActive(false);

            //layerMask for platform only
            LayerMask maskPlatform = 1 << LayerManager.LayerPlatform();
            //layerMask for detect all collider within buildPoint
            LayerMask maskAll      = 1 << LayerManager.LayerPlatform();
            int       terrainLayer = LayerManager.LayerTerrain();

            if (terrainLayer >= 0)
            {
                maskAll |= 1 << terrainLayer;
            }

            //int creepLayer=LayerManager.layerCreep();
            //if(creepLayer>=0) maskAll|=1<<creepLayer;

            Camera mainCam = Camera.main;

            if (mainCam != null)
            {
                Ray        ray = mainCam.ScreenPointToRay(pointer);
                RaycastHit hit;
                if (Physics.Raycast(ray, out hit, Mathf.Infinity, maskPlatform))
                {
                    for (int i = 0; i < buildPlatforms.Count; i++)
                    {
                        if (hit.transform == buildPlatforms[i].thisT)
                        {
                            PlatformTD platform = buildPlatforms[i];

                            //checking if tower can be built on the platform, for dragNdrop mode
                            if (ID >= 0 && !platform.availableTowerIDList.Contains(ID))
                            {
                                return(_TileStatus.Unavailable);
                            }

                            //calculating the build center point base on the input position
                            Vector3 pos = GetTilePos(platform.thisT, hit.point);

                            //check if the position is blocked, by any other obstabcle other than the baseplane itself
                            Collider[] cols = Physics.OverlapSphere(pos, _gridSize / 2 * 0.9f + footprint * _gridSize, ~maskAll);
                            if (cols.Length > 0)
                            {
                                //Debug.Log("something's in the way "+cols[0]);
                                return(_TileStatus.Unavailable);
                            }
                            else
                            {
                                //confirm that we can build here
                                newBuildInfo.position = pos;
                                newBuildInfo.platform = platform;
                            }

                            //check if the platform is walkable, if so, check if building on the point wont block all possible path
                            if (platform.IsWalkable())
                            {
                                if (platform.CheckForBlock(pos))
                                {
                                    //Debug.Log("all path is blocked "+Time.time);
                                    status = _TileStatus.Blocked;
                                }
                            }

                            //newBuildInfo.availableTowerIDList=platform.availableTowerIDList;
                            //map platform availableTowerIDList (which is the towers' prefabID) to the list elements' ID in towerList
                            newBuildInfo.availableTowerIDList = new List <int>();
                            for (int m = 0; m < platform.availableTowerIDList.Count; m++)
                            {
                                for (int n = 0; n < towerList.Count; n++)
                                {
                                    if (platform.availableTowerIDList[m] == towerList[n].prefabID)
                                    {
                                        newBuildInfo.availableTowerIDList.Add(n);
                                        break;
                                    }
                                }
                            }

                            //List<int> tempList=new List<int>();
                            //for(int n=0; n<towerList.Count; n++) tempList.Add(towerList[n].prefabID);
                            //newBuildInfo.availableTowerIDList=tempList;

                            buildInfo = newBuildInfo;

                            break;
                        }
                    }
                }
                else
                {
                    return(_TileStatus.NoPlatform);
                }
            }
            else
            {
                return(_TileStatus.NoPlatform);
            }

            //reverse block status for mine
            if (status == _TileStatus.Blocked)
            {
                //for drag n drop mode
                if (ID >= 0 && GetTower(ID).type == _TowerType.Mine)
                {
                    status = _TileStatus.Available;
                }
                if (ID < 0)
                {
                    bool gotMineInList = false;
                    for (int i = 0; i < buildInfo.availableTowerIDList.Count; i++)
                    {
                        if (towerList[buildInfo.availableTowerIDList[i]].type == _TowerType.Mine)
                        {
                            gotMineInList = true;
                        }
                        else
                        {
                            buildInfo.availableTowerIDList.RemoveAt(i);
                            i -= 1;
                        }
                    }
                    if (gotMineInList)
                    {
                        status = _TileStatus.Available;
                    }
                }
            }


            if (buildInfo != null && cursorIndicatorMode != _CursorIndicatorMode.None)
            {
                if (status == _TileStatus.Available)
                {
                    indicatorBuildPointRen.material.SetColor("_TintColor", new Color(0, 1, 0, 1));
                }
                else
                {
                    indicatorBuildPointRen.material.SetColor("_TintColor", new Color(1, 0, 0, 1));
                }

                indicatorBuildPoint.SetActive(true);
                indicatorBuildPoint.transform.position = buildInfo.position;
                if (buildInfo.platform != null)
                {
                    indicatorBuildPoint.transform.rotation = buildInfo.platform.thisT.rotation;
                }

                HideCursorIndicator();
            }

            return(status);
        }
コード例 #4
0
ファイル: BuildManager.cs プロジェクト: wattson-coder/TD
        public void _SetIndicator(Vector3 pointer)
        {
            //~ if(!buildManager.enableTileIndicator) return;
            if (cursorIndicatorMode == _CursorIndicatorMode.None)
            {
                return;
            }

            if (buildInfo != null)
            {
                indicatorCursor.SetActive(false);
                return;
            }

            //layerMask for platform only
            LayerMask maskPlatform = 1 << LayerManager.LayerPlatform();
            //layerMask for detect all collider within buildPoint
            LayerMask maskAll      = 1 << LayerManager.LayerPlatform();
            int       terrainLayer = LayerManager.LayerTerrain();

            if (terrainLayer >= 0)
            {
                maskAll |= 1 << terrainLayer;
            }

            Camera mainCam = Camera.main;

            if (mainCam != null)
            {
                Ray        ray = mainCam.ScreenPointToRay(pointer);
                RaycastHit hit;
                if (Physics.Raycast(ray, out hit, Mathf.Infinity, maskPlatform))
                {
                    for (int i = 0; i < buildPlatforms.Count; i++)
                    {
                        if (hit.transform == buildPlatforms[i].thisT)
                        {
                            //calculating the build center point base on the input position
                            Vector3 pos = GetTilePos(buildPlatforms[i].thisT, hit.point);

                            //Debug.Log(new Vector3(remainderX, 0, remainderZ)+"  "+new Vector3(signX, 0, signZ)+"  "+p+"  "+basePlane.position);
                            indicatorCursor.transform.position = pos;
                            indicatorCursor.transform.rotation = buildPlatforms[i].thisT.rotation;

                            Collider[] cols = Physics.OverlapSphere(pos, _gridSize / 2 * 0.9f, ~maskAll);
                            if (cols.Length > 0)
                            {
                                if (cursorIndicatorMode == _CursorIndicatorMode.All)
                                {
                                    indicatorCursor.SetActive(true);
                                    indicatorCursorRen.material.SetColor("_TintColor", Color.red);
                                }
                                else
                                {
                                    indicatorCursor.SetActive(false);
                                }
                            }
                            else
                            {
                                indicatorCursor.SetActive(true);
                                indicatorCursorRen.material.SetColor("_TintColor", Color.green);
                            }
                        }
                    }
                }
                else
                {
                    indicatorCursor.SetActive(false);
                }
            }
            else
            {
                indicatorCursor.SetActive(false);
            }
        }
コード例 #5
0
ファイル: AbilityManager.cs プロジェクト: wattson-coder/TD
        //called in every frame, execute if there's an ability is selected and pending target selection
        //use only mouse input atm.
        void SelectAbilityTarget()
        {
            if (selectedAbilityID < 0)
            {
                return;
            }

            //only cast on terrain and platform
            LayerMask mask         = 1 << LayerManager.LayerPlatform();
            int       terrainLayer = LayerManager.LayerTerrain();

            if (terrainLayer >= 0)
            {
                mask |= 1 << terrainLayer;
            }

            Ability ability = abilityList[selectedAbilityID];

            if (ability.singleUnitTargeting)
            {
                if (ability.targetType == Ability._TargetType.Hybrid)
                {
                    mask |= 1 << LayerManager.LayerTower();
                    mask |= 1 << LayerManager.LayerCreep();
                }
                else if (ability.targetType == Ability._TargetType.Friendly)
                {
                    mask |= 1 << LayerManager.LayerTower();
                }
                else if (ability.targetType == Ability._TargetType.Hostile)
                {
                    mask |= 1 << LayerManager.LayerCreep();
                }
            }


#if UNITY_IPHONE || UNITY_ANDROID || UNITY_WP8
            Unit targetUnit = null;
            if (Input.touchCount >= 1)
            {
                Camera mainCam = Camera.main;
                if (mainCam != null)
                {
                    Ray        ray = mainCam.ScreenPointToRay(Input.touches[0].position);
                    RaycastHit hit;
                    if (Physics.Raycast(ray, out hit, Mathf.Infinity, mask))
                    {
                        currentIndicator.position = hit.point + new Vector3(0, 0.1f, 0);
                        validTarget = true;

                        if (ability.singleUnitTargeting)
                        {
                            targetUnit = hit.transform.GetComponent <Unit>();
                            if (targetUnit != null)
                            {
                                currentIndicator.position = targetUnit.thisT.position;
                            }
                            else
                            {
                                validTarget = false;
                            }
                        }
                    }
                    else
                    {
                        validTarget = false;
                    }
                }
            }
            else
            {
                if (validTarget)
                {
                    ActivateAbility(ability, currentIndicator.position, targetUnit);
                }
                else
                {
                    GameControl.DisplayMessage("Invalid target for ability");
                }
                ClearSelectedAbility();
            }
#else
            Camera mainCam = Camera.main;
            if (mainCam != null)
            {
                Ray        ray = mainCam.ScreenPointToRay(Input.mousePosition);
                RaycastHit hit;
                if (Physics.Raycast(ray, out hit, Mathf.Infinity, mask))
                {
                    currentIndicator.position = hit.point + new Vector3(0, 0.1f, 0);

                    Unit targetUnit = null;

                    validTarget = true;
                    if (ability.singleUnitTargeting)
                    {
                        targetUnit = hit.transform.GetComponent <Unit>();
                        if (targetUnit != null)
                        {
                            currentIndicator.position = targetUnit.thisT.position;
                        }
                        else
                        {
                            validTarget = false;
                        }
                    }

                    if (Input.GetMouseButtonDown(0))
                    {
                        if (validTarget)
                        {
                            ActivateAbility(ability, currentIndicator.position, targetUnit);
                            ClearSelectedAbility();
                        }
                        else
                        {
                            GameControl.DisplayMessage("Invalid target for ability");
                        }
                    }
                }
            }


            if (Input.GetMouseButtonDown(1))
            {
                ClearSelectedAbility();
            }
#endif
        }
コード例 #6
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 << LayerManager.LayerTower();
                    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 << LayerManager.LayerPlatform();
                    mask |= 1 << LayerManager.LayerTower();
                    if (LayerManager.LayerTerrain() >= 0)
                    {
                        mask |= 1 << LayerManager.LayerTerrain();
                    }
                    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 << LayerManager.LayerPlatform();
                                mask |= 1 << LayerManager.LayerTower();
                                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);
        }