IEnumerator Wander() { Vector3 startPos = gameObject.transform.position, endPos = startPos; Quaternion startAngle = gameObject.transform.rotation; Quaternion endAngle = startAngle; bool rotating = false; ScenarioMgr.Direction nextFacing = facing; IntPoint2D nextTile = curTile; while (wandering) { bool goingNowhere = false; int x = curTile.xCoord, y = curTile.yCoord; IntPoint2D tileAhead = curTile, tileLeft = curTile, tileRight = curTile, tileBehind = curTile; switch (facing) { case ScenarioMgr.Direction.Left: tileAhead = new IntPoint2D(x - 1, y); tileRight = new IntPoint2D(x, y - 1); tileLeft = new IntPoint2D(x, y + 1); tileBehind = new IntPoint2D(x + 1, y); break; case ScenarioMgr.Direction.Up: tileLeft = new IntPoint2D(x - 1, y); tileAhead = new IntPoint2D(x, y - 1); tileBehind = new IntPoint2D(x, y + 1); tileRight = new IntPoint2D(x + 1, y); break; case ScenarioMgr.Direction.Right: tileBehind = new IntPoint2D(x - 1, y); tileRight = new IntPoint2D(x, y + 1); tileLeft = new IntPoint2D(x, y - 1); tileAhead = new IntPoint2D(x + 1, y); break; case ScenarioMgr.Direction.Down: tileRight = new IntPoint2D(x - 1, y); tileBehind = new IntPoint2D(x, y - 1); tileAhead = new IntPoint2D(x, y + 1); tileLeft = new IntPoint2D(x + 1, y); break; } // pick direction int p = Random.Range(0, 100); if (p < 30) { goingNowhere = true; rotating = false; } else if (p < 60 && scenarioInfo.IsPassableTile(tileAhead)) { rotating = false; nextFacing = facing; nextTile = tileAhead; } else if (p < 80 && scenarioInfo.IsPassableTile(tileLeft)) { rotating = true; nextTile = tileLeft; nextFacing = ScenarioMgr.GetLeftTurn(facing); } else if (scenarioInfo.IsPassableTile(tileRight)) { rotating = true; nextTile = tileRight; nextFacing = ScenarioMgr.GetRightTurn(facing); } else if (scenarioInfo.IsPassableTile(tileBehind)) { rotating = true; nextTile = tileBehind; nextFacing = ScenarioMgr.GetReverseDirection(facing); } else { goingNowhere = true; rotating = false; } startPos = transform.position; startAngle = gameObject.transform.rotation; if (goingNowhere) { //Debug.Log("no road to move to"); // no rotation, no movement, no nothing -- just wait things out for a second yield return(new WaitForSeconds(tileMoveTime)); } else { endPos = scenarioInfo.ComputeTopLeftPointOfTile(nextTile) + citizenTileOffset; // compute ending position switch (nextFacing) { case ScenarioMgr.Direction.Left: endAngle = Quaternion.Euler(0, 180, 0); break; case ScenarioMgr.Direction.Up: endAngle = Quaternion.Euler(0, 90, 0); break; case ScenarioMgr.Direction.Down: endAngle = Quaternion.Euler(0, 270, 0); break; case ScenarioMgr.Direction.Right: endAngle = Quaternion.Euler(0, 0, 0); break; } float elapsedTime = 0; if (rotating) { // first handle the rotation while (elapsedTime < this.turnTime) { this.gameObject.transform.rotation = Quaternion.Slerp(startAngle, endAngle, (elapsedTime / this.turnTime)); elapsedTime += Time.deltaTime; yield return(0); } } //Debug.Log("starting movement from " + startPos.ToString() + " to " + endPos.ToString()); //Debug.Log("from tile " + curTile.ToString() + " to " + nextTile.ToString()); // move float moveTime = this.tileMoveTime; if (!scenarioInfo.IsRoadTile(curTile)) { moveTime = moveTime * 2; } elapsedTime = 0; while (elapsedTime <= moveTime) { this.gameObject.transform.position = Vector3.Lerp(startPos, endPos, (elapsedTime / moveTime)); elapsedTime += Time.deltaTime; yield return(0); } // fix data for next tile this.facing = nextFacing; this.curTile = nextTile; startPos = this.gameObject.transform.position; startAngle = endAngle; } } //Debug.Log("Starting takepath coroutine from Wander"); //startPath = true; }
IEnumerator Walk() { Vector3 startPos = gameObject.transform.position, endPos = startPos; Quaternion startAngle = gameObject.transform.rotation; Quaternion endAngle = startAngle; bool rotating = false; ScenarioMgr.Direction nextFacing = facing; IntPoint2D nextTile = curTile; while (tilesToGo > 0) { //Debug.Log("doing distribution"); // do water delivery scenarioInfo.DistributeWater(new IntPoint2D(curTile.xCoord, curTile.yCoord - 1)); scenarioInfo.DistributeWater(new IntPoint2D(curTile.xCoord, curTile.yCoord + 1)); scenarioInfo.DistributeWater(new IntPoint2D(curTile.xCoord - 1, curTile.yCoord)); scenarioInfo.DistributeWater(new IntPoint2D(curTile.xCoord + 1, curTile.yCoord)); // check for road tile ahead and turn appropriately int x = curTile.xCoord, y = curTile.yCoord; IntPoint2D tileAhead = curTile, tileLeft = curTile, tileRight = curTile, tileBehind = curTile; switch (facing) { case ScenarioMgr.Direction.Left: tileAhead = new IntPoint2D(x - 1, y); tileRight = new IntPoint2D(x, y - 1); tileLeft = new IntPoint2D(x, y + 1); tileBehind = new IntPoint2D(x + 1, y); break; case ScenarioMgr.Direction.Up: tileLeft = new IntPoint2D(x - 1, y); tileAhead = new IntPoint2D(x, y - 1); tileBehind = new IntPoint2D(x, y + 1); tileRight = new IntPoint2D(x + 1, y); break; case ScenarioMgr.Direction.Right: tileBehind = new IntPoint2D(x - 1, y); tileRight = new IntPoint2D(x, y + 1); tileLeft = new IntPoint2D(x, y - 1); tileAhead = new IntPoint2D(x + 1, y); break; case ScenarioMgr.Direction.Down: tileRight = new IntPoint2D(x - 1, y); tileBehind = new IntPoint2D(x, y - 1); tileAhead = new IntPoint2D(x, y + 1); tileLeft = new IntPoint2D(x + 1, y); break; } startPos = transform.position; startAngle = gameObject.transform.rotation; bool goingNowhere = false; if (scenarioInfo.IsRoadTile(tileAhead)) { // no rotation required, just moving straight ahead rotating = false; nextFacing = facing; nextTile = tileAhead; } else { rotating = true; // we can't just go straight ahead, so we're doing some sort of rotation if (turningLeft) { // check left first if (scenarioInfo.IsRoadTile(tileLeft)) { // turning left nextTile = tileLeft; nextFacing = ScenarioMgr.GetLeftTurn(facing); } else if (scenarioInfo.IsRoadTile(tileRight)) { // turn right because we can't turn left nextTile = tileRight; nextFacing = ScenarioMgr.GetRightTurn(facing); } else if (scenarioInfo.IsRoadTile(tileBehind)) { nextTile = tileBehind; nextFacing = ScenarioMgr.GetReverseDirection(facing); } else { goingNowhere = true; rotating = false; } } else { // check right first if (scenarioInfo.IsRoadTile(tileRight)) { nextTile = tileRight; nextFacing = ScenarioMgr.GetRightTurn(facing); } else if (scenarioInfo.IsRoadTile(tileLeft)) { // turning left because we can't turn right nextTile = tileLeft; nextFacing = ScenarioMgr.GetLeftTurn(facing); } else if (scenarioInfo.IsRoadTile(tileBehind)) { nextTile = tileBehind; nextFacing = ScenarioMgr.GetReverseDirection(facing); } else { goingNowhere = true; rotating = false; } } } if (goingNowhere) { //Debug.Log("no road to move to"); // no rotation, no movement, no nothing -- just wait things out for a second yield return(new WaitForSeconds(tileMoveTime)); } else { // compute ending position switch (nextFacing) { case ScenarioMgr.Direction.Left: endPos = startPos + new Vector3(-1, 0, 0); endAngle = Quaternion.Euler(0, 180, 0); break; case ScenarioMgr.Direction.Up: endPos = startPos + new Vector3(0, 0, -1); endAngle = Quaternion.Euler(0, 90, 0); break; case ScenarioMgr.Direction.Down: endPos = startPos + new Vector3(0, 0, 1); endAngle = Quaternion.Euler(0, 270, 0); break; case ScenarioMgr.Direction.Right: endPos = startPos + new Vector3(1, 0, 0); endAngle = Quaternion.Euler(0, 0, 0); break; } float elapsedTime = 0; if (rotating) { // first handle the rotation while (elapsedTime < this.turnTime) { this.gameObject.transform.rotation = Quaternion.Slerp(startAngle, endAngle, (elapsedTime / this.turnTime)); elapsedTime += Time.deltaTime; yield return(0); } } //Debug.Log("starting movement from " + startPos.ToString() + " to " + endPos.ToString()); //Debug.Log("from tile " + curTile.ToString() + " to " + nextTile.ToString()); // move elapsedTime = 0; while (elapsedTime < this.tileMoveTime) { this.gameObject.transform.position = Vector3.Lerp(startPos, endPos, (elapsedTime / this.tileMoveTime)); elapsedTime += Time.deltaTime; yield return(0); } // fix data for next tile this.facing = nextFacing; this.curTile = nextTile; startPos = endPos; startAngle = endAngle; } tilesToGo--; } Destroy(gameObject); }