• ACM Studio Logo
  • home

    home

  • about

    about

  • blog

    blog

  • events

    events

  • Instagram
  • Facebook
  • Discord
Aubrey Clark
Byte Sized Tutorials

C# for Unity

This article was made for ACM Studio’s Workshop Series.

Programming was meant to be relatively logical. Each concept in a programming language should roughly map to a solution to a problem somebody was trying to solve. C# is no different.

This article requires basic knowledge of Unity.

Writing a Unity Component

Here’s a unity component

using UnityEngine;

public class MyComponent : MonoBehaviour {
	int health;
	
	void Start() {
		health = 100;
	}
}

Let’s go over the syntax.

A class specifies that you are creating a type of object. The : MonoBehaviour specifies that this is a subtype of Unity’s MonoBehaviour type, which is a component. Thus, this code creates a type of component. Note that this is not a specific component, since multiple components can be added across GameObjects. This is like the archetype of all components.

public means that if you write other classes, they can “see” this class. That is, if you do not write public, C# will throw an error if you try to access MyComponent from another component.

int health specifies a field (often called member variables of miscalled properties) on the class.

This is a piece of data that is stored on every instance of the class. Thus, every MyComponent I add in Unity will have a member variable called health.

C# provides a feature called namespaces that make sure two different libraries don’t have naming conflicts. For example, C# and Unity both define something with the name Debug . However, C#’s Debug is in the namespace System.Diagnostics while Unity’s is in UnityEngine, so if you need to disambiguate between them, you can write their full name: System.Diagnostics.Debug or UnityEngine.Debug.

using UnityEngine; means that everything in the namespace UnityEngine you can now use without specifying UnityEngine. before it. Right now, this is needed to simplify UnityEngine.MonoBehaviour to MonoBehaviour.

How to learn

Learning to program is easier if you’re willing to make mistakes and if you’re curious about the details of what you’re doing. Whenever you read something or have a question, try it out yourself on your machine or on an online tool like .NET Fiddle.

Learn to read the error messages you see when you mess up. If the C# creators did a good job, it should usually tell you exactly how to fix simple errors. Whenever there is an error in your code, this is what I do to fix it. But this is a learned skill!

Otherwise, learn to Google your problem well.

Data and Classes

Programming’s end goal is to manipulate data. Even for a complicated thing like a game engine, the goal is to manipulate all the objects in the game into formats that your graphics card knows how to put on the screen.

C# knows how to represent only a few types of data. It can represent an integer 0 or a decimal 0.0. It can represent a character 'c' or text (a string) "hello". You can write any of these values in C#.

You can play around with these by using some sort of “print” function (I’m sure you’ve heard of print("hello world!")). In C#, the default is System.Console.WriteLine(whatever) (though later, in Unity, you will be using UnityEngine.Debug.Log).

System.Console.WriteLine(10);
System.Console.WriteLine("Hello");

This is valid code, and writing code like this is often useful. However, it is often useful to be able to use a value more than once, or to modify it over time. Both of these can be achieved using variables (which don’t necessarily need to vary). In C#, the syntax for this is

// <type> variableName = value; (btw this is a comment, it does nothing)
int integer = 10;
double dec = 11.0;
char ch = 'a';
string text = "hi!";
int integer2; // i can't use this until i set its value
integer2 = 13; // i can use it now
var integer3 = 10; // C# will infer that var = int
// var integer2; but it cannot here, since it doesn't know its value
System.Console.WriteLine(dec);
System.Console.WriteLine(dec * 2);

You can manipulate values using basic math operations, and then you can replace the current value using the equals sign = again.

int a = 10;
int b = 40;
b = a * b / (a + b);
System.Console.WriteLine(b); // what will this be?

Objects are more complex data structures that can contain multiple pieces of data (member variables/field) alongside code (member functions). string is actually an object. It contains multiple chars and provides code that lets you find the length of the string, convert it to uppercase, and all other cool things.

You can access these member variables and functions using a period:

var text = "hello";
System.Console.WriteLine(text.Length); // what will this be?
text = text.ToUpper();
System.Console.WriteLine(text); // what will this be?

An object is a value. But for C# to know that, for example, string contains a member Length, you must declare a class.

class Player {
	public string name;
	public string noise;
}

Common Mistakes

Floats vs. Doubles

Computers allow different “precisions” of decimals (aka floating-point numbers). Most of the time, you will either use a float or a double. However, in C#, when you write 10.5, that is a double. If you try to do

float x = 1.0;

it will give you an error “Literal of type double cannot be implicitly converted to type 'float’”.

To fix this, use the float suffix f for decimals.

float x = 1.0f;

Note that this behavior is generally not the case in other languages (most languages have implicit casts), it is generally a good feature to have.

If you have a double for whatever reason and want to turn it into a float, you can use casting.

float x = (float) 1.0;