/// <summary> /// On each frame sets basic objects and starts player after round starts @todo: This is inefficient and should only be done once /// </summary> private void Update() { // Initialises basic objects playerCar = GameManager.instantiatedPlayer.transform.GetChild(0).gameObject.GetComponent <AVController>(); car = GameManager.instantiatedPlayer.transform.GetChild(0).gameObject; driver = car.transform.GetChild(4).gameObject; // Finds the player GameObject PlayerObject = GameObject.FindGameObjectWithTag("Player"); playCon = PlayerObject.GetComponent <PlayerController>(); // Spawns the player and starts the game after the round starts if (Time.time > startTime + waitTime && flag) { flag = false; StartCoroutine(GameLoop()); } //printing passenger pick up choices foreach (var xx in choices) { UnityEngine.Debug.Log(xx.ToString()); } }
protected void OnRowUpdating(object sender, GridViewUpdateEventArgs e) { try { // Get selected row GridViewRow row = AVDetailsGridView.Rows[e.RowIndex]; // Get page data string itemNo = (row.FindControl("LabelItemNo") as Label).Text; int qty = Int32.Parse((string)e.NewValues["Qty"]); string reason = (string)e.NewValues["Reason"]; // Update AVD (qty & reason) AVController.UpdateAVDetailQty(aVNo, itemNo, qty, reason); // Update page AVDetailsGridView.EditIndex = -1; SetPageAttributes(); BindGrid(); } catch (Exception exception) { // Alert user of error Session["Error"] = "An Error Has Occured: " + exception.Message; } }
/// <summary> /// Recreates the player path for the round /// </summary> /// <param name="roundNum">Integer representing the round's number (indexes from 0)</param> public void Pathing(int roundNum) { path = g.PathToFrom(startIDs[roundNum], endIDs[roundNum]); av = GetComponentInChildren <AVController>(); clearPath(); makePath(path); }
/// <summary> /// Generates a new path for the player based on the path provided /// If it is a new round then all AI car paths will be reset too /// </summary> /// <param name="path">List of all node IDs for the player to use as a path</param> /// <param name="newRound">Boolean indicating whether the path is being made for a new round</param> /// <param name="newCurrentNode">Integer indicating which is the next current node (used for changing existing paths)</param> public void makePath(List <string> path, bool newRound = true, int newCurrentNode = 0) { // Generate Node Elements for path GameObject NodeGameObject = PathGameObject.transform.GetChild(0).gameObject; bool isFirst = true; Vector3 nodePos; foreach (string nodeID in path) { Graph.Node node = g.nodeIdNodeDict[nodeID]; Vector2d xy = world.toXY(node.lat, node.lon); nodePos = new Vector3((float)xy[0], 0.71f, (float)xy[1]); if (isFirst) { NodeGameObject.transform.position = (nodePos); isFirst = false; } else { GameObject childObject = Instantiate(NodeGameObject) as GameObject; childObject.transform.position = (nodePos); childObject.transform.SetParent(PathGameObject.transform); } } av = GetComponentInChildren <AVController>(); av.setPath(path); av.currentNode = newCurrentNode; av.resetPaths(newRound); av.setOneWayRoads(path); }
/// <summary> /// Changes the player's path by picking a new intermediate point and constructing a path that goes via it /// </summary> public void changePath() { // Get next location and end locations GameObject playerCarObject = GameObject.FindGameObjectWithTag("DriverCar"); AVController playerAV = playerCarObject.GetComponent <AVController>(); List <string> pathList = playerAV.pathList; int currentNode = playerAV.currentNode; string startNodeID = pathList[0]; string nextNodeID = pathList[currentNode]; string endNodeID = pathList[pathList.Count - 1]; // Make a pathSet from pathList for faster lookups HashSet <string> pathSet = new HashSet <string>(); foreach (string str in pathList) { pathSet.Add(str); } // Select an intermediate point string intNodeID = selectIntermediateNode(nextNodeID, pathSet); // Construct the path List <string> pathToNext = g.PathToFrom(startNodeID, nextNodeID); List <string> newPath = g.PathToFrom(nextNodeID, intNodeID); List <string> pathToEnd = g.PathToFromExclude(intNodeID, endNodeID, newPath[newPath.Count - 2]); int i = 0; foreach (string str in newPath) { if (i > 0) { pathToNext.Add(str); } i++; } i = 0; foreach (string str in pathToEnd) { if (i > 0) { pathToNext.Add(str); } i++; } // Replace the player path with the new script GameObject PlayerObject = GameObject.FindGameObjectWithTag("Player"); PlayerController pc = PlayerObject.GetComponent <PlayerController>(); pc.clearPath(); pc.makePath(pathToNext, false, currentNode); }
private void BindGrid() { // Get Pending Adjustment Vouchers belonging to this User pendingAdjustmentVouchers = AVController.GetPendingAdjustmentVouchersByIssueEmp(Profile.EmpNo); // Bind GridView PendingAdjustmentVoucherGridView.DataSource = pendingAdjustmentVouchers.Select(aV => new { AvNo = aV.AvNo, DateIssued = aV.DateIssued, Status = aV.Status }); PendingAdjustmentVoucherGridView.DataBind(); }
protected void PendingAdjustmentVoucherGridView_Delete(object sender, GridViewDeleteEventArgs e) { try { int aVNo = Int32.Parse(PendingAdjustmentVoucherGridView.Rows[e.RowIndex].Cells[0].Text); AVController.DeleteAV(aVNo); BindGrid(); Session["AVProcessed"] = aVNo; } catch (Exception exception) { Session["Error"] = " " + exception.Message; } }
/// <summary> /// Start is called before the first frame update to instantiate dynamic objects /// </summary> void Start() { GameObject PlayerObject = GameObject.FindGameObjectWithTag("Player"); PathGameObject = PlayerObject.transform.Find("Path").gameObject; av = GetComponentInChildren <AVController>(); // Set spawn GameObject SpawnObject = PlayerObject.transform.Find("Spawn").gameObject; GameObject SpawnPointObject = SpawnObject.transform.Find("SpawnPoint").gameObject; g = GameObject.Find("Graph").GetComponent <GraphController>().graph; }
private void BindGrid() { // Set DataGrid AVDetailsGridView.DataSource = aVDetails.Select( aVD => new { ItemNo = aVD.ItemNo, ItemDescription = aVD.StationeryCatalogue.Description, Qty = aVD.Qty, UnitPrice = AVController.GetUnitPrice(aVD.ItemNo, aVD.StationeryCatalogue.Supplier1), AdjustmentAmount = AVController.GetUnitPrice(aVD.ItemNo, aVD.StationeryCatalogue.Supplier1) * aVD.Qty, Reason = aVD.Reason }); AVDetailsGridView.DataBind(); }
protected void Button_Click(object sender, EventArgs e) { try { Button buttonPressed = (Button)sender; if (buttonPressed.CommandArgument == "Delete") { // Delete AV AVController.DeleteAV(aVNo); Session["AVProcessed"] = (int)Session["AVNo"]; } } catch (Exception exception) { // Alert user of error Session["Error"] = "An Error Has Occured: " + exception.Message; } if (Session["Error"] == null) { GoToAdjustmentVoucherListPage(); } }
protected void OnRowDeleting(object sender, GridViewDeleteEventArgs e) { try { // Get selected row GridViewRow row = AVDetailsGridView.Rows[e.RowIndex]; // Get page data string itemNo = (row.FindControl("LabelItemNo") as Label).Text; // Delete AVD AVController.DeleteAVD(aVNo, itemNo); // UpdatePage SetPageAttributes(); BindGrid(); } catch (Exception exception) { // Alert user of error Session["Error"] = "An Error Has Occured: " + exception.Message; } }
/// <summary> /// Sets the path for the car gameobject and places it in the world /// </summary> /// <param name="CarObject">GameObject representing the AI car</param> /// <param name="path">List of nodes for the car to travel to which form a path</param> /// <param name="dumbCarID">Integer identifying the car</param> /// <param name="smart">Boolean indicating whether the car is smart or not</param> private void setAICarParams(GameObject CarObject, List <string> path, int dumbCarID, bool smart) { // Make path from start to end GameObject PathGameObject = CarObject.transform.Find("Path").gameObject; if (!useCachedPath) { //Path thisPath = new Path() { nodeIDs = path }; DumbCar thisCar = new DumbCar(); thisCar.id = dumbCarID; //thisCar.path = path.ToArray(); dumbCars.Add(thisCar); // NOTE: seems to add all cars whether they are dumb or not //paths.Add(thisPath); } makePath(PathGameObject, g, path); AVController av = CarObject.GetComponentInChildren <AVController>(); Vector3 offset = av.setOneWayRoads(path); av.setPath(path); av.isSmart = smart; // Set spawn GameObject SpawnObject = CarObject.transform.Find("Spawn").gameObject; GameObject SpawnPointObject = SpawnObject.transform.Find("SpawnPoint").gameObject; Graph.Node startingNode = g.nodeIdNodeDict[path[0]]; Vector2d xy = world.toXY(startingNode.lat, startingNode.lon); if (smart) { av.roundOver = false; av.TP2Start(); } //SpawnPointObject.transform.position = new Vector3((float)xy[0], 0.71f, (float)xy[1]) + transform.InverseTransformPoint(offset); }
private void setAICarParams(GameObject CarObject, List <string> path, int dumbCarID) { // Make path from start to end GameObject PathGameObject = CarObject.transform.Find("Path").gameObject; if (!useCachedPath) { //Path thisPath = new Path() { nodeIDs = path }; DumbCar thisCar = new DumbCar(); thisCar.id = dumbCarID; thisCar.path = path.ToArray(); dumbCars.Add(thisCar); //paths.Add(thisPath); } makePath(PathGameObject, g, path); AVController av = CarObject.GetComponentInChildren <AVController>(); Vector3 offset = av.setOneWayRoads(path); av.setPath(path); // Set spawn GameObject SpawnObject = CarObject.transform.Find("Spawn").gameObject; GameObject SpawnPointObject = SpawnObject.transform.Find("SpawnPoint").gameObject; Graph.Node startingNode = g.nodeIdNodeDict[path[0]]; UnityEngine.Debug.Log("StartingNode nodeId: " + startingNode.nodeId); UnityEngine.Debug.Log("StartingNode Lat: " + startingNode.lat); UnityEngine.Debug.Log("StartingNode Lon: " + startingNode.lon); Vector2d xy = world.toXY(startingNode.lat, startingNode.lon); UnityEngine.Debug.Log("X: " + xy[0]); UnityEngine.Debug.Log("Y: " + xy[1]); //SpawnPointObject.transform.position = new Vector3((float)xy[0], 0.71f, (float)xy[1]) + transform.InverseTransformPoint(offset); }
/// <summary> /// On every fixed frame update, will check how the car should react to its conditions /// </summary> private void FixedUpdate() { frameCount++; /*if (gameObject.transform.parent.gameObject.name == "AICar(Clone)") * { * var player = GameObject.Find("Player"); * if (player) * { * UnityEngine.Debug.Log("Player object found"); * //float distance = Vector3.Distance(player.transform.position, gameObject.transform.position); * //UnityEngine.Debug.Log("Distance from player: " + distance); * * } * }*/ // Sleep if the round is over if (roundOver) { foreach (AxleInfo axleInfo in axleInfos) { axleInfo.leftWheel.motorTorque = 0; axleInfo.rightWheel.motorTorque = 0; } GetComponent <Rigidbody>().Sleep(); return; } // Remove AICar if at end of path if (gameObject.transform.parent.gameObject.name == "AICar(Clone)" && haveReachedDestination) { UnityEngine.Debug.Log("Destroyed Car"); GetComponent <Rigidbody>().Sleep(); Destroy(gameObject.transform.parent.gameObject); return; } //Stop movement if game timer is paused // OR if reached the end of nodes if (currentNode == -1 || (timer != null && timer.isPaused()) || haveReachedDestination) { if (haveReachedDestination && !roundOver) { sm.driverReachedDest = true; haveReachedDestination = false; } foreach (AxleInfo axleInfo in axleInfos) { axleInfo.leftWheel.motorTorque = 0; axleInfo.rightWheel.motorTorque = 0; } GetComponent <Rigidbody>().Sleep(); return; } var distanceToNode = Vector3.Distance(transform.position, nodes[currentNode].position); // If close to node if (distanceToNode < 20f && distanceToNode > 5f) { // Check if traffic light if (pathList.Count > 1 && currentNode > 0 && trafficLightController.trafficCheck(pathList[currentNode - 1], pathList[currentNode])) { if (!isAtTrafficLight) { isAtTrafficLight = true; UnityEngine.Debug.Log("Now at Traffic Light"); } foreach (AxleInfo axleInfo in axleInfos) { axleInfo.leftWheel.motorTorque = 0; axleInfo.rightWheel.motorTorque = 0; } GetComponent <Rigidbody>().Sleep(); return; } else { if (isAtTrafficLight) { UnityEngine.Debug.Log("Now no longer at Traffic Light"); } isAtTrafficLight = false; } //check for intersection and then raycast if needed if (pathList.Count > 1 && currentNode > 0 && !g.trafficLights.Contains(pathList[currentNode]) && isIntersection(pathList[currentNode]) && !isAtIntersection) { Vector3 centre = nodes[currentNode].position; bool clear = true; LayerMask layer = LayerMask.GetMask("Cars"); //check intersection is clear Collider[] hits = Physics.OverlapBox(centre, transform.localScale * 50, Quaternion.identity, layer, QueryTriggerInteraction.Ignore); UnityEngine.Debug.Log(hits.Length + " cars detected in intersection"); foreach (Collider collider in hits) { if (collider == GetComponent <Collider>()) { continue; } var other = collider.gameObject.GetComponent <AVController>(); if (!other.isAtIntersection || !other.isAtIntersection) { continue; } Vector3 direction = collider.transform.forward; float dot = Vector3.Dot(direction, transform.forward); if (dot > 0.5) // other car is travelling in same direction { continue; } else if (true) { clear = false; } } if (turning == turningDirection.left) { // check to the right hits = Physics.OverlapBox(centre + transform.right * castDistance, new Vector3(2, 1, 1) * castDistance, transform.rotation, layer, QueryTriggerInteraction.Ignore); UnityEngine.Debug.Log(hits.Length + " cars detected to the right when turning left."); foreach (Collider collider in hits) { if (collider == this.GetComponent <Collider>()) { continue; } AVController other = collider.gameObject.GetComponent <AVController>(); Vector3 direction = collider.transform.forward; float dot = Vector3.Dot(direction, transform.right); if (dot < 0) // other car is travelling left, i.e. towards this car { if (other.isAtIntersection || other.isAtTrafficLight) { continue; } // ignore cars that don't impede movement if (((int)currentBearing + 1) % 4 == (int)other.currentBearing) { UnityEngine.Debug.Log("Turning Left: Ignoring car coming from clockwise direction"); continue; } else if ((((int)currentBearing + 4) - 1) % 4 == (int)other.currentBearing && (other.turning == turningDirection.left || other.turning == turningDirection.right)) { UnityEngine.Debug.Log("Turning Left: Ignoring car coming from anti-clokwise direction turning left or right"); continue; } else if (Math.Abs(currentBearing - other.currentBearing) == 2 && (other.turning == turningDirection.left || other.turning == turningDirection.forward)) { UnityEngine.Debug.Log("Turning Left: Ignoring car coming in opposite direction going forward or turning left"); continue; } // ignore cars which give way to you if (other.braking) { continue; } // ignore cars with lower priority if (other.roadPriority < roadPriority) { continue; } if (other.stopTime < 1 || other.stopTime > stopTime) { clear = false; } } } } else if (turning == turningDirection.forward) { // check to the right hits = Physics.OverlapBox(centre + transform.right * castDistance, new Vector3(2, 1, 1) * castDistance, transform.rotation, layer, QueryTriggerInteraction.Ignore); UnityEngine.Debug.Log(hits.Length + " cars detected to the right when going forward."); foreach (Collider collider in hits) { Vector3 direction = collider.transform.forward; float dot = Vector3.Dot(direction, transform.right); if (dot < 0) { if (collider == this.GetComponent <Collider>()) { continue; } AVController other = collider.gameObject.GetComponent <AVController>(); if (other.isAtIntersection || other.isAtTrafficLight) { continue; } if (other.braking) { continue; } // ignore cars with lower priority if (other.roadPriority < roadPriority) { continue; } if (other.stopTime < 1 || other.stopTime > stopTime) { clear = false; } } } // check to the left hits = Physics.OverlapBox(centre - transform.right * 20, new Vector3(2, 1, 1) * 20, transform.rotation, layer, QueryTriggerInteraction.Ignore); UnityEngine.Debug.Log(hits.Length + " cars detected to the left when going forward."); foreach (Collider collider in hits) { Vector3 direction = collider.transform.forward; float dot = Vector3.Dot(direction, -transform.right); if (dot > 0) { if (collider == this.GetComponent <Collider>()) { continue; } AVController other = collider.gameObject.GetComponent <AVController>(); if (other.isAtIntersection || other.isAtTrafficLight) { continue; } if (other.braking) { continue; } if (other.roadPriority < roadPriority) { continue; } // ignore cars that don't impede movement //if (other.roadPriority == roadPriority && (other.turning == AVController.direction.forward || other.turning == AVController.direction.left)) continue; if (other.stopTime < 1 || other.stopTime > stopTime) { clear = false; } } } // check forward /*hits = Physics.OverlapBox(centre + transform.forward * 5, new Vector3(1, 1, 2) * 5, transform.rotation, layer, QueryTriggerInteraction.Ignore); * foreach (Collider collider in hits) * { * Vector3 direction = collider.transform.forward; * float dot = Vector3.Dot(direction, transform.forward); * if (dot < 0) * { * if (collider == this.GetComponent<Collider>()) continue; * AVController other = collider.gameObject.GetComponent<AVController>(); * //if (other.inIntersection) continue; * * //if (other.braking) continue; * * if (currentBearing == other.currentBearing) * { * UnityEngine.Debug.Log("Going forward: Car in front going in the same direction"); * * foreach (AxleInfo axleInfo in axleInfos) * { * axleInfo.leftWheel.brakeTorque = maxMotorTorque; * axleInfo.rightWheel.brakeTorque = maxMotorTorque; * } * braking = true; * GetComponent<Rigidbody>().Sleep(); * return; * } * else * { * UnityEngine.Debug.Log("Going forward: Hitting a car so not clear"); * clear = false; * } * * * } * }*/ } else // turning right { // check to the right hits = Physics.OverlapBox(centre + transform.right * 20, new Vector3(2, 1, 1) * 20, transform.rotation, layer, QueryTriggerInteraction.Ignore); UnityEngine.Debug.Log(hits.Length + " cars detected to the right when turning right."); foreach (Collider collider in hits) { Vector3 direction = collider.transform.forward; float dot = Vector3.Dot(direction, transform.right); if (dot < 0) { if (collider == this.GetComponent <Collider>()) { continue; } AVController other = collider.gameObject.GetComponent <AVController>(); if (other.isAtIntersection || other.isAtTrafficLight) { continue; } if (other.braking) { continue; } if (other.roadPriority < roadPriority) { continue; } // ignore cars that don't impede movement //if (other.roadPriority == roadPriority && other.turning == AVController.direction.right) continue; if (other.stopTime < 1 || other.stopTime > stopTime) { clear = false; } } } // check to the left hits = Physics.OverlapBox(centre - transform.right * 20, new Vector3(2, 1, 1) * 20, transform.rotation, layer, QueryTriggerInteraction.Ignore); UnityEngine.Debug.Log(hits.Length + " cars detected to the left when turning right."); foreach (Collider collider in hits) { if (collider == this.GetComponent <Collider>()) { continue; } AVController other = collider.gameObject.GetComponent <AVController>(); if (Math.Abs(currentBearing - other.currentBearing) == 2 && other.turning == AVController.turningDirection.right) { UnityEngine.Debug.Log("Turning Right: Ignoring car coming in opposite direction turning right"); continue; } Vector3 direction = collider.transform.forward; float dot = Vector3.Dot(direction, -transform.right); if (dot > 0) { if (other.isAtIntersection || other.isAtTrafficLight) { continue; } if (other.braking) { continue; } if (other.roadPriority < roadPriority) { continue; } // ignore cars that don't impede movement //if (other.roadPriority == roadPriority && other.turning == AVController.direction.right) continue; if (other.stopTime < 1 || other.stopTime > stopTime) { clear = false; } } } // check forward hits = Physics.OverlapBox(centre + transform.forward * 20, new Vector3(1, 1, 2) * 20, transform.rotation, layer, QueryTriggerInteraction.Ignore); UnityEngine.Debug.Log(hits.Length + " cars detected forward when turning right."); foreach (Collider collider in hits) { if (collider == this.GetComponent <Collider>()) { continue; } AVController other = collider.gameObject.GetComponent <AVController>(); if (Math.Abs(currentBearing - other.currentBearing) == 2 && other.turning == AVController.turningDirection.right) { UnityEngine.Debug.Log("Turning Right: Ignoring car coming in opposite direction turning right"); continue; } Vector3 direction = collider.transform.forward; float dot = Vector3.Dot(direction, transform.forward); if (dot < 0) { if (other.isAtIntersection) { continue; } if (other.braking) { continue; } if (other.roadPriority < roadPriority) { continue; } // ignore cars that don't impede movement //if (other.roadPriority == roadPriority && other.turning == AVController.direction.right) continue; if (other.stopTime < 1 || other.stopTime > stopTime) { clear = false; } } } } if (clear) { isAtIntersection = true; stopTime = UnityEngine.Random.Range(0f, 1f); StartCoroutine("Intersection"); } else { stopTime += 1; if (!stopped) { StartCoroutine("Stop"); } } } } //Update wheel positions based on speed and angle Vector3 relativeVector = transform.InverseTransformPoint(nodes[currentNode].position) + new Vector3(-drivingOffset, 0, 0); float newSteer = (relativeVector.x / relativeVector.magnitude) * maxSteerAngle; foreach (AxleInfo axleInfo in axleInfos) { currentSpeed = 2 * Mathf.PI * axleInfo.leftWheel.radius * axleInfo.leftWheel.rpm * 60 / 1000; if (axleInfo.steering) { axleInfo.leftWheel.steerAngle = newSteer; axleInfo.rightWheel.steerAngle = newSteer; } if (axleInfo.motor) { if (currentSpeed < maxSpeed) { axleInfo.leftWheel.motorTorque = maxMotorTorque; axleInfo.rightWheel.motorTorque = maxMotorTorque; } else { axleInfo.leftWheel.motorTorque = 0; axleInfo.rightWheel.motorTorque = 0; } } lastSpeed = currentSpeed; ApplyLocalPositionToVisuals(axleInfo.leftWheel); ApplyLocalPositionToVisuals(axleInfo.rightWheel); } if (currentSpeed == 0 && !isAtTrafficLight) { consecutiveFramesWithNoSpeed++; if (consecutiveFramesWithNoSpeed > minConsecutiveFramesWithNoSpeed) { var newFps = 1 / Time.unscaledDeltaTime; if (newFps >= 25) { fps = newFps; UnityEngine.Debug.Log("FPS:" + fps); } var consecutiveSecondsWithNoSpeed = consecutiveFramesWithNoSpeed / fps; UnityEngine.Debug.Log("Consecutive seconds with no speed:" + consecutiveSecondsWithNoSpeed); if (consecutiveSecondsWithNoSpeed >= minConsecutiveSecondsWithNoSpeed) { var randomNumber = UnityEngine.Random.Range(minConsecutiveSecondsWithNoSpeed, maxConsecutiveSecondsWithNoSpeed); if (randomNumber < consecutiveFramesWithNoSpeed) { if (nodes.Count > 1) { currentNode--; gameObject.transform.position = nodes[currentNode].position; gameObject.transform.LookAt(nodes[currentNode + 1]); gameObject.transform.position = transform.TransformPoint(new Vector3(-drivingOffset, 0, 0)); UnityEngine.Debug.Log("Have been stationary for awhile, moving back to previous node"); } consecutiveFramesWithNoSpeed = 0; } } } } else { consecutiveFramesWithNoSpeed = 0; } CheckWaypointDistance(); UpdateSteeringWheel(); }
private void SetPageAttributes() { aVNo = (int)Session["AVNo"]; aV = AVController.GetAdjustmentVoucher(aVNo); aVDetails = AVController.GetAVDetails(aVNo); }
/// <summary> /// On every fixed frame update, will check how the car should react to its conditions /// </summary> private void FixedUpdate() { // Sleep if the round is over if(roundOver) { foreach (AxleInfo axleInfo in axleInfos) { axleInfo.leftWheel.motorTorque = 0; axleInfo.rightWheel.motorTorque = 0; } GetComponent<Rigidbody>().Sleep(); return; } // Remove AICar if at end of path if (gameObject.transform.parent.gameObject.name == "AICar(Clone)" && reachedDestination) { UnityEngine.Debug.Log("Destroyed Car"); GetComponent<Rigidbody>().Sleep(); Destroy(gameObject.transform.parent.gameObject); return; } //Stop movement if game timer is paused // OR if reached the end of nodes if (currentNode == -1 || (timer != null && timer.isPaused()) || reachedDestination) { if (reachedDestination && !roundOver) { sm.driverReachedDest = true; reachedDestination = false; } foreach (AxleInfo axleInfo in axleInfos) { axleInfo.leftWheel.motorTorque = 0; axleInfo.rightWheel.motorTorque = 0; } GetComponent<Rigidbody>().Sleep(); return; } // If close to node if (Vector3.Distance(transform.position, nodes[currentNode].position) < 20f && Vector3.Distance(transform.position, nodes[currentNode].position) > 5f) { // Check if traffic light if (pathList.Count > 1 && currentNode > 0 && trafficLightController.trafficCheck(pathList[currentNode - 1], pathList[currentNode])) { //UnityEngine.Debug.Log("At Traffic Light"); foreach (AxleInfo axleInfo in axleInfos) { axleInfo.leftWheel.motorTorque = 0; axleInfo.rightWheel.motorTorque = 0; } GetComponent<Rigidbody>().Sleep(); return; } //check for intersection and then raycast if needed else if (pathList.Count > 1 && currentNode > 0 && !g.trafficLights.Contains(pathList[currentNode]) && isIntersection(pathList[currentNode]) && !inIntersection) { Vector3 centre = nodes[currentNode].position; bool clear = true; LayerMask layer = LayerMask.GetMask("Cars"); //check intersection is clear Collider[] hits = Physics.OverlapBox(centre, transform.localScale * 50, Quaternion.identity, layer, QueryTriggerInteraction.Ignore); foreach (Collider collider in hits) { if (collider != this.GetComponent<Collider>()) { if (collider.gameObject.GetComponent<AVController>().inIntersection) { Vector3 direction = collider.transform.forward; float dot = Vector3.Dot(direction, transform.forward); if (dot > 0.5) // other car is travelling in same direction { continue; } else if (true) { clear = false; } } } } if (turning == direction.left) { // check to the right hits = Physics.OverlapBox(centre + transform.right * 20, new Vector3(2,1,1) * 20, transform.rotation, layer, QueryTriggerInteraction.Ignore); foreach (Collider collider in hits) { Vector3 direction = collider.transform.forward; float dot = Vector3.Dot(direction, transform.right); if (dot < 0) // other car is travelling left, i.e. towards this car { if (collider == this.GetComponent<Collider>()) continue; AVController other = collider.gameObject.GetComponent<AVController>(); if (other.inIntersection) continue; // ignore cars which give way to you if (other.braking) continue; if (other.roadPriority < roadPriority) continue; if (other.stopTime < 1 || other.stopTime > stopTime) { clear = false; } } } } else if (turning == direction.forward) { // check to the right hits = Physics.OverlapBox(centre + transform.right * 20, new Vector3(2,1,1) * 20, transform.rotation, layer, QueryTriggerInteraction.Ignore); foreach (Collider collider in hits) { Vector3 direction = collider.transform.forward; float dot = Vector3.Dot(direction, transform.right); if (dot < 0) { if (collider == this.GetComponent<Collider>()) continue; AVController other = collider.gameObject.GetComponent<AVController>(); if (other.inIntersection) continue; if (other.braking) continue; if (other.roadPriority < roadPriority) continue; if (other.stopTime < 1 || other.stopTime > stopTime) { clear = false; } } } // check to the left hits = Physics.OverlapBox(centre - transform.right * 20, new Vector3(2,1,1) * 20, transform.rotation, layer, QueryTriggerInteraction.Ignore); foreach (Collider collider in hits) { Vector3 direction = collider.transform.forward; float dot = Vector3.Dot(direction, -transform.right); if (dot > 0) { if (collider == this.GetComponent<Collider>()) continue; AVController other = collider.gameObject.GetComponent<AVController>(); if (other.inIntersection) continue; if (other.braking) continue; if (other.roadPriority < roadPriority) continue; if (other.stopTime < 1 || other.stopTime > stopTime) { clear = false; } } } } else // turning right { // check to the right hits = Physics.OverlapBox(centre + transform.right * 20, new Vector3(2,1,1) * 20, transform.rotation, layer, QueryTriggerInteraction.Ignore); foreach (Collider collider in hits) { Vector3 direction = collider.transform.forward; float dot = Vector3.Dot(direction, transform.right); if (dot < 0) { if (collider == this.GetComponent<Collider>()) continue; AVController other = collider.gameObject.GetComponent<AVController>(); if (other.inIntersection) continue; if (other.braking) continue; if (other.roadPriority < roadPriority) continue; if (other.stopTime < 1 || other.stopTime > stopTime) { clear = false; } } } // check to the left hits = Physics.OverlapBox(centre - transform.right * 20, new Vector3(2,1,1) * 20, transform.rotation, layer, QueryTriggerInteraction.Ignore); foreach (Collider collider in hits) { Vector3 direction = collider.transform.forward; float dot = Vector3.Dot(direction, -transform.right); if (dot > 0) { if (collider == this.GetComponent<Collider>()) continue; AVController other = collider.gameObject.GetComponent<AVController>(); if (other.inIntersection) continue; if (other.braking) continue; if (other.roadPriority < roadPriority) continue; if (other.stopTime < 1 || other.stopTime > stopTime) { clear = false; } } } // check forward hits = Physics.OverlapBox(centre + transform.forward * 20, new Vector3(1,1,2) * 20, transform.rotation, layer, QueryTriggerInteraction.Ignore); foreach (Collider collider in hits) { Vector3 direction = collider.transform.forward; float dot = Vector3.Dot(direction, transform.forward); if (dot < 0) { if (collider == this.GetComponent<Collider>()) continue; AVController other = collider.gameObject.GetComponent<AVController>(); if (other.inIntersection) continue; if (other.braking) continue; if (other.roadPriority < roadPriority) continue; if (other.stopTime < 1 || other.stopTime > stopTime) { clear = false; } } } } if(clear) { inIntersection = true; stopTime = UnityEngine.Random.Range(0f, 1f); StartCoroutine("Intersection"); } else { stopTime += 1; if (!stopped) { StartCoroutine("Stop"); } } } } //Update wheel positions based on speed and angle Vector3 relativeVector = transform.InverseTransformPoint(nodes[currentNode].position) + new Vector3(-drivingOffset, 0, 0); float newSteer = (relativeVector.x / relativeVector.magnitude) * maxSteerAngle; foreach (AxleInfo axleInfo in axleInfos) { currentSpeed = 2 * Mathf.PI * axleInfo.leftWheel.radius * axleInfo.leftWheel.rpm * 60 / 1000; if (axleInfo.steering) { axleInfo.leftWheel.steerAngle = newSteer; axleInfo.rightWheel.steerAngle = newSteer; } if (axleInfo.motor) { if (currentSpeed < maxSpeed) { axleInfo.leftWheel.motorTorque = maxMotorTorque; axleInfo.rightWheel.motorTorque = maxMotorTorque; } else { axleInfo.leftWheel.motorTorque = 0; axleInfo.rightWheel.motorTorque = 0; } } ApplyLocalPositionToVisuals(axleInfo.leftWheel); ApplyLocalPositionToVisuals(axleInfo.rightWheel); } CheckWaypointDistance(); UpdateSteeringWheel(); }