// Update is called once per frame public void Update() { if (group && group.goals == null) { group = null; goal = null; } if (!paused) { if (GridManagerScript.enableCollisions && avatar.GetComponent <Trigger>().stop) { return; } //sanity check if (nextNode == null || currentNode == null || currentNode.FindEdgeTo(nextNode) == null) { return; } //update a the path when end is closed if (GridManagerScript.usingAStarOnly && (AStarPath.Count == 0 || (entering && !AStarPath.Last().goal))) { Debug.Log("NewPath " + AStarPath.Last()); indexAtAstarPath = 0; AStarPath = GridManagerScript.AStar. GenerateEntryPath(currentNode, group != null? group.goals.ToArray() : null); nextNode = GetBestDiffusionNode(currentNode); } if (!GridManagerScript.isTest) { float speedLimit = GridManagerScript.citySpeed; //get the edge speed and calculate speed limit if it exist, else assume no difference //calc traffic EdgeScript edge = currentNode.FindEdgeTo(nextNode); if (currentNode != null && edge != null) { //speed in miles per hour //0.0003miles/s = 0.066p/second per second (fs - fake seconds) speedLimit = edge.GetSpeed(); //GET THIS CHECKED OUT // speedLimit = speedLimit - speedLimit * (edge.nodesTraffic / EdgeScript.maxTraffic) * EdgeScript.maxTrafficP; } if (GridManagerScript.accelerationCalculations) { //if the next node is the parking node and avatar has some speed0 slow down if (nextNode.openParking && (nextNode.NodeStatus == NodeScript.NODE_STATUS.END && atmSpeed >= (speedLimit * parkingSpeed))) { atmSpeed -= atmSpeed * (decceleration * 2); } //else accelerate// decelerate else { //calc deceleration //if above speed limit or if (atmSpeed > speedLimit) { atmSpeed -= atmSpeed * decceleration; } //calc acceleration else if (atmSpeed < speedLimit) { acceleration = acceleration * accelerationSteepness; atmSpeed += atmSpeed * acceleration; if (atmSpeed > speedLimit) { atmSpeed = speedLimit; //skip coming into calculations for dec or acc next time } } } speedLimit = atmSpeed; } //foreach frame translate //checkout 123 for explanation //1 mile irl = 240p in game //add about 20p to make up for inconsistency of time.deltatime //every update calc how much of a second has passed in game and add it on the speed float speedinpixels = (speedLimit * 260) / 3600; //mile/h float translatePerFrame = speedinpixels * GridManagerScript.secondsPerSecond * Time.deltaTime; Vector3 translateAvatar = avatar.transform.position + (nextNode.transform.position - avatar.transform.position).normalized * translatePerFrame; //vector to translate by //get the distance between avatar and goal and see if you're overshooting //if you're not overshooting just continue //if you are overshooting just arrive //Db (distance before) is hypothenos from origin to goal (basic distance) //Da (distance after) is the hypothenos from origin to the potential new destination (towards goal) float Db = Vector3.Distance(avatar.transform.position, nextNode.transform.position); float Da = Vector3.Distance(avatar.transform.position, translateAvatar); if (Da > Db) { avatar.transform.position = nextNode.transform.position; } else { avatar.transform.position = translateAvatar; } } else { avatar.transform.position = avatar.transform.position + (nextNode.transform.position - avatar.transform.position).normalized; } // Check if the avatar is within the bounds of the next node's centre if (avatar.transform.position.x >= nextNode.transform.position.x - 1.0f && avatar.transform.position.y >= nextNode.transform.position.y - 1.0f && avatar.transform.position.z >= nextNode.transform.position.z - 1.0f && avatar.transform.position.x <= nextNode.transform.position.x + 1.0f && avatar.transform.position.y <= nextNode.transform.position.y + 1.0f && avatar.transform.position.z <= nextNode.transform.position.z + 1.0f) { double timeOfDay = getTimeOfDay(); currentNode.FindEdgeTo(nextNode).removeOccupancy(timeOfDay); // If not at the destination //TODO REWRITE THIS CHECK AND THE ONES BELOW //if no specific goal any goals count //if specific goal, all goals count if ((goal == null && ((nextNode.NodeStatus != NodeScript.NODE_STATUS.END && !isCityAvatar) || (!nextNode.goal && isCityAvatar && entering) || (!nextNode.exit && isCityAvatar && !entering))) || (goal != null && goal != nextNode)) { //set the previous node to the current node previousNode = currentNode; // Set the current node as the next node currentNode = nextNode; // Calculate the next node if (entering) { nextNode = GetBestDiffusionNode(nextNode); } else { nextNode = GetBestExitDiffusionNode(nextNode); } currentNode.FindEdgeTo(nextNode).addOccupancy(timeOfDay); totalPathLength += currentNode.FindEdgeTo(nextNode).roadLen; } else { // check if destination reached is in goals //if goal is not specified arrive at any of the goals //if goal is specified only arrive at the given goal //only arrive at redir goal if ((goal == null && (group == null || group.goals == null || (group.goals.Contains(nextNode) || (redirected && group.redirectToGoals.Contains(nextNode))) || !entering)) || (goal == nextNode)) { //reset the overlapping avatars on the node behind you //if(GridManagerScript.isTest) currentNode.avatarsOverlapping = -1; // If your destination was a parking lot add a car to the lot if ((entering && nextNode.goal && nextNode.GetComponentInParent <ParkingLot>() || goal == nextNode)) { timeArrived = (float)timeOfDay; //get the current time timeLeftArrivedVTCAll.Add(new Tuple <float, float, float>(timeLeft, timeArrived, totalPathLength)); nextNode.GetComponentInParent <ParkingLot>().AddCar(this); endReached = true; } else if (!entering) { endReached = true; } } //go to the actual goal else { //set the previous node to the current node previousNode = currentNode; // Set the current node as the next node currentNode = nextNode; // Calculate the next node //passes current end that is not it's own goal nextNode = GetBestDiffusionNode(nextNode); currentNode.FindEdgeTo(nextNode).addOccupancy(timeOfDay); totalPathLength += currentNode.FindEdgeTo(nextNode).roadLen; } } } } }