Unity3D: JavaScript vs. C# – Part 5
Posted by Dimitri | Dec 23rd, 2010 | Filed under Featured, Programming
As the end of the year draws close, so is this post series. Here, the differences between JavaScript and C# when casting a ray in Unity3D will be pointed out. Don’t forget to read the first, second, third and forth parts of the series for a better general understanding of what is being discussed here.
Let’s start from the basics: What is ray casting? As the name describes, it is basically a program that simulates a ray being cast, much like a laser pointer in real life. It is very useful for game programming, as Raycast classes are programmed to return the distance a ray collided with something (and sometimes, even the name of the object). Unity3D doesn’t have one single Raycast class, instead its functionality is scattered across the Physics, RaycastHit and Ray classes.
I will explain how to cast a ray in Unity3D with a JavaScript example:
//Creates a ray object private var ray : Ray; //creates a RaycastHit, to query informarion about the objects that are colliding with the ray private var hit : RaycastHit = new RaycastHit(); //Get this GameObject's transform private var capsTrans:Transform; function Awake() { //get this Transform capsTrans = this.GetComponent(Transform); } // Update is called once per frame function Update () { //recreate the ray every frame ray = new Ray(capsTrans.position, Vector3.left); //Casts a ray to see if something have hit it if(Physics.Raycast(ray.origin,ray.direction, hit, 10))//cast the ray 10 units in distance { //Collision has happened, print the distance and name of the object into the console Debug.Log(hit.collider.name); Debug.Log(hit.distance); } else { //the ray isn't colliding with anything Debug.Log("none") } }
This is how it works: first, we need to create a Ray object and recreate it every frame (lines 02 and 20). The Ray class stores the ray properties, such as direction the ray is being cast and origin. Then, to obtain information about ray’s collision with other GameObjects, we need a RaycastHit class object, which will return the Collider and Transform from the GameObject that collided with the ray, distance which the collision occurred and some other details.
Last but not least, we need to call the Raycast() static method from the Physics class (line 23). This is the method that will actually cast the ray. Note that it takes the origin of the ray, a direction to cast the ray, a RaycastHit object and distance as parameters. What this method does is cast the ray to the given distance and store the collision results passed inside the RaycastHit object.
In the beginning, it may sound a little bit confusing, but after programming it for the first time it will make more sense (additional information here). In C#, the same above example is the following code:
using UnityEngine; using System.Collections; public class Raycast : MonoBehaviour { //Creates a ray object private Ray ray; //creates a RaycastHit, to query informarion about the objects that are colliding with the ray private RaycastHit hit = new RaycastHit(); //Get this GameObject's transform private Transform capsTrans; void Awake() { //get this Transform capsTrans = this.GetComponent<Transform>(); } // Update is called once per frame void Update () { //recreate the ray every frame ray = new Ray(capsTrans.position, Vector3.left); //Casts a ray to see if something have hit it if(Physics.Raycast(ray.origin, ray.direction, out hit, 10))//cast the ray 10 units in distance { //Collision has happened, print the distance and name of the object into the console Debug.Log(hit.collider.name); Debug.Log(hit.distance); } else { //the ray isn't colliding with anything Debug.Log("none") } } }
When casting rays, the only difference between these two programming languages is at line 28 in the above code. See how we had to pass the hit object with the out keyword? That happens because, in C#, the Raycast() method says it needs the RaycastHit parameter passed as reference and that’s exactly what the out keyword does. So instead of passing the object (as we done in JavaScript), we are passing a reference to it, the place where it is so the Raycast() method can find it (more information here).
It may not look like much, however one can spend some time trying to figure that out, specially when migrating from JavaScript to C#. And that’s basically it! These are the main differences between those two programming languages. There must be a lot more out there!
Final Thoughts
JavaScript or C# ? Which one to choose? It depends heavily on a lot of factors, such as previous programming skills, previous game programming experiences, affinity with certain programming languages, just to name of few.
Nevertheless, people that are beginning to grasp the basic concepts of programming, or just started programming games recently or are new to Unity3D, should stick with JavaScript, because they will have less to worry about. These people will eventually migrate to C#, due to it’s internal classes and structures which can really help to solve complex programming problems.
For the folks who have some programming baggage with C#, C++ or Java and some experience with game programming in these languages: go directly to C#.
In the end, this won’t matter after all. Eventually, you will end up learning both programming languages when writing code for Unity3D, meaning that this won’t be an issue. Naturally, you will end up creating scripts in these two languages, and then converting the code to the one the rest of your project is using. One thing is for certain: try not to mix use these two programming languages at the same time. Doing everything with one scripting language will avoid a lot of headaches.
One last thing: I haven’t forgotten the project with the examples as promised in the first post of the series. Grab it here:
- JSvsCSharp.zip Read instructions at the README.txt file.
Thanks for your post, it’s very halpfull. I’m a newbie in Unity3d but not in C#.
Note for C# listing: when you call a method with OUT parameter, you should not create the object for that parameter, it is created by calling method.
Check this out.