public RaceLinePoint getNextPoint(RaceLinePoint aCurrent) { for(int i = 0;i<points.Length-1;i++) { if(points[i]==aCurrent) { return points[i+1]; } } return points[points.Length-1]; }
private bool findAltRacingLine(bool aShorterOnly) { List<RacingLine> allRacingLines = RaceTrack.REF.racingLines; for(int i = 0;i<allRacingLines.Count;i++) { bool a = (i>0&&allRacingLines[i-1]==this.myRacingLine); bool b = (i<allRacingLines.Count-1&&allRacingLines[i+1]==this.myRacingLine); if(a||b) { RaceLinePoint r = allRacingLines[i].pointAtIndex(currentPoint.thisIndex); float currentDistanceToFinish = this.currentPoint.distanceToFinish+(Vector3.Distance(this.transform.position,this.currentPoint.transform.position)); float altLineDistanceToFinish = r.distanceToFinish+(Vector3.Distance(this.transform.position,r.transform.position)); bool shorter = altLineDistanceToFinish<currentDistanceToFinish; if(!aShorterOnly||altLineDistanceToFinish<currentDistanceToFinish) { // We want to move to a different race line if we can RaceLinePoint p = allRacingLines[i].pointAtIndex(currentPoint.thisIndex-1); Vector3 there = p.transform.position; Vector3 diff = p.transform.position-this.transform.position; float dist = Vector3.Distance(allRacingLines[i].pointAtIndex(currentPoint.thisIndex-1).transform.position,this.transform.position); // Spherecast towards the current point on this line, if there is something there, lets RaycastHit hit; float distanceToObstacle = 0; // Cast a sphere wrapping character controller 10 meters forward // to see if it is about to hit anything. Vector3 here = this.transform.position; here.y += 1f; there.y += 1f; Vector3 left = (this.transform.right*-1)*(Vector3.Distance(here,there))+this.transform.position; Vector3 right = (this.transform.right)*(Vector3.Distance(here,there))+this.transform.position; left.y+=1f; right.y+=1f; // I don't know whether this is on left or right of us right now, lets see whats closest to "There" Vector3 sideways = right; if(Vector3.Distance(left,there)<Vector3.Distance(right,there)) { sideways = left; } Vector3 infrontAndLeftDiff = there-sideways; Vector3 behind = sideways-infrontAndLeftDiff; Vector3 behindDouble = sideways-infrontAndLeftDiff*3; Vector3 infrontAndSide = sideways+infrontAndLeftDiff/2; if((this.horseInTargetLaneAtVector(here,there,allRacingLines[i])!=null)|| (this.horseInTargetLaneAtVector(here,sideways,allRacingLines[i])!=null)|| (this.horseInTargetLaneAtVector(here,behind,allRacingLines[i])!=null)|| (this.horseInTargetLaneAtVector(here,infrontAndSide,allRacingLines[i])!=null)|| (this.horseInTargetLaneAtVector(here,behindDouble,allRacingLines[i])!=null)) { } else { this.myRacingLine = allRacingLines[i]; if(currentPoint.thisIndex>0) prevPoint = allRacingLines[i].pointAtIndex(currentPoint.thisIndex-1); this.currentPoint = allRacingLines[i].pointAtIndex(currentPoint.thisIndex); useMidway = true; return true; } } } } // No suitable race line found return false; }
public void FixedUpdate () { if(!this.hasStarted) { return; } if(this.hasFinished) { handleFinishedHorse(); return; } if(currentPoint==null) initClosestPoint(); bool blocked = false; HorseController infront = this.horseInFront; // Debug.DrawRay(horseNose.position,this.transform.forward,Color.yellow); // Debug.DrawLine(this.transform.position,currentPoint.transform.position); if(Vector3.Distance(currentPoint.transform.position,this.transform.position)<closenessToNextPoint) { // We're looking ahead forward for the next race point now, lets decide how to deal with it. bool changingRaceLines = false; prevPoint = currentPoint; currentPoint = myRacingLine.getNextPoint(currentPoint); useMidway = true; // this.desiredSpeed += UnityEngine.Random.Range(-1f,1f); changingRaceLines = findAltRacingLine(true); if(!changingRaceLines) { // Find out whether there is a horse between us and the next point if(infront!=null) { if(this.currentPoint==infront.currentPoint) { float timeUntilTheyAtPoint = infront.timeUntilPointAtCurrentSpeed; float timeUntilWeAtPoint = this.timeUntilPointAtDesiredSpeed; if(timeUntilTheyAtPoint>timeUntilWeAtPoint) { this.findAltRacingLine(false); } } } } this.desiredSpeed = this.whichSpeedBase; if(RaceTrack.REF.iAmHost) { RaceTrack.REF.broadcastPositions(); /*(SFSObject o = this.dataPackage; TOTAL_DATA_SENT += o.ToBinary().Length; SmartfoxConnectionHandler.REF.sendRaceMessage("b",o);*/ } } else { if(infront!=null) { float dist = Vector3.Distance(infront.transform.position,this.transform.position); if(dist<MIN_FOLLOW_DISTANCE) { if(this.speed>infront.speed) { speed = infront.speed-0.1f; blocked = true; } } } } if(!blocked) { if(speed<desiredSpeed) { speed += acceleration; if(speed>desiredSpeed) { speed = desiredSpeed; } } else if(speed>desiredSpeed) { speed -= this.deceleration; if(speed<desiredSpeed) { speed = desiredSpeed; } } } float step = speed * 0.01f; Vector3 endPlace = currentPoint.transform.position; if(useMidway&&prevPoint!=null) { endPlace = (currentPoint.transform.position-prevPoint.transform.position)/2+prevPoint.transform.position; // Debug.DrawLine(endPlace,this.transform.position,Color.cyan); } //find the vector pointing from our position to the target _direction = (endPlace - transform.position).normalized; //create the rotation we need to be in to look at the target _lookRotation = Quaternion.LookRotation(_direction); Quaternion r = transform.rotation; transform.rotation = Quaternion.Slerp(r, _lookRotation, Time.deltaTime * this.rotationSpeed); Vector3 diff = transform.forward*step*4f; this.lastAppliedSpeed = diff; transform.position += diff; if(this.useMidway) { float distFromStart = Vector3.Distance(this.horseNose.transform.position,this.prevPoint.transform.position); float distFromFinish = Vector3.Distance(this.horseNose.transform.position,this.currentPoint.transform.position); if(distFromStart*1.25f>distFromFinish) { useMidway = false; } } this.animator.SetFloat("Speed",speed); }
private void initClosestPoint() { prevPoint = currentPoint; currentPoint = myRacingLine.getClosestNodeToHorse(this.transform.position); startDistanceToFinish = currentPoint.distanceToFinish; }