Waypoints

I have some waypoints set up on one of my tracks. Then the opponent’s code is:

var target : Transform;
function FixedUpdate () {
	if (Physics.Raycast (transform.position, Vector3.down, 1.5)) {
		rigidbody.AddForce (Vector3.up * 7);
	}
	transform.LookAt(target);
	rigidbody.AddRelativeForce(Vector3.forward * 2);
}

What I can’t figure out is how to change the target after hitting the first waypoint. Can you guys help out? Thanks! :wink:

Put a trigger collider on the waypoint, and give each waypoint code that looks something like:

//This assumes the script you posted is named "Racer.js"
var nextTarget : Transform;
function OnTriggerEnter(c:Collider) {
var racer : Racer = c.GetComponent(Racer);
if (racer  racer.target == transform  nextTarget) {
racer.target = nextTarget;
}
}

That’s one cool piece of code there. Except now when the enemy reaches a waypoint he stops there for a few seconds before moving to the next one (obviously bad behaviour for a racing game enemy).

That’s… odd. Does the waypoint’s collider stretch to cover the entire area through which a racer could pass? I forgot to mention the collider should do that.

Also, as an improvement to you chasing code: if every waypoint has a collider, you could make the computers chase after that collider.ClosestPointOnBounds. It would make your AI a tiny bit smarter (they might try to take turns on the inside, etc.)

Yeah, they cover the whole track width. Also, with the code I have, where would I put the ClosestPointOnBounds, and what exactly does it do? Thanks for all this help. :wink:

I’m not sure what could be causing that behavior - a Web player might be helpful in terms of seeing precisely what’s going on.

ClosestPointsOnBounds does exactly what its name suggests: you give it a point in space, and it returns the nearest point to that point that is along the collider’s surface.

var target : Transform; 
function FixedUpdate () { 
   if (Physics.Raycast (transform.position, Vector3.down, 1.5)) { 
      rigidbody.AddForce (Vector3.up * 7); 
   } 
if (target.collider) transform.LookAt(target.collider.ClosestPointOnBounds(transform.position)); 
   rigidbody.AddRelativeForce(Vector3.forward * 2); 
}

“InvalidCastException: Cannot cast from source type to destination type”

Hmmm…

I realize what I’d need to do to stop the problem with the AI. He has to sense if he’s close to his target, and then change before he actually hits it. I already tried with a raycast, but he just sensed if any collider was in front of him, not just the targets. Any ideas guys? Thanks!

Theres some way to selectively test for collisions using layers, apparently…Guys…?Cheers
AC

try getting the racecraft’s position in the waypoint’s local space. This means the waypoint has to be facing forward in the track.

//This assumes the script you posted is named "Racer.js"
// you have to have the object with a Racer component have a tag that is "enemy"
// turnAtMeters is how far before the waypoint you want the racer to turn

var turnAtMeters = 0.00;
var nextTarget : Transform;

var racers = new Array();
racerObjects = gameObject.FindGameObjectsWithTag("enemy");
for(racerObject in racerObjects) racers.Add(racerObject.GetComponent(Racer));

function Update()
{
	for(racer in racers)
	{
		if (racer  racer.target == transform  nextTarget)
		{
			localPos = transform.InverseTransformPoint(racer.transform.position);
			if(localPos.z < 0  localPos.z > -turnAtMeters) racer.target = nextTarget;
		}
	}
}

You can raycast to specific layers of colliders. http://unity3d.com/Documentation/ScriptReference/Physics.Raycast.html?from=LayerMask
Use the second form: bool Raycast (Vector3 origin, Vector3 direction, out RaycastHit hitInfo, float distance = Mathf.Infinity, int layerMask = kDefaultRaycastLayers)

Set all the waypoints to a specific layer. To generate the appropriate mask for the raycast, I recommend using a script like my Layers script. Create an exclusive mask with the layer your waypoints are in, and raycast for that. Let me know if you need more help with that.

There probably no need to do an expensive raycast. You can just calculate the distance yourself.

//In a script on the player
Vector3 closestPointOnTarget = target.collider.ClosestPointOnBounds(transform.position)
float distanceToTarget = (closestPointOnTarget - transform.position).magnitude;

Fixed my biggest problem by just turning him into Ice. Thanks for your complicated codes though. :stuck_out_tongue: