Hey folks. Unity newbie, trying to learn C# before I get too comfortable with JS.
I’ve got some code which moves a camera to the position of a gameobject if the player gets within a certain radius of the gameobject.
There are two scripts - CameraControllerRevCsharp.cs and NodeControllerRevCsharp.cs.
CameraControllerRevCsharp is attached to the Main Camera.
NodeControllerRevCsharp is attached to gameobjects (4 in this example) named CameraNode.
On Awake, a NodeControllerRevCsharp script takes the position and activation range from the CameraNode it’s attached to and pushes it into an array on the CameraControllerRevCsharp attached to the Main Camera.
The CameraControllerRevCsharp regularly iterates through the array containing the Camera Nodes, identifies which one is closest to the player character and moves the Main Camera to the identified node.
(There’s a delay in the code to stop the while loop from eating up the processor, but it’s currently commented out until I can get the code to compile)
That’s how it should work. BUT IT AIN’T! I’ve eliminated as many bugs as I can (learning about different C# arrays and the need to make bools explicit in functions, etc), but the durn thing just won’t compile. I have the following errors:
Assets/Scripts/CameraControllerRevCsharp.cs(53,182):
error CS0030: Cannot convert type
System.Collections.ArrayList' to
CameraControllerRevCsharp.CameraNode’Assets/Scripts/CameraControllerRevCsharp.cs(53,117):
error CS1502: The best overloaded
method match for
`UnityEngine.Vector3.Distance(UnityEngine.Vector3,
UnityEngine.Vector3)’ has some invalid
argumentsAssets/Scripts/CameraControllerRevCsharp.cs(53,117):
error CS1503: Argument#2' cannot convert
object’ expression to type
`UnityEngine.Vector3’Assets/Scripts/CameraControllerRevCsharp.cs(59,65):
error CS0246: The type or namespace
name `cameraNode’ could not be found.
Are you missing a using directive or
an assembly reference?
Code for NodeControllerRevCsharp follows, with the original Javascript (which I had working just fine) commented out at the end of each script:
================================================================================
using UnityEngine;
using System.Collections;
public class NodeControllerRevCsharp : MonoBehaviour {
public float range;
void OnDrawGizmosSelected() {
Gizmos.color = Color.red;
Gizmos.DrawWireSphere (transform.position, range);
}
void Start () {
CameraNode myNode = new CameraNode(transform.position, range);
gameObject.Find("Main Camera").GetComponent(CameraControllerRevCsharp).cameraNodes.push(myNode);
}
}
/*
//#pragma strict
var range : float;
function OnDrawGizmosSelected() {
Gizmos.color = Color.red;
Gizmos.DrawWireSphere (transform.position, range);
}
function Start () {
var myNode : CameraNode = new CameraNode(transform.position, range);
gameObject.Find(“Main Camera”).GetComponent(CameraController).cameraNodes.push(myNode);
}
*/
================================================================================
Code for CameraControllerRevCsharp follows (again, working javascript follows after c#, commented out):
================================================================================
using UnityEngine;
using System.Collections;
public class CameraControllerRevCsharp : MonoBehaviour {
//Went with ArrayList because it lets me find the .Count - NOTE THE CAPITAL 'C'!
ArrayList cameraNodes = new ArrayList();
//List<CameraNode> cameraNodes = new List<CameraNode>();
//Declare Inspector slot for controllable character
public Transform target;
//Boolean switch to turn the tracking on and off
public bool loophandle = true;
// Local access for CameraNode objects, passing range
// (set in the CameraNode script) and position
// (read from CameraNode object)
public class CameraNode{
public Vector3 position;
public float range;
//I think the 'this' keyword is being used to qualify
// members hidden by similar names, ie. the 'position'
// variable in THIS scope
public CameraNode(Vector3 position, float range){
this.position = position;
this.range = range;
}
}
// Have switched to the convention of putting curly braces at the end of
// lines so I'm not tempted to check braces by their indentation
void Start () {
// This is declaring the Transform variable 'target' again?
// Finds the transform of the GameObject named 'Player' -
// potentially something for a public var?
Transform target = GameObject.Find("Player").transform;
// While the public boolean variable 'loophandle' is set to true...
while (loophandle){
// Made this '> 0' as c# seems to freakout if you offhandedly use any variable as a boolean
// ALSO: ArrayList wants you to use 'Count' instead of 'Length'. Note the capital 'C'!
if(cameraNodes.Count > 0){
int node = 0;
for (int i = 0; i < cameraNodes.Count; i++){
//Get the range from the CameraNode object (set in the inspector), see if it's greater
//than the distance between the character controller and the CameraNode
if( ((CameraControllerRevCsharp.CameraNode)cameraNodes_).range >= Vector3.Distance(target.position, ((CameraControllerRevCsharp.CameraNode)cameraNodes)*.position)){*_
* // Assign the index number - which corresponds to the camera number - to node.*
* node = i;*
* }*
* }*
* // Move the camera to the position of the CameraNode which is indicated by node/i*
* transform.position = ( (cameraNode)cameraNodes[node]).position;*
* }*
* // ‘WaitASecond’ - This makes the code wait a set time before executing again*
* // - which saves unity from crashing Would something connected to*
* // time.Deltatime make more sense? So it only executes once perframe? (see the*
* // IEnumerator function ‘WaitASec’ below)*
* // COMMENTING OUT LINE BELOW BECAUSE I HAVE ENOUGH PROBLEMS TO WORRY ABOUT RIGHT NOW*
* // StartCoroutine(WaitASec(1.0));*
* }*
* }*
* // Update is called once per frame*
* void Update () {*
* // Makes the camera turn to face the object set up in the target variable.*
* transform.LookAt(target); *
* }*
* //IEnumerator WaitASec(float waitTime){*
* // yield return new WaitForSeconds(waitTime);*
* // Debug.Log (“Waited a sec”);*
* //}*
}
// ORIGINAL JAVASCRIPT
//#pragma strict
/*
var cameraNodes : Array = new Array();
var target : Transform;
var loopHandle : boolean = true;
class CameraNode {
* var position : Vector3;*
* var range : float;*
* function CameraNode (position : Vector3, range : float)*
* {*
* this.position = position;*
* this.range = range;*
* }*
}
function Start () {
* target = gameObject.Find(“Player”).transform;*
* while(loopHandle)*
* {*
* if(cameraNodes.length)*
* {*
* var node : int;*
* for(var i = 0; i < cameraNodes.length; i++)*
* {*
if(cameraNodes_.range >= Vector3.Distance(target.position, cameraNodes*.position))
{
node = i;
}
}*_
* transform.position = cameraNodes[node].position;*
* }*
* yield WaitForSeconds(1.0);*
* }*
}
function Update ()
{
* transform.LookAt(target);*
}
*/
================================================================================
Really having a tough time with this script. As mentioned, I had this working in Javascript and it’s driving me crazy that I can’t get it to work in C#. If anybody can provide a solution & explanation (GRR C# ARRAYS NNNNNNGH) I’d very much appreciate it. I’ve read this page - Unity Coding: Arrays, Hashtables and Dictionaries explained | robotduck - many times, but I’m still unsure whether I chose the right array for this issue. I’m determined to learn C#, but arrays are a major speedbump.
Thanks for taking the time to look at the script!