- 最后登录
- 2017-5-15
- 注册时间
- 2012-3-1
- 阅读权限
- 90
- 积分
- 32973
- 纳金币
- 32806
- 精华
- 12
|
// 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;
}
|
|