(Note: If you like this article you can support me by using my DigitalOcean.com referral link, and by using my referral link you are directly supporting my blogs that are hosted there. Also follow me on social media: @IMG4MR/G4MR)
Godot 3.1 was recently released and now is a good time to get more people trying it out. This version of godot makes it even easier to get up and running because it takes less work and this quick start is going to be an introductory guide on helping you do just that.
This guide expects you to understand how to install software, and a mild understanding of your editorial software/ide. For this quick start we’ll be using Jetbrains Rider, but the default preferred editor is Visual Studio Code because it’s just as easy to setup remote debugging with the mono runtime. You can use my guide here if you prefer to use Visual Studio Code. Then come back to this tutorial and we can get started.
- Godot 3.1
- MSBuild (via Visual Studio/Visual Studio Tools/Mono)
Godot 3.1 is more streamlined than before, requires less to get started. First and foremost it’s recommended that you download the latest godot stable from the website. Make sure you’re using the version listed under Mono version and install (move) it to your preferred folder location and create a shortcut of the exe if necessary. (note: the steam version does not include the mono build, I’m sure there will be a mono version released sometime in the future on steam)
(heed the note under the download buttons)
Next we need MSBuild 15 to build your projects. Godot no longer relies on a specific installation version of Mono and is currently bundled with version 5.18 on the stable branch. What this means is you can now use any version of mono on your PC for your personal projects and still be able to use godot’s editor without any conflicts. Now if you’re already using Mono locally you can use that version of mono’s MSBuild, as most versions of mono already use a custom msb 15 out of the box if I’m not mistaken. Now if you don’t have mono and have VS Build Tools installed (or Visual Studio that includes them), check and make sure your vs build tools has at least version 15 and you should be okay.
Personally I would use VS Build Tools 2017 if you go that route, as there’s reports regarding VS Build Tools 2019 not working as intended. I haven’t tested so I can’t confirm, but you can download 2017’s via Chocolatey or the official website. For Mono’s MSBuild you can download the latest mono stable and should be fine.
Setting up a New Project
Open the Godot editor and you’ll be presented with a Project Manager. Make sure you’re under the Project List tab then hit the New Project button and you should be presented with a new project window.
Before we can start you’re going to want to select the project path that your new project will go in. So next to that red x icon choose browse and find the parent directory that we’ll create the project in. Once you do that you should name your project, and I recommend using PascalCase when naming your project because your solution file and namespace will be the exact name of this field which has caused problems in the past, but it should be fine if you decide to use spaces. For this project I’m going to name it QuickStart. Hit Create folder, then press Create & Edit and now your project should be created.
You should be prompted with an empty project UI which will indicate that you’ve followed my steps precisely.
Setting Build Tools
By default godot has Visual Studios build tools set, but if we want godot to use something else such as mono’s msbuild or xbuild on mac/linux (deprecated) then we need to change it and this is how you do that.
First select Editor from the menu bar then Editor Settings and the editor’s settings should popup. Editor Settings is different from project settings, so if you’re looking for a setting you can’t find it may be in Project -> Project Settings. More on that in a future tutorial.
You will be presented a search box and a bunch of settings. Simply type “build” in the search box and you’ll instantly see the options under Mono that we need. So select “Builds” and then change the Build Tool setting to the appropriate build tools you’re using.
Create your solution file
By default every project is empty. You can create scenes without scripts, although you’ll get a error telling you this that there’s no script meta file, everything you add to a scene can be previewed before using any scripts. Now if we want to add C# scripts to our project we’ll want to create this solution file because c# is a compiled language unlike gdscript which is more of an embedded scripting language. Now if you remember the empty project image we had above, you should see a flat text button that says Build below the window’s exit button. Click this and you’ll create an empty project solution file.
Personally, my work flow is to create an empty solution then open that solution in my favorite IDE. Some people prefer to setup their scene first then right click on a node and attach a script which will allow godot to create the script for you inside their editor using blank c# templates, but there is no auto-complete or syntax highlighting which isn’t preferable to me; but everyone’s different and today for this guide we’ll be creating the scripts ourselves from scratch instead of using godot’s generated c# templates.
Opening your project in your favorite IDE
Today we will be using Jetbrains Rider to show you how to open your godot project. It’s as simple as finding and opening your project’s solution.
Find your project folder and click on your .sln file, alternatively you could open the csproj file, but rider is known for duplicating your sln file for no reason so I wouldn’t recommend it.
Once your project opens, I want you to expand all files to your project. This makes it easier to add files to your solution.
This should allow you to see every file in your project making it a nice reference for filenames and what not. Before we add a script I want to create a basic scene and setup a basic project structure.
Folder Structure & Namespaces
Now personally I’ve been writing games for godot on and off for a little over a year and my folder structure changes with every project because I can’t get a hold of something I like, mostly because right now you cannot change the project root to a sub folder for cs source files so you just make due with a sub folder which gets included with the namespace. Hopefully this changes in the future. With that said we’re going to go with the following:
- ./Objects (packed scenes)
The way namespaces work in godot is based on the project name, and all subsequent namespaces are tied to subfolders. So in our case QuickStart.Core.Scripts is tied to the scripts sub sub folder.
Alright for this guide we’re going to create a basic scene. We’re going to focus on 2D so this gives me a chance to show you how to switch to the 2D camera view. It’s pretty straight forward, but you may have missed it. So lets start by changing the current scene to the 2D view, and to do this we click on “2D” in the top center of the editor and this will switch it from a 3d camera to a 2D one.
Now on the right under the scene tab you should see godot asking you to create a Root Node. A root node is basically the parent object container which will hold your scene together. Sometimes the root node in games is called World or Base or if we’re reusing a node sometimes we’d call it a Character, Enemy or Player, but for now lets name it MainScene. Since we’re using 2D nodes for this example lets make the root scene a 2d Node, or 2D Scene as shown in the UI above. Now double click on Node2D and rename it to MainScene. Save the scene to the Scenes folder that we created from our project view as MainScene.tscn.
(Sometimes you may want a 3D scene which is a world node that contains everything in your world view. Or if you want just UI you could create a Control Node as a root node. You can learn more about nodes on the official documentation.)
You should have successfully created your first scene that currently does nothing. Now if you hit the play scene (F6) button at the top it should open an empty window that does nothing. Just getting here means you haven’t screwed up anything.
(The debugger will show an error saying ‘missing scripts metadata file’, just ignore this because we haven’t added any scripts to our project yet which is all that error is saying)
Creating our first script
For this quick start guide we’re going to create our first script manually through code. I would recommend typing out the code rather than copying so muscle memory comes into play later, but I can’t stop you if you don’t.
(As of Jetbrains Rider 2018.3, if you’ve added a folder to your project from the solution viewer it will automatically include that folder to that project. If you add a class and it doesn’t automatically give you a namespace try deleting the file then right clicking on the folder and force including it into the solution. Also make sure your Data folder is not included into your project, right click and exclude it if it is included into the project.)
Right click on the Scripts folder and add a new class and call it main scene.
You can leave off the file extension name and Rider will still understand what to do. From here you should be prompted with a class that looks something like the following:
You see how Rider automatically sets up your namespace for you? That’s the reason I like using Rider personally. From here we’re going to setup the code so later we can move the godot logo around the window using WASD keys.
In godot, you can only assign one script to one node. Which means you can setup a script for the whole scene and work from there or you can break down your scripts into smaller scripts to have specific functionality. So yes, you can use more than one script in one scene, but you cannot assign multiple scripts to the same node. This isn’t limited to c# as gdscript has the same functionality as well.
For this example we will be doing the former and attaching a script to the whole scene and accessing the child nodes within it with this script.
Scene classes MUST extend the class of the type of node you are extending. Because the godot api is so nice almost every node is a 1:1 equivalent to the class name, even in gdscript. Just for reference, all Nodes are PascalCase. For a reference of class names you can check out godotsharp.net for an api reference of the classes, but if you’re using Jetbrains Rider 2018.3 or higher you can use the assembly explorer right inside of the IDE.
For our MainScene class we’ll be using Node2D because that’s the node type that we set as the root of our scene. To do this you must include the Godot namespace and you can extend the class from the root godot namespace. Doing this will also open you up to specific godot methods such as _Ready(), _Process(), _ProcessPhysics(), and _Input(). Those 4 are the main predefined methods you’ll use in godot for all nodes.
_Ready() is similar to gdscript’s _ready method. C# doesn’t have an equivalent to gdscript’s onready keyword so instead of defining onready, we define all our variables inside this method which will be called once the script is added to the scene. You load resources in this method, think of it like an Init or Load method in other graphic engines.
_Process() runs every frame, so in our case we’ll use this method to move the godot logo around the scene. Think of this method as an Update() method in other graphic engines/frameworks. _PhysicsProcess is similar, but that’s called every physics frame. You want to use that with RigidBody‘s or KinematicBody‘s and the class methods that associate with those node types.
_Input() is a bit different, out of the box it’s used to handle all incoming input from keyboard, mice and controllers per the OS. You can read more on it here. Now handling input isn’t limited to this method, you can definitely do it inside the _Process method if you want, but you wouldn’t rely on the input event system; there’s also InputMaps which are even easier, but sometimes you may want a bit more control over your inputs for whatever reason (like the joystick) and go from there. You could possibly consider this the Events() method from other graphic engines.
Creating our MainScene script
Now lets apply the information we learned and extend the Node2D node and add a _Ready() method to our class so we can then move the godot logo around. Don’t worry we haven’t added the godot logo from the root directory to the scene yet, we will shortly. Your code should now look like this:
Before completing this section lets print a simple message to the godot output window by adding this code to the body of _Ready():
Attaching Script to Scene
Attaching a script to a scene is as simple as dragging and dropping. Although you can also right click on the root scene and attach a script or you can press the + icon and do the same thing. I’m going to show you how to do that using all 3 techniques in the gif below:
Now if you hit play scene (F6) button again and move the game window to the side, you should be able to see your output message printed to the output section at the bottom of the editor.
Lets Make The Godot Logo Move Around
If you’ve gotten this far then you’ve successfully created a new project, added & saved a scene, created a script, attached your script and got a message printed to the editor’s output section. Pat yourself on the back it only gets easier from here. In this section we’re going to add the godot logo from your project’s root folder to the current scene and use code to move it around the screen using WASD. Nothing fancy, but it’ll give you a taste until I write more tutorials.
First, lets add the logo somewhere on the screen
We’re not going to bother trying to position it through code because this is just an example, so do your best to follow this step. In the left file explorer left click the icon.png and drag it to the middle of your scene. If you don’t let go of the image you’ll notice some text popup in the top left of the scene giving you some hotkeys. By default all images dragged & dropped this way are called Sprite‘s. If you see the hotkeys on screen and hold alt when you drop it you can change the default node type before it’s added as a child to the current selected node. Keep it as a sprite for simplicity sake.
Lets rename the Sprite node to “Logo” by double clicking on the node and editing it directly inside the editor. There’s no reason for this aside from getting you prepped to use the editor as much as possible. There’s a rich feature set and more is always being added, yet the UI is simple and not overwhelming which is why I’ve stuck with godot for over a year now.
Now, lets create a class property to access our node for usage
Godot is pretty straight forward when it comes to setting up properties for accessing nodes. You create a private or public class property with the type of node you want to access then you attempt to access & assign the value for that node you want to use in the _Ready() method from the node tree, which in our case is just MainScene as the root node and Logo as a child node in our scene tree.
When we attach a script to a node and call GetNode(), which is the gdscript equivalent of $ or get_node(), the script’s node tree root is the node we attached it to. So when using get node we can directly access all its children and branches without including itself. You can also use period paths to get parent nodes if you attach a script to a child node, but want access to that nodes parent doing something like ../ParentNode, and I discourage that type of usage personally unless you are sure that node won’t ever become an instanced Scene/PackedScene where things become a little weird. More about that in a future tutorial maybe.
Lets create a class property called “_logo” and make it private and of type Sprite.
(You don’t normally create an instance of a scene script directly, so you can leave the default value off, but it doesn’t hurt if you prefer to assign an empty Sprite instance as the default value before assigning.)
Next, inside your _Ready() method lets attempt to access the node using GetNode<Sprite>(). GodotSharp has generic support on GetNode<T> which acts similar to type casting a normal GetNode call, which will throw an Exception rather than return null. If you prefer to handle null then you can use an GetNode(‘…’) as Type call and go from there. You can view the source if you want to see other generic methods. Your code should now look like this:
Now if you play the scene you shouldn’t get any errors and see the godot logo somewhat in the center of the screen (where ever you placed it).
Lets Move the Godot Logo
Now I won’t go too in depth on the code, but I’ll give you a brief explanation of what’s going on.
So now that we have access to the logo, we want to move that logo around the screen using delta time; and since we’re using a sprite, we are going to code the movement ourselves.
So first, we’ll define a default Speed field and set it to 300 in our MainScene class, you can make this field public.
Next we’re going to add a local variable called velocity inside the _Process() method, which takes a float property, and we’ll multiply the speed property with delta to get the appropriate frame velocity so we’re moving the sprite consistently in most directions per frame.
Now, we need to create another local variable called direction and assign this to a new instance of a Vector2D struct. This will help us determine which direction we’re going to be going (and easily apply this data to our logo’s position because the assignment value is an overload and understands how to add two Vector2D’s together.)
Following that we want to use godot’s built-in Input class to determine when specific buttons are being pressed so we can tell our code which direction we’re going. These static methods are called Input.IsKeyPressed which takes a int currently, but in future versions should take enum’s like they are meant to. From there we want to pass a type-casted KeyList enum of the key we’re pressing as int and do this for each direction. In godot 2d, we work in the X and Y axis, so -Y is up, +Y is down and -X is left and +X is right. Now we use that information to determine the direction we’re going.
After getting the direction, we want to add it to the existing logo’s position to move it. Your code should look something like this:
Now if you play your scene and press WASD, you will see the godot logo move around the scene.
Congratulations, you’re ready to start making games in godot!
[QuickStart Source Code]
Don’t forget to checkout the discord and join the #csharp channel for any questions you have. If you aren’t using Jetbrains Rider to view the assembly data, you can use the api reference as mentioned earlier on godotsharp.net. Lastly, feel free to check the docs on a vast amount of c# specific information that’s kind of hidden away.
(If you like this article you can support me by using my DigitalOcean.com referral link, and by using my referral link you are directly supporting my blogs that are hosted there. Also follow me on social media: @IMG4MR/G4MR)