C# Crash Course =============== Fully teaching C# or introducing a new comer to programming in general is out of the scope of this documentation, so this will page will assume you already have experience with another language and are looking for a place to quickly understand C#. C# is a very complicated language with a vast array of features and this page will only be scratching the very tip of the iceburg. So, what is C#? C# is an object orientated programming language with an event driven paradigm. It's actually fairly similar to Java in it's structure, but with C based syntax instead. If you come from a Java or C++ background then C# should be easy enough to get a grasp of. Basic Keywords -------------- .. code-block:: csharp char // character string // an array of characters byte // unsigned byte sbyte // signed byte int // signed 32-bit integer uint // unsigned 32-bit integer short // signed 16-bit integer ushort // unsigned 16-bit integer long // signed 64-bit integer ulong // unsigned 64-bit integer float // 32-bit floating point value double // 64-bit floating point value null // null reference void // used as a return type on methods that don't return anything Access Modifiers ----------------- Much like in languages similar to C#, any kind of object can have access modifiers that determine what can access what in your code. Here's a list of them: .. code-block:: csharp public // anything can access the object internal // only code inside of your library can access the object private // only the root class that defines the object can access it protected // object is private but can be accessed by children of a root class sealed // class is public but cannot be inherited static // object is always in memory and does not require an object instance to access. const // object is static but cannot be modified at runtime Class Example ------------- This example shows you a fully structured class that makes use of many C# features. I have commented everything to explain what's going on. There are also structs in C#, which you can think of as more lightweight classes. They're a lot trickier to understand then classes though, so I recommend you read Microsoft's documentation if you're interested in that. .. code-block:: csharp // double forward slash is a single line comment /* Forward slash with an asterix is a multiline comment See, even this is a comment! */ // This allows us to reference code from other namespaces (mentioned below). using System.Collections.Generic; using UnityEngine; // This is a namespace. They're not required but they let us organise our code. // You can think of namespaces like a folder hiearchy. // Not wrapping a class in a namespace puts it into the "root". // Everything can access anything in the root without a using to reference it. // By using a period we can define sub directories, so for this MyClass is in // Example -> Crash Course namespace Example.CrashCourse { public class MyClass { // an example of a static variable. This can be accessed via MyClass.CoolFeatureEnabled public static bool CoolFeatureEnabled = true; // an example of a constant. This can be accessed via MyClass.DebugMode. public const bool DebugMode = true; public MyClass() { // this is a constructor // called on new instances of the class when created // I'm including this to show you how to declare one. They're not required if (DebugMode) { Debug.Log("Hello World!"); } } public MyClass(int myNumber) { // this is a constructor with parameters // called on new instances of the class when created // I'm including this to show you how to declare one. They're not required MyNumber = myNumber; if (DebugMode) Debug.Log("Hello World!"); // we can indent code on the next line to nest it too } ~MyClass() { // this is a destructor // called when the class instance is about to be destroyed // I'm including this to show you how to declare one. They're not required if (DebugMode) Debug.Log("Goodbye World!"); // nested code can actually be on the same line too if you want tidy one liners } // an example of a public variable public int MyNumber = 2159; // an example of a private variable private bool _myBool = true; // an example of an array that holds the numbers 1 through 5 public int[] MyArray = new int[5] {1, 2, 3, 4, 5}; // an example of a new list. We can leave this empty for now. public List MyList = new List(); /* an example of a property You can think of these like a method that are specifically designed to handle controlling data in the class. This is a really basic example of how we can use one to get and set our private _myBool variable. If you get rid of the set portion, you can use this to expose _myBool as a readonly variable. */ public bool MyBool { get {return _myBool;) set {_myBool = value;} } // example of a method that doesn't return anything // let's have some fun with loops in this! public void PopulateList() { // make sure MyList isn't null and redeclare it if it is. // since we declared it above it won't be, but this is a good practice anyway if (MyList == null) MyList = new List(); // using a for loop to enumerate from 0 to 10 and add the value to the list for (int i = 0; i < 10; ++i) { MyList.add(i); } if (DebugMode) { // using a foreach loop to enumerate through each list item and log it foreach(int val in MyList) { Debug.Log(val); } // let's do it again using a while loop, but this time backwards! int index = MyList.Count - 1; while (index >= 0) { Debug.Log(MyList[index]); --index; } } } // example of a method that returns something public string GetCoolDisplayString() { // we can use ? and : to write an if statement. // when comparing booleans we can also cut == true and == false and // just implicitly infer the value return _myBool ? "Very Cool" : "Very Not Cool"; } /// /// This is a documented member. /// This works on anything but with methods we can provide documentation for each param. /// This description will show up in intelisense when highlighting this method. /// /// is a lambda expression, which allows us to define methods without a name OnObjectSpawned += (Object o) => { // do something with o here }; BallisticNG Example ^^^^^^^^^^^^^^^^^^^ Alright so we've seen how to create and subscribe to events. So, how would this apply to BallisticNG? Well, here's an example of responding to ships spawning in a BallisticNG mod. .. code-block:: csharp public class PrintShipNamesOnSpawn : ModRegister { public override void OnRegistered() { BallisticEvents.Race.OnShipSpawned += OnShipSpawned; } private void OnShipSpawned(ShipRefs ship) { Debug.Log(ship.name); } }