Calculate Position

Well, the guys on IRC already told me how but I think I need a slightly more in-depth explanation. I need to find a way to calculate what position (or standing in the race) the main character is in. I already have a series of waypoints, 3 computers plus 1 human, and a GUIText that tells the position (or it will). If you guys could give me any pointers I’d appriciate it. Thanks!

-Moldorma

The way I did this:

  1. Give each waypoint a “progress” variable for how far that waypoint is in the race: 0.3, 0.6, 1.0, something like that.
  2. Calculate the distance between the vehicle, and the waypoint before and after it. use those distances to calculate how far it is between the two on a scale of 0 to 1.
    If d1 is the distance to the previous waypoint, and d2 to the next, the formula for finding this value is (d1 / (d1+d2))
  3. Use Mathf.Lerp(w1.progress, w2.progress, x), where w1 is the previous waypoint (progress is the “progress” variable from its progress script, as you set in #1), w2 is the next waypoint, and x is the value you got from #2.
    That will be the progress in the overall race.

From there it’s just a matter of comparing your total race progress with the other 3 cars.

Waypoints.js

var nextTarget : Transform;
var thisTarget : Transform;
var progress : float;
function OnTriggerEnter(c:Collider) {
	var player : PlayerControl = c.GetComponent(PlayerControl);
	if (player  player.target == transform  nextTarget) {
		player.target = nextTarget;
		player.last = thisTarget;
	}
	var racer : EnemyControl = c.GetComponent(EnemyControl);
	if (racer  racer.target == transform  nextTarget) {
		racer.target = nextTarget;
		racer.accel = Random.Range (2, 5);
	}
}

Alright, that’s my waypoint code. I have step 1 done (var progress : float, up top).

And this:

PlayerControl.js

static var checks = 0;
var brakes = false;
var target : Transform;
var last : Transform;

function Awake () {
	LapCounter.laps = 1;
}
function FixedUpdate () {
	if (Physics.Raycast (transform.position, Vector3.down, 1.5)) {
		rigidbody.AddForce (Vector3.up * 7);
	}
	if (brakes == true) {
		if (Input.GetAxis ("Brake")) {
			rigidbody.drag = 1;
		} else {
			rigidbody.drag = 0;
		}
	}
	var accel = Input.GetAxis ("Vertical") * 3;
	rigidbody.AddRelativeForce (0, 0, accel);
	var h = Input.GetAxis ("Horizontal");
	transform.Rotate (0, h, 0);
}

is my player’s code. Now, step two confused me. How should I calculate this distance, and where should I put the (d1/(d1+d2). Thanks for your help!

I assume that, at a given time, the racer is between the objects represented by thisTarget and nextTarget.

(I would recommend a single uniform script on each racer, both player and enemy, that keeps track of this, instead of EnemyControl and PlayerControl, like WaypointTracker. EnemyControl and PlayerControl can just reference this script’s nextTarget instead of having their own variables. It will simplify your code.)

var d1 = Vector3.Distance(transform.position, thisTarget.position);
var d2 = Vector3.Distance(transform.position, nextTarget.position);

var lerpVal = (d1/(d1+d2));

progress = Mathf.Lerp(prevWaypoint.GetComponent(Waypoint).progress, prevWaypoint.GetComponent(Waypoint).progress, lerpVal);

I sooo wish I could make sense of that…
One day…

Bring on the unity magazine (and book and dvd series)
AC

Thanks for getting me this far StarManta. Now I’m stuck one more time. I’m putting the code on the actual 3d-text that will display the position. I have variables referencing transforms for all the crafts, and then I have it getComponent of each of their scripts, like: “Green.GetComponent(EnemyControl).percent;” like you have in the other script you gave me, but it errors me up saying that it can’t find variable “percent”. What ezzactly am I doing wrong. Whole Script Follows:

var Player : Transform;
var Red : Transform;
var Green : Transform;
var Yellow : Transform;

function Update () {
	var blueper = Player.GetComponent(PlayerControl).percent;
	var redper = Red.GetComponent(EnemyControl).percent;
	var greenper = Green.GetComponent(EnemyControl).percent;
	var yelloper = Yellow.GetComponent(EnemyControl).percent;
	if (blueper > redper  greenper  yelloper){
		print("hi");
	}else{
		print("oh");
	}
}

And that leads me to my second problem. :stuck_out_tongue: How would I compare the percentages of the four? Is there a thing that does, like, “if (blueper isBiggest){” and “isSecondLargest”? Or will I have to give many-a variable for

if (blueper > greenper&redper&yelloper) {

? Thanks for helping me get this. :wink:

Does your EnemyControl script have a public variable called percent like

var percent = 2.0;

For sorting, you might be able to use an arraylist. Perhaps some of the .Net people can help you with that. It looks cumbersome in .Net since you can’t just tell the Sort method which method on its contained classes to sort on. You would probably have to create a little class to keep your percent values in, one instance for each value. Perhaps another of the .Net classes might work. You would probably hvae to implement an IComparable, whatever that is.

Another thing you might be able to do is instead of dragging your waypoints to the variables in the inspector, in your Start() function Find all your waypoints (by Tag or Type). Then iterate through them each time you need to do the comparison. If you are just checking for the blueper to be greater than each, then something like

var blueIsTheGreatest = true;
for (var go : GameObject in yourArrayListOfWayPoints)
{
  if (bluePer < go.GetComponent(EnemyControl).percent)
  {
    blueIsTheGreatest = false;
    break;
   }
}
if (blueIsTheGreatest) {
  Debug.Log ("Blue is the Greatests!!!");
} else {
  Debug.Log("Blue is not the greatest");
}

I would move the comparison to its own method for future flexibility and to allow for easy addition of other comparisons. I believe the ICompare will do this for you, you just would need an ICompare for each type of comparison.

in the scripts, var percent looks something like:

var percent = Mathf.Lerp (last.GetComponent(Waypoints).progress, next.GetComponent(Waypoints).progress, LerpVal)

Or something like that. I’m at school now, so I’m working off of memory. :wink:

And it isn’t that I just need to see if blue is higher than the others. I need to calulate how high blue is compared to the others. Thanks!

Hey guys. I was visiting with my dad this weekend, so I didn’t get around to much RC. Anyways, percent in PlayerControl is acting oddly… If I have it in this format in FixedUpdate:

var percent = something;

it works fine. If I do this outside of a function:

var percent = 0;

and then in fixed update:

percent = whatever;

it just returns as 0. And if I put var meep = 0; outside the function and then var percent = whatevs; and meep = percent; inside a fixedupdate, meep returns as 0. What is going on here? (Sorry if that explanation was a little wacky, :P).

It’s much easier to diagnose the problem if you post a simple example code that contains the problem you are experiencing.

My guess is that you either have something like this

var percent=0;

function FixedUpdate() {
   var percent = 1;
}

or this:

var percent=0;

function FixedUpdate() {
   percent = 0.1; // or other small number
}

In the first example, the percent variable inside FixedUpdate and the one outside it are two different variables. The fix is to remove the “var” in front of the variable name inside FixedUpdate.

In the second example, you are assigning a floating point value to an integer variable. The fractions will be rounded off before assignment, causing 0.1 to be stored as 0. The fix in this case is to replace the declaration “var percent=0;” with “var percent=0.0;”

Again… finding out what’s wrong would be much easier if I had the actual code that was causing the problem, so I might be wrong about the two guesses above.

I didn’t even think of that! I (coming from Flash-world) am new to there being a difference between Ints and Floats. And the variable is at all times below 1. Thanks for the tip, I’ll plug it in when I get home and see if it works. Wow, just… wow. :stuck_out_tongue:

EDIT: Sure enough! Thanks a lot freyr. Its good to know stuff like this. :wink: