查看: 1297|回复: 0
打印 上一主题 下一主题

寻路、代码

[复制链接]

2508

主题

2

听众

3万

积分

资深设计师

Rank: 7Rank: 7Rank: 7

纳金币
32806
精华
12

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

跳转到指定楼层
楼主
发表于 2012-6-15 17:39:52 |只看该作者 |倒序浏览

    // simple a* search and output routine

     
    var pathNode : GameObject; // this is our parent node to all points to search from

     
    var searchNode : GameObject; // our default open list node

     
    var startNode : GameObject; // this is home

     
    var targetNode : GameObject; // this is the destination

     
    var moveCost : int = 2;

     
   

     
    // visual aids booleans

     
    var clearSearchNodes : boolean = ***e;

     
    var clearPathNodes : boolean = false;

     
    var clearStartNode : boolean = false;

     
    var clearTargetNode : boolean = false;

     
   

     
    // visual debug text

     
    var debugTexts : GUIText[];

     
   

     
    private var maxPathNodes : int = 100;

     
    private var parentToPointTraceDistance : float = 2.0; // our distance to trace to our points around the parent

     
    private var nodeObjects : Array = new Array();

     
    private var initParentToPointDistance : Array = new Array(8); // our parent to trace point

     
    private var closedListIndexPos : int = 0;

     
    private var pathDoneIndex : int = 0;

     
    private var pathFound : boolean = false;

     
    private var closedListNodeLength : int = 0;

     
    private var pathBuilt : boolean = false;

     
   

     
    // our node data class

     
    class nodeData {

     
            var fCost : int = 0; // our surrounding total costs

     
            var gCost : int = 0; // our move costs

     
            var hCost : float = 0.0; // our hueristic costs

     
            var node : GameObject;

     
    }

     
   

     
    private var openList : nodeData[];

     
    private var jsOpenList = new Array();

     
    private var closedList = new Array();

     
    private var openListCtr : int = 0;

     
   

     
    function Start() {

     
            if (startNode.transform.position.y != targetNode.transform.position.y) {

     
                    Debug.Log("ath cannot be obtained! Your Start and Target heights are different!");

     
                    return;

     
            }

     
            

     
            if (clearStartNode == ***e)

     
                    startNode.GetComponent(MeshRenderer).enabled = false;

     
            if (clearTargetNode == ***e)

     
                    targetNode.GetComponent(MeshRenderer).enabled = false;

     
                    

     
            // initialize our search direction array, this is the distance and directions to search around our parent node

     
            initParentToPointDistance[0] = Vector3(0, 0.1, 1) * parentToPointTraceDistance;

     
            initParentToPointDistance[1] = Vector3(1, 0.1, 1) * parentToPointTraceDistance;

     
            initParentToPointDistance[2] = Vector3(1, 0.1, 0) * parentToPointTraceDistance;

     
            initParentToPointDistance[3] = Vector3(1, 0.1,-1) * parentToPointTraceDistance;

     
            initParentToPointDistance[4] = Vector3(0, 0.1,-1) * parentToPointTraceDistance;

     
            initParentToPointDistance[5] = Vector3(-1,0.1,-1) * parentToPointTraceDistance;

     
            initParentToPointDistance[6] = Vector3(-1,0.1, 0) * parentToPointTraceDistance;

     
            initParentToPointDistance[7] = Vector3(-1,0.1, 1) * parentToPointTraceDistance;

     
                    

     
            var dis : float = Vector3.Distance(targetNode.transform.position, startNode.transform.position);

     
            openList = new nodeData[8];

     
            for (i = 0; i < 8; i++) {

     
                    openList = new nodeData();

     
            }

     
                    

     
            openList[0].gCost = 0;

     
            openList[0].hCost = Mathf.RoundToInt(dis);

     
            openList[0].fCost = Mathf.RoundToInt(openList[0].hCost);

     
            openList[0].node = Instantiate(pathNode, startNode.transform.position, startNode.transform.rotation);

     
                    

     
            // since we know this is our first addition to openList, we go ahead an add it to closedList

     
            closedList.Add(new nodeData());

     
            closedList[0].gCost = openList[0].gCost;

     
            closedList[0].hCost = Mathf.RoundToInt(openList[0].hCost);

     
            closedList[0].fCost = Mathf.RoundToInt(openList[0].fCost);

     
            closedList[0].node = openList[0].node;

     
                    

     
            while(pathDoneIndex == 0) {

     
                    

     
                    pathBuilt = false;

     
                    

     
                    for (openListCtr = 0; openListCtr < 8; openListCtr++) {

     
                            Debug.Break();

     
                            AddToOpenList(openListCtr);

     
                            if (pathFound == ***e) {

     
                                    break;

     
                            }

     
                            yield;

     
                    }

     
                    

     
                    if (pathDoneIndex == 0 && pathFound == false) {

     
                            var index = ReturnLowestfCostInIndex(openList);

     
                            closedListIndexPos++;

     
                            // assign that as our next index on the closedList

     
                            AddToClosedList(closedListIndexPos, index);

     
                    }

     
            

     
                    yield;

     
            }

     
   

     
    }

     
   

     
    function DestroyOpenListNodes() {

     
            for (i = 0; i < openList.length; i++) {

     
                    GameObject.Destroy(openList.node);

     
            }

     
    }        

     
   

     
    function AddToClosedList(clIndex : int, olIndex : int) {

     
            closedList.Add(new nodeData());        

     
            closedList[clIndex].gCost = openList[olIndex].gCost;

     
            closedList[clIndex].hCost = Mathf.RoundToInt(openList[olIndex].hCost);

     
            closedList[clIndex].fCost = Mathf.RoundToInt(openList[olIndex].fCost);

     
            closedList[clIndex].node = Instantiate(pathNode, openList[olIndex].node.transform.position, Quaternion.identity);

     
            

     
            //GameObject.Destroy(openList[olIndex].node);

     
                    

     
            DestroyOpenListNodes();        

     
    }

     
   

     
    function ReturnLowestgCostInIndex(searchArray : Array) {

     
            // find the lowest fCost in the array index

     
            var lowest = 99999;   

     
            var index = -1;   

     
            for (n = 0; n < searchArray.length; n++) {                 

     
                    if (searchArray[n].gCost < lowest) {

     
                            lowest = searchArray[n].fCost;

     
                            index = n;

     
                    }

     
            }        

     
            

     
            return index;

     
    }

     
   

     
    function ReturnLowestfCostInIndex(searchArray : Array) {

     
            // find the lowest fCost in the array index

     
            var lowest = 99999;   

     
            var index = -1;   

     
            for (n = 0; n < searchArray.length; n++) {                 

     
                    if (searchArray[n].fCost < lowest) {

     
                            lowest = searchArray[n].fCost;

     
                            index = n;

     
                    }

     
            }        

     
            

     
            return index;

     
    }

     
   

     
    function AddToOpenList(index : int) {

     
            // so now we search it's neighbors

     
            var endPos : Vector3 = new Vector3(Mathf.RoundToInt(closedList[closedListIndexPos].node.transform.position.x),0.1,

     
                                                                                       Mathf.RoundToInt(closedList[closedListIndexPos].node.transform.position.z)) + initParentToPointDistance[index];

     
                    var dis = Vector3.Distance(targetNode.transform.position, Vector3(Mathf.RoundToInt(endPos.x),endPos.y,Mathf.RoundToInt(endPos.z)));

     
                    Debug.DrawLine(closedList[closedListIndexPos].node.transform.position, endPos, Color.red);

     
                    //print(endPos);               

     
                    if (Vector3.Distance(targetNode.transform.position, endPos) < parentToPointTraceDistance) {

     
                            print("We've found our goal");

     
                            closedList[closedListIndexPos].node = targetNode;

     
                            for (j = 0; j < closedList.length; j++) {

     
                                    if (closedList[j].node != null) {

     
                                            closedListNodeLength = j;

     
                                    }

     
                            }

     
                            DestroyOpenListNodes();

     
                            pathDoneIndex = closedListIndexPos;

     
                            pathFound = ***e;

     
                            return;

     
                    }

     
                    

     
                    if ((index % 2) == 0)

     
                              moveCost = 10;

     
                    else

     
                              moveCost = 14;

     
                     

     
                      print(jsOpenList.length);                        

     
                    jsOpenList.Add(new nodeData());

     
                    print(jsOpenList.length);

     
                    

     
                    if (!Physics.Linecast(Vector3(closedList[closedListIndexPos].node.transform.position.x,0.1,closedList[closedListIndexPos].node.transform.position.z),endPos)) {        

     
                            if (closedListIndexPos > 0) { // this just means we have added the first round of position to the open list

     
                                    

     
                                    if ((Mathf.RoundToInt(endPos.x) != Mathf.RoundToInt(closedList[closedListIndexPos-1].node.transform.position.x))

     
                                      ||  (Mathf.RoundToInt(endPos.z) != Mathf.RoundToInt(closedList[closedListIndexPos-1].node.transform.position.z))) { // if our x or y is not our previous closed list node

     
                                              print("We are not on the closed list");

     
                                              var tempIndex : int = 0;

     
                                              //print(jsOpenList.length);

     
                                              for (i = 0; i < jsOpenList.length; i++) { // now we have to search our total open list

     
                                                      //print(i);

     
                                                      //print(endPos.x + " " + endPos.z + " " + jsOpenList.node.transform.position.x + " " + jsOpenList.node.transform.position.z);

     
                                                      if (jsOpenList.node != null) {

     
                                                              if ((Mathf.RoundToInt(endPos.x) == Mathf.RoundToInt(jsOpenList.node.transform.position.x))

     
                                                              &&  (Mathf.RoundToInt(endPos.z) == Mathf.RoundToInt(jsOpenList.node.transform.position.z))) { // if we have found a node already on our open list

     
                                                                      print("You are on the openList");

     
                                                                      //print(endPos.x + " " + endPos.z + " " + jsOpenList.node.transform.position.x + " " + jsOpenList.node.transform.position.z);

     
                                                                      tempIndex = i; // record the index                                                           

     
                                                                      break;

     
                                                              }

     
                                                      }

     
                                                      else {

     
                                                              print(i);

     
                                                      }

     
                                              }

     
                                             

     
                                              if (tempIndex == 0) { // if none are on the open list, we add it to the open list

     
                                                      print("We are not on the open list");

     
                                                      //print(openList.length);

     
                                                      print(index);

     
                                                      //print(jsOpenList.length);

     
                                                      openList[index].hCost = Mathf.RoundToInt(dis);

     
                                                       openList[index].gCost = moveCost; // temporary until we have found better ways to build our path

     
                                                      openList[index].fCost = Mathf.RoundToInt(openList[index].gCost + openList[index].hCost);

     
                                                      openList[index].node = Instantiate(searchNode,endPos,Quaternion.identity);         

     
                                                      

     
                                                      jsOpenList[index].hCost = openList[index].hCost;

     
                                                    jsOpenList[index].gCost = openList[index].gCost;

     
                                                    jsOpenList[index].fCost = openList[index].fCost;

     
                                                    jsOpenList[index].node = openList[index].node;                                       

     
                                              }

     
                                              else {// if a searched position is on the open list

     
                                                      if (jsOpenList[tempIndex].gCost < (moveCost + closedList[closedListIndexPos].gCost)) { // see if the move cost is better than what it takes to move from our last closed list pos

     
                                                              //print("It is better to go to jsOpenList[tempIndex] than it is to go to closedList[closedListIndexPos]");

     
                                                              //print(moveCost + closedList[closedListIndexPos].gCost + " " + openList[index].gCost);

     
                                                              

     
                                                              // add the parent node with the bigger move costs to our total open list (so we do not go back to it)

     
                                                              var tempPos = jsOpenList[tempIndex].node.transform.position; // get our current parent position we are searching form

     
                                                                                                                        

     
                                                              // add to our index our previous parents data (we do this because we make sure we make this a prent node again)

     
                                                              jsOpenList[index].node = Instantiate(searchNode,closedList[closedListIndexPos].node.transform.position,Quaternion.identity);

     
                                                              print(jsOpenList[index].node.transform.position);

     
                                                              jsOpenList[index].hCost = closedList[closedListIndexPos].hCost;

     
                                                              var updatedgCost = closedList[closedListIndexPos].gCost + moveCost; // this should equal 20

     
                                                              jsOpenList[index].gCost = updatedgCost;

     
                                                              jsOpenList[index].fCost = closedList[closedListIndexPos].fCost + updatedgCost;

     
                                                              

     
                                                              GameObject.Destroy(closedList[closedListIndexPos].node); // now destroy the parent node (we are updating with a better to move to parent)

     
                                                              

     
                                                              //  now we replace our better node data to our current closedList position we are searching from                                                         

     
                                                              closedList[closedListIndexPos].node  = Instantiate(pathNode,tempPos,Quaternion.identity);

     
                                                              closedList[closedListIndexPos].hCost = Vector3.Distance(targetNode.transform.position, Vector3(Mathf.RoundToInt(tempPos.x), 0.1, Mathf.RoundToInt(tempPos.z)));

     
                                                              closedList[closedListIndexPos].gCost = jsOpenList[tempIndex].gCost;

     
                                                              closedList[closedListIndexPos].fCost = Mathf.RoundToInt(jsOpenList[tempIndex].gCost + jsOpenList[tempIndex].hCost);

     
                                                              

     
                                                              //jsOpenList.length = jsOpenList.length - 1;

     
                                                              

     
                                                            print("back to main loop");

     
                                                            openListCtr = -1;

     
                                                              return;

     
                                                      }

     
                                                      else {

     
                                                              print("Our cost is greater");

     
                                                      }                                                         

     
                                              }                                                         

     
                                      }

     
                                      else {

     
                                              print("We did find a cost on the closed list");

     
                                              foundOnClosed = ***e;

     
                                              openList[index].node = null;

     
                                        openList[index].fCost = 99999;

     
                                        openList[index].hCost = 99999;

     
                                        openList[index].gCost = 99999;

     
                                       

     
                                        jsOpenList[index].hCost = openList[index].hCost;

     
                                            jsOpenList[index].gCost = openList[index].gCost;

     
                                            jsOpenList[index].fCost = openList[index].fCost;

     
                                            jsOpenList[index].node = openList[index].node;

     
                                      }        

     
                              }

     
                              else {

     
                                      openList[index].hCost = Mathf.RoundToInt(dis);

     
                                      openList[index].gCost = moveCost; // temporary until we have found better ways to build our path

     
                                      openList[index].fCost = Mathf.RoundToInt(openList[index].gCost + openList[index].hCost);

     
                                      openList[index].node = Instantiate(searchNode,endPos,Quaternion.identity);

     
                                      

     
                                      jsOpenList[index].hCost = openList[index].hCost;

     
                                    jsOpenList[index].gCost = openList[index].gCost;

     
                                    jsOpenList[index].fCost = openList[index].fCost;

     
                                    jsOpenList[index].node = openList[index].node;

     
                              }                                                                                                      

     
                    }        

     
                    else {

     
                            print("We hit a wall");

     
                        openList[index].node = null;

     
                        openList[index].fCost = 99999;

     
                        openList[index].hCost = 99999;

     
                        openList[index].gCost = 99999;

     
                        

     
                        jsOpenList[index].hCost = openList[index].hCost;

     
                            jsOpenList[index].gCost = openList[index].gCost;

     
                            jsOpenList[index].fCost = openList[index].fCost;

     
                            jsOpenList[index].node = openList[index].node;                    

     
                    }

     
                    

     
                    debugTexts[index].text = "Cost: " + jsOpenList[index].fCost + " Move: " + jsOpenList[index].gCost + " Dist: " + jsOpenList[index].hCost;

     
    }
分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2024-9-20 14:46 , Processed in 0.106642 second(s), 28 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部