Converting Autowaypoint (JS) to C#

I’ve been working through the old FPS tutorial, convertine the scripts to C#. For the most part I’ve been able to fix up the errors I’ve come across without too much difficulty, however I seem to have gotten stuck on the Autowaypoint script (I’ve looked and tried using this as well with no luck: Convert unity javascript (unityscript) to C#).

Here’s the original JS:

static var waypoints = Array();
var connected = Array();
static var kLineOfSightCapsuleRadius = 0.25;

static function FindClosest (pos : Vector3) : AutoWayPoint {
	// The closer two vectors, the larger the dot product will be.
	var closest : AutoWayPoint;
	var closestDistance = 100000.0;
	for (var cur : AutoWayPoint in waypoints) {
		var distance = Vector3.Distance(cur.transform.position, pos);
		if (distance < closestDistance)
		{
			closestDistance = distance;
			closest = cur;
		}
	}

	return closest;
}

@ContextMenu ("Update Waypoints")
function UpdateWaypoints () {
	RebuildWaypointList();
}

function Awake () {
	RebuildWaypointList();
}


// Draw the waypoint pickable gizmo
function OnDrawGizmos () {
	Gizmos.DrawIcon (transform.position, "Waypoint.tif");
}

// Draw the waypoint lines only when you select one of the waypoints
function OnDrawGizmosSelected () {
	if (waypoints.length == 0)
		RebuildWaypointList();
	for (var p : AutoWayPoint in connected) {
		if (Physics.Linecast(transform.position, p.transform.position)) {
			Gizmos.color = Color.red;
			Gizmos.DrawLine (transform.position, p.transform.position);
		} else {
			Gizmos.color = Color.green;
			Gizmos.DrawLine (transform.position, p.transform.position);
		}
	}
}

function RebuildWaypointList () {
	var objects : Object[] = FindObjectsOfType(AutoWayPoint);
	waypoints = Array(objects);
	
	for (var point : AutoWayPoint in waypoints) {
		point.RecalculateConnectedWaypoints();
	}
}

function RecalculateConnectedWaypoints ()
{
	connected = Array();

	for (var other : AutoWayPoint in waypoints) {
		// Don't connect to ourselves
		if (other == this)
			continue;
		
		// Do we have a clear line of sight?
		if (!Physics.CheckCapsule(transform.position, other.transform.position, kLineOfSightCapsuleRadius)) {
			connected.Add(other);
		}
	}	
}

And here’s the C# I have:

using UnityEngine;

using System.Collections;
using System.Collections.Generic;

public class AutoWaypoint:MonoBehaviour
{
static AutoWaypoint waypoints;
public ArrayList connected;
static float kLineOfSightCapsuleRadius = .25f;

static AutoWaypoint FindClosest(Vector3 pos)
{
	//The closer two vector are, the larger our dot product shall be.
	AutoWaypoint closest = waypoints[0];
	float closestDistance = 100000.0f;
	if(waypoints.Length == 0)
	{
		return null;
	}
	
    
	foreach(AutoWaypoint cur in waypoints)
   {
	   var distance = Vector3.Distance(cur.transform.position,
			pos);
	   
		//If the distance is smaller than the closest distance, set
		//the closest distance to be equal.
		if(distance < closestDistance)
		{
		closestDistance = distance;
		closest = cur;
		}
	}

     return closest;
   
}

[ContextMenu("Update Waypoints")]

void UpdateWaypoints()
{
   RebuildWaypointList();
}

void Awake()
{
   RebuildWaypointList();
}

//Now we'll draw the waypoint pickable gizmo.
void OnDrawGizmos()
{
   Gizmos.DrawIcon(transform.position, "Waypoint.tif");
}

//We'll only draw the waypoint lines when we select one of the waypoints.
void OnDrawGizmosSelected()
{
   if(waypoints.Length == 0)
   {
     RebuildWaypointList();
   }

   foreach(AutoWaypoint p in connected)
   {
     if(Physics.Linecast(transform.position, 
          p.transform.position))
     {
      Gizmos.color = Color.red;
      Gizmos.DrawLine(transform.position, 
          p.transform.position);
     }
     else
     {
      Gizmos.color = Color.green;
      Gizmos.DrawLine(transform.position, p.transform.position);
     }
   }
}

void RebuildWaypointList()
{
    waypoints = FindObjectsOfType(typeof(AutoWaypoint)) as AutoWaypoint[];

   foreach(AutoWaypoint point in waypoints)
   {
     point.RecalculateConnectedWaypoints();
   }
}

void RecalculateConnectedWaypoints()
{
   List<AutoWaypoint> connectionList = new List<AutoWaypoint>();

   foreach(AutoWaypoint other in waypoints)
   {
	   //We don't want to connect to ourselves.
	   if(other == this)
	   {
		   continue;
	   }
	   
	   //Make sure we have a line of sight.
	   if(!Physics.CheckCapsule(transform.position, other.transform.position,
          kLineOfSightCapsuleRadius))
	   {
		   connected = connectionList.ToArray();
	   }
   }
}

}

The errors (so far):

AutoWaypoint.cs(29,32): error CS0165: Use of unassigned local variable `closest’

AutoWaypoint.cs(10,29): error CS0161: `AutoWaypoint.FindClosest(UnityEngine.Vector3)': not all code paths return a value

AutoWaypoint.cs(54,30): error CS1061: Type System.Collections.ArrayList' does not contain a definition for length’ and no extension method length' of type System.Collections.ArrayList’ could be found (are you missing a using directive or an assembly reference?)

AutoWaypoint.cs(79,29): error CS0103: The name `Array’ does not exist in the current context

AutoWaypoint.cs(89,29): error CS0103: The name `Array’ does not exist in the current context

edit: I’ve gotten the original errors taken care of, and now (I’ve got the feeling this is something rather simple I’m just not seeing as early as it is here :P) I’m getting:

AutoWaypoint.cs(109,28): error CS0029: Cannot implicitly convert type AutoWaypoint[]' to System.Collections.ArrayList’

I’ve updated the C# code above.

First off, you may want to use a simple array for the waypoints and connected values. They’re faster, and strongly typed to boot. So, at the top-

static AutoWaypoint[] waypoints;

Then, whenever you would use that variable, make sure that you call the correct functions for an inbuilt array instead of an ArrayList.

Errors-

1: In this code, the variable ‘closest’ isn’t guaranteed to be assigned to everything. It is possible, if the array of waypoints has no members, for closest to never get assigned. You should fix this by returning null if the array is length zero, and then assigning current to the first waypoint in ‘waypoints’.

if(waypoints.Length == 0)
{
    return null;
}
AutoWaypoint current = waypoints[0];
// and the rest...

2: This is as simple as a misplaced bracket. You should be putting

return closest;

right at the end of the function, not inside the foreach. Look closely, you’ll see it.

3: This applies to all the ‘length’ issues. Anywhere where it would call for ‘whatever.length’, you should replace with ‘whatever.Length’. I know, it’s weird that it’s a variable that starts with a capital, but that’s just how it is.

4: The first error complaining about the non-existant ‘Array’ class can be fixed just by simplifying those lines to

waypoints = FindObjectsOfType(typeof(AutoWaypoint)) as AutoWaypoint[];

5: The second one is a little more complex, because it requires functionality which arrays do not have. First up, add the line

using System.Collections.Generic;

at the top of the page.

Then, change that function so that instead of

connected = Array();

it uses

List<AutoWaypoint> connectionList = new List<AutoWaypoint>();

Then, when you would use ‘connections’ in that function, use ‘connectionList’ instead. Then, right at the end of the function, use

connected = connectionList.ToArray();

To convert the list back into an array that you can use elsewhere. (Make sure that you are using an inbuilt array for connected, instead of the arrayLists you are using at the moment).

I think that’s all, for now- revise your question as more things come up!