- Home /
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: http://www.m2h.nl/files/js_to_c.php).
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.
See that last bit? You're doing it wrong.
The line
connected = connectionList.ToArray();
needs to go at the end of the function- not in the bit where the 'Add' function went! That line should have been
connectionList.Add(other);
Then at the end (right before the closing bracket) turn the list back into an array with the aforementioned function.
Answer by syclamoth · Dec 21, 2011 at 10:40 AM
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!
Thanks a lot. The fixes you mentioned took care of the original errors. I think I may be misunderstanding the last part of the answer though or I'm just missing something else (see edit in question).
Yes, it's because (as I said), connected should be an array of AutoWaypoints, not an ArrayList.
public AutoWaypoint[] connected;
Remember when I said you should get rid of all that ArrayList nonsense? That's still true.
Can't believe I missed that one in the code... I probably shouldn't be trying to program at 4-6A$$anonymous$$ :P
Thanks again for all the help.
there're still existing erroes Assets/Scripts/AutoWayPoint.cs(29,24): error CS0165: Use of unassigned local variable closest' Assets/Scripts/AutoWayPoint.cs(53,17): error CS0127:
AutoWayPoint.OnDrawGizmosSelected()': A return keyword must not be followed by any expression when method returns void Assets/Scripts/AutoWayPoint.cs(53,17): error CS0037: Cannot convert null to `void' because it is a value type
The lastones are from return null;