Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon
9. October 2015

 

In this part of the SFML we will look at creating our first basic SFML application.  At the heart of every SFML application is the RenderWindow which provides both a way to draw things on screen and receive input events from the user.

 

As always, there is an HD video of this tutorial here.

 

At the heart of every non-trivial game is the game loop.  In some game engines it’s hidden away from you inside the engine, but it is always there somewhere.  In SFML it is your responsibility to implement, which is what we will do today.  A game loop is a pretty simple concept… it’s a loop that runs over and over until your game is completed.  Each pass through the loop the screen is cleared and new graphics are drawn (this is referred to as a frame, so when you hear Frames Per Second, this is what is being referred to).  There are several other tasks a game is responsible for handling… input and physics to name just two.

 

Let’s start off with a very simple application:

#include "SFML/Graphics.hpp"

int main(int argc, char ** argv) {
  sf::RenderWindow renderWindow(sf::VideoMode(640, 480), "SFML Demo");

  while (true) {
    renderWindow.clear();
    renderWindow.display();
  }

}

This represents about the simplest meaningful SFML application you can create.  We create a new RenderWindow, passing in both its dimensions and title.  Then we simply loop forever and each pass through the loop we clear the window then draw it again with a call to display().

 

When you run this code you will get a black 640x480 window on screen, however if you attempt to move or close this window you will quickly notice something is wrong.  It doesn’t respond to any of your actions.  In fact, if you lose focus (click on a different window) you can’t even get it to focus again!  This is because we aren’t responding to any events.  Let’s switch things up a bit so that are window is a tad more responsive.  Instead of simply looping forever, we will create a slightly more intelligent game loop.

  sf::Event event;
  while(renderWindow.isOpen()){
    // Check for all the events that occured since the last frame.
    while (renderWindow.pollEvent(event)){
      //Handle events here
      if (event.type == sf::Event::EventType::Closed)
        renderWindow.close();
    }
  
    renderWindow.clear();
    renderWindow.display();
  }

Now your window properly responds to events, it can be moved around and most importantly, it can be closed.  Let’s take a quick look at what we’ve done here.

 

First off, instead of looping forever, we instead loop until our RenderWindow is closed.  Next inside this loop we’ve implemented another while loop that calls pollEvent.  pollEvent checks for all of the events that occurred since the last time pollEvent was called.  It is called inside a while loop because it is possible that multiple events occurred since the last pass through the outer loop.  pollEvent() will return false when no more events exist.  Events exist for things such as mouse and keyboard actions or the window being resized.  In this particular case we are checking to see if the EventType is Closed, which means a close request has occured.  In the event that one does we call renderWindow.close() which will result in the next check of isOpen() to return false, thus ending our game.

 

We will cover events in more detail later, but for an idea of what EventTypes exist, click here.  There are two very important things to realize in this game loop.  Notice that the sf::Event is declared outside of the loop?  This code is going to be called ALOT.  Never put variable allocations, even stack based ones like this, inside a high frequency loop if it can be helped.  Second, notice how the clear() and display() calls are outside of the inner pollEvent() loop?  This is also important, as otherwise your screen with only update when an event occurs!

 

There is one final important concept to cover before we move on to the next tutorial… time.  It is quite common for a game engine to provide the elapsed time since the last frame.  This value is very useful to your entire game as we will see shortly.  In SFML however you are rolling your own game loop, so you are also rolling your own time tracking system.  Don’t worry though, the process is extremely simple.  That’s see one final complete sample that also keeps track of the elapsed time per frame.

#include "SFML/Graphics.hpp"
#include <iostream>

int main(int argc, char ** argv) {
  sf::RenderWindow renderWindow(sf::VideoMode(640, 480), "SFML Demo");

  sf::Event event;

  // A Clock starts counting as soon as it's created
  sf::Clock clock;
  
  while(renderWindow.isOpen()){
    // Check for all the events that occured since the last frame.
    while (renderWindow.pollEvent(event)){
      //Handle events here
      if (event.type == sf::Event::EventType::Closed)
        renderWindow.close();
    }
  
    // A microsecond is 1/1,000,000th of a second, 1000 microseconds == 1 millisecond
    std::cout << "Elapsed time since previous frame(microseconds): " << clock.getElapsedTime().asMicroseconds() << std::endl;
    // Start the countdown over.  Think of laps on a stop watch.
    clock.restart();


    renderWindow.clear();
    renderWindow.display();
  }

}

You will notice the addition of an sf::Clock to our game.  The Clock provides the most accurate time that the underlying OS is capable of giving (different timers have different resolutions, and this timer needs to be very precise!).  As soon as it is declared, it starts counting.  Think of sf::Clock like a stopwatch that starts automatically.  Each “lap” you can read the elapsed time using getElapsedTime() and you can start a new lap by calling restart().   In this example we get the elapsed time in microseconds.  There are 1000 microseconds in a millisecond, and 1000 milliseconds in a second, so a microsecond is one millionth of a second.  Like I said, we need precision!

 

So that is the process of creating a very simple SFML application, clearing and displaying the window, tracking how much time elapsed and handling events.  In the next tutorial we will look at events a bit closer and see how best to handle keyboard input.

 

The Video

 

Programming , , ,

7. October 2015

 

This text tutorial is a companion to this video tutorial showing how to create and configure a new SFML project using Visual C++ 2013.  If you are running Visual Studio 2015 instead, the process should be virtually 100% identical, although you will have to download a different set of files.

 

First you need to download a version of SFML.  Head on over to the SFML download page and select the newest SFML version, as of writing 2.3.2:

image 

 

Now you need to figure out which version to download.  This mostly comes down to identifying what C++ compiler you are using as well as the “bit-ness” you want to target.  Keep in mind, even though you OS is 64bit, it is likely that you want to use the 32bit version.  This is especially true if your game is meant to run on Windows XP.  A 32bit binary can run on a 64bit OS, but not the opposite.  Additionally, for a 2D game, 64bit doesn’t really get you all that much in return.  In the end though, it doesn’t really matter which one you choose, just be aware of the results.

image

 

Now that we have SFML downloaded, extract the resulting zip file somewhere.

 

Now load up Visual Studio and create a new C++ project of type Win32 Console Application:

image

Name it and locate it however you want then click ok.

 

A new window will pop up, click next, then on the next screen, I used the following settings:

image

Click Finish.

 

We now have a project, let’s add a bit of code to it.   In solution explorer, right click your the Source Files folder in your project and choose Add->New Item..

image

 

Now choose C++ file and name it Main.cpp.

image

 

Click Add and your file is created.

 

Now enter the following code:

#include "SFML/Graphics.hpp"


int main(int argc, char** argv)
{
  sf::RenderWindow renderWindow(sf::VideoMode(640, 480), "Hello SFML");
  while (true){
    renderWindow.clear();
    renderWindow.display();
  }
}

 

You will notice lots of errors in Visual Studio, like so:

image

Don’t worry, we will fix these in a second.

 

Copying files from SFML

Open up the archive you downloaded earlier from sfml.  The contents should look something like this:

image

Copy the folders include and lib to your project directory, which should now look something like this:

image

 

Leave the SFML folder open, we will need it again in a second.

 

Configuring Visual Studio

 

Now that we have the libraries and header files copied into our project, we need to tell Visual Studio about them.  Right click your project and select Properties:

image

 

In the resulting dialog, select C++ on the left, then Additional Include Directories:

image

 

Enter the following value (for more detailed explanations, watch the video, it goes more into the why of things):

image

Make sure to hit enter and it goes bold so you know your setting was saved.

 

Now we need to configure the linker.  On the left hand side select Linker instead of C++ then Additional Library Directories:

image

 

Now enter the following:

image

 

Next we need to add our lib files.  Under linker, select Input, then locate Additional Dependencies on the right.

image

 

Assuming you are using all of the components of SFML and linking to DLLs ( see video for more options ), click in the white area and select edit and add the following (order is important!):

image

 

Your project should now be configured.  Hit CTRL+SHIFT+B to build it.  Don’t run it yet, it wont work without the DLLs, but we need to build it once to have the proper folders made.  Assuming your build went without errors, you should now have a Debug folder inside your project directory, like so:

image

 

Now, remember the SFML zip file I told you to keep open?  Switch back to it and select the contents of the bin folder:

image

And paste them into your Debug directory.  This folder actually contains both debug and release dlls, and you only need the debug for now, but disk space is cheap, no? :)  We will cover building for release at a later date and I will go into the difference in more details then.

 

Now your “game” should be ready to run, hit F5:

image

 

Congratulations, you just completed your first successful SFML project.  Now let’s head over to the next tutorial and make it actually do something!

 

The Video

 

Programming , ,

5. October 2015

 

Welcome to the next section in the ongoing Closer Look at series, a series of guides aimed at helping you decide which game engine is right for you.  Each closer look at entry is a cross between a review and a getting started tutorial that should give you a good idea if a game engine is a good fit for you.  Today we areCloserLook going to be looking at the Wave Engine.  The Wave Engine started life in 2011 and is a C# based 2D/3D engine that runs on Mac, Linux and Windows and is capable of targeting all of those plus iOS, Android and Windows Mobile, although a Xamarin license may be required for some mobile targets.  There is no cost to develop using the current version of Wave Engine, however you are required to show a splash screen on application start.

 

As always there is an HD video version of this guide available here.

 

Meet Wave Engine

 

With the release of version 2, Wave Engine now includes a level editing tool to help you quickly compose scenes.  Judging by the number of “Wave Engine vs Unity” or “Wave Engine vs Unreal Engine” searches on Google, this was a heavily requested feature.  Do be aware though that the editor is quite young, and it certainly shows sometimes.

 

As mentioned earlier, Wave Engine is C# based game engine and games can be written entirely in Visual Studio or MonoDevelop/Xamarin Sutdio if you prefer.  The editor however can make like a great deal easier and integration between your code and the editor is well done and makes heavy use of reflection.  This makes your requirement to a editing support to your own classes extremely easy as we will see shortly.

 

As is quickly becoming the norm, Wave Engine is built around a entity/component model.  Your scene is a series of entities, and those entities are in turn composed of components, behaviours and drawables (renderers).  These can be composed using either the editor or entirely in code.  Let’s take a look at the editor.

 

Wave Visual Editor

 

image

 

Let’s take a quick tour around the editor.

 

Asset Management

image

This is where the various assets ( textures, models, materials, scenes ) that make up your game are managed.  You can often, but not always, create an instance of an asset by dragging it on to the viewport.  Options here are fairly simple, mostly limited to renaming and deleting assets.  A bit of a warning, I ran into some issues when deleting assets, especially when I deleted an asset then added a new version with the same name.  Hopefully these behaviours will be ironed out in time.  Not that a scene, which is where you assemble your various assets for display in the game, is in fact an asset itself.

 

Depending on the type of asset, double clicking it will either invoke a built in tool, such as the material editor or 3D model viewer, or invoke the native application if no behaviour is defined.

 

Console

image

This is where your various levels of debug information are displayed.  You can filter between errors, warnings, informational and debug logs and of course you can clear it all out.

 

Scene Graph

image

 

The Entity hierarchy is the scene graph of your game scene.  Each scene has it’s own hierarchy.  All the assets in the hierarchy are entities which in turn are holders for various components.  Entities can be parented to other entities and will inherit their transforms.  There are several kinds of entities that can be created, depending on if you are in 2D or 3D mode.  To create an entity simply click the + icon.

The 3D entities:

image

 

The 2D Entities:

image

 

You can effectively built any of the pre-existing entity types by using an empty entity and adding all of the same components and behaviors.  Speaking of which, with an entity selected you can then access the Entity details, where you configure components and add more.  Here for example is the 3D camera’s details:

image

 

New components or behaviours can be added using the + icon.  For visible objects such as models or sprites, a Drawable component also needs to be added.  Here for example is the process of adding a film grain to our camera:

image

 

Select Components, then FilmGrainLens, then OK:

image

 

You should now be able to configure the amount of film grain in the Entity Details panel:

image

 

Viewport

image

 

This is the area where you place entities within your scene.  It is also the aspect of Wave Engine editor that by far needs the most work.  When an object is selected ( using the Entity Hierarchy, direct selection rarely works ) a widget appears for translation, scaling or rotation depending on the settings in the toolbar at the top.  In the top right corner is a widget enabling you to switch between the different camera views.  If your camera is selected you can see the camera’s viewing frustum as well as a preview of what the camera sees, like the image shown above.  You can zoom using the scroll wheel, pan with middle mouse button and rotate the view using the right mouse button.  There does not appear to be an orbit ability, which is frustrating.

 

The major current flaws are the selection mechanics ( left click works sometimes ), manipulators dont work if you click on the arrow portion, there is only one view at a time and selecting and position a camera is a rage inspiring prospect.  The single viewport with poor viewport controls makes positioning entities far more frustrating than it should be.  In fact, I tend to position entities using direct numeric entry because the viewport is so frustrating to use.  Hopefully these areas are improved soon, as all are fairly easy things to fix.

 

Toolbar

A fair bit of functionality is packed into the toolbar, as shown below:

image

 

Tools and Editors

 

As mentioned earlier, there are a few tools built directly in to Wave Editor.  Some of these are invoked by selected an asset in the asset viewer.  Others are invoked when creating new assets in the Assets menu:

 

image

 

Model Viewer

image

 

Material Editor

image

 

SpriteSheet Tool

image

Create Font

image

 

Coding in Wave Engine

 

So we’ve looked at the editor in some depth, now let’s take a look at the coding experience.  As the editor is actually a fairly recent addition, Wave Engine can obviously has pretty solid code support.  Let’s take a look at the process of creating a camera and adding film grain to it like we did earlier in the editor.  The results of the Editor are two fold, a series of file formats that the engine can understand and a CSharp project that you can edit.  You can load the solution from the File menu:

image

 

Your project should look like this:

image

 

The first project is the bootstrap for your game, it’s the second project where your code goes.

Game.cs

#region Using Statements
using System;
using WaveEngine.Common;
using WaveEngine.Common.Graphics;
using WaveEngine.Framework;
using WaveEngine.Framework.Services;
#endregion

namespace ProgrammaticCamera
{
    public class Game : WaveEngine.Framework.Game
    {
        public override void Initialize(IApplication application)
        {
            base.Initialize(application);

      ScreenContext screenContext = new ScreenContext(new MyScene()); 
      WaveServices.ScreenContextManager.To(screenContext);
        }
    }
}

 

MyScene.cs

#region Using Statements
using System;
using WaveEngine.Common;
using WaveEngine.Common.Graphics;
using WaveEngine.Common.Math;
using WaveEngine.Components.Cameras;
using WaveEngine.Components.Graphics2D;
using WaveEngine.Components.Graphics3D;
using WaveEngine.Framework;
using WaveEngine.Framework.Graphics;
using WaveEngine.Framework.Resources;
using WaveEngine.Framework.Services;
#endregion

namespace ProgrammaticCamera
{
    public class MyScene : Scene
    {
        protected override void CreateScene()
        {
            this.Load(WaveContent.Scenes.MyScene);           
        }
    }
}

 

WaveContent.cs

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.42000
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

// File generated on 2015-10-04 12:43:05 PM
namespace ProgrammaticCamera
{
    using System;
    
    
    public sealed class WaveContent
    {
        
        public sealed class Scenes
        {
            
            /// <summary> Path to Content/Scenes/MyScene.wscene </summary>
            public const string MyScene = "Content/Scenes/MyScene.wscene";
        }
    }
}

 

Game.cs creates your scene, MyScene.cs is your scene and WaveContent.cs is a system generated file for mapping resources in the editor into code friendly variables.  MyScene.cs is where your logic will go.  Let’s do a simple example that creates a red spinning cube entirely procedurally.

 

#region Using Statements
using System;
using WaveEngine.Common;
using WaveEngine.Common.Graphics;
using WaveEngine.Common.Math;
using WaveEngine.Components.Cameras;
using WaveEngine.Components.Graphics2D;
using WaveEngine.Components.Graphics3D;
using WaveEngine.Framework;
using WaveEngine.Framework.Graphics;
using WaveEngine.Framework.Resources;
using WaveEngine.Framework.Services;
using WaveEngine.ImageEffects;
using WaveEngine.Materials;
#endregion

namespace ProgrammaticCamera
{
    public class MyScene : Scene
    {
        protected override void CreateScene()
        {
            this.Load(WaveContent.Scenes.MyScene);  
         
            //Create a new red material
            WaveEngine.Materials.StandardMaterial material = new 
                                                             StandardMaterial(
                                                             Color.Red,
                                                             DefaultLayers.
                                                             Opaque);

            //Create our new entity with the name "cube"
            Entity entity = new Entity("cube");

            // AddComponent is chainable.  Add a Transform3D for position, 
            ModelRenderer so it renders
            // and a MaterialMap containing our material
            entity.AddComponent(Model.CreateCube())
                .AddComponent(new Transform3D())
                .AddComponent(new ModelRenderer())
                .AddComponent(new MaterialsMap(material));

            // Accessing components is easy.  Let's position at 0,0,0, even 
            though this is actually the default
            entity.FindComponent<Transform3D>().Position = new Vector3(0f, 0f, 
                                              0f);

            // We can also add behaviors to our entity.  Let's make it spin
            entity.AddComponent(new Spinner());

            // You can also get components by type, the true/false is wether the 
            type needs to be an exact match
            var spinner = (Spinner)entity.FindComponent(typeof(Spinner), true);
            // Spin on the Y axis
            spinner.IncreaseY = 5f;

            // Finally add our component to the active scene using EntityManager 
            global
            EntityManager.Add(entity);
        }
    }
}

 

And when run:

WaveEd1

 

The code is pretty heavily commented, so I wont bother with much explanation.  Keep in mind that code could actually be a great deal shorter.  Things were done the way they are for demonstration purposes only.  The entire thing could have been defined in a single chain of AddComponent calls.

 

Next let’s take a look at a 2D example that shows how you can respond to input and more tightly integrate into the editor.  We are going to add a class that can be used to control a 2D player sprite, such as the players character in a 2D game.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using WaveEngine.Common.Graphics;
using WaveEngine.Common.Input;
using WaveEngine.Components.Animation;
using WaveEngine.Components.Graphics2D;
using WaveEngine.Framework;
using WaveEngine.Framework.Graphics;
using WaveEngine.Framework.Services;

namespace SpriteTest
{
    [DataContract]
    class MyPlayer : Behavior
    {
        [RequiredComponent]
        public Transform2D transform2D;

        [RequiredComponent]
        public SpriteAtlas spriteAtlas;

        [RequiredComponent]
        public Animation2D animation2D;

        [RequiredComponent]
        public SpriteAtlasRenderer spriteAtlasRender;

        public MyPlayer()
            : base("MyPlayer")
        {
            transform2D = null;
            spriteAtlas = null;
            animation2D = null;
            spriteAtlasRender = new SpriteAtlasRenderer();
        }

        protected override void Initialize()
        {
            base.Initialize();
        }

        protected override void Update(TimeSpan gameTime)
        {
            if(WaveServices.Input.KeyboardState.Left == ButtonState.Pressed)
                transform2D.X -= (float)(100.0 * gameTime.TotalSeconds);
            if (WaveServices.Input.KeyboardState.Right == ButtonState.Pressed)
                transform2D.X += (float)(100.0 * gameTime.TotalSeconds);
        }

    }
}

 

Now in Wave Editor when you add a new Entity you should see your type as an option as a component that can be added to an entity.

image

 

As you can see, the types we added and marked as [RequiredComponent] are exposed to the editor.  I define a sprite sheet for our player (see video for the complete process), then when you run the game:

waved4

Pretty cool.

 

Engine Features

 

Of course, we can only go into a very small subset of the actual engine functionality in this tutorial, so let’s take a quick look at the marketing feature set:

 

Wave Engine is a C# component-based modern game engine which allows you to create cross-platform games and apps for many platforms: Windows, Linux, MacOS, iOS, Android, Windows Store and Windows Phone.

Wave Engine supports the same set of features in all its platforms to make it easy to port all your projects to other supported platforms.

You also have a great set of extensions with the complete code on github, to use WaveEngine with Kinect, OculusRift, Vuforia, Cardboard, LeapMotion and much more.

 

There is also a product roadmap available here for some direction on where Wave Engine development is headed.

 

Documentation and Community

 

At first glance Wave Engine has extremely good documentation.  After closer inspection this proves to be untrue, in fact, this is certainly an area that Wave Engine needs to improve.  For example I couldn’t find a single comprehensive link on the 3D export process ( supported formats, process involved, etc ) an area that most certainly should be well documented.

 

There is a wiki that serves as the getting started guide and tutorial in one.  Again at first glance it looks pretty complete, but when you start opening up entries and see that 75% of them are just stubs you know there is an issue.  The generated reference material also at first glance looks very good, but once you start diving in you realize that there is almost no descriptive text in any of the entries.  This is extremely disappointing… I can live without tutorials/manual when getting started, but a lack of reference is a painful pill to swallow.  There is also a technical blog that covers a mismatch of subjects.

 

There is a community forum that seems fairly active.  In researching the product Google led me to far too many questions without answers however.  Given the state of the documentation, this makes things even more frustrating.  If you aren’t the type to figure things out yourself, this will be a frustrating experience.  The design is straightforward enough that you can intuit most steps, but when you run into a wall, it hurts, a lot.

 

Fortunately there are several starter kits hosted on Github.  It is through this source code that you will mostly figure out how to work with Wave Engine.

 

Books

 

There are currently no books covering Wave Engine development.  Will update here if that changes.

 

Summary

 

Like the Paradox Game Engine, WaveEngine provides a solid code focused cross platform C# based alternative to Unity.  The design is clean, the code is intuitive and the examples are quite good.  The new editor is a step in the right direction and should certainly help with productivity, but does need a layer of polish.  The documentation certainly needs more attention too, especially if this engine is going to be used by newer developers.  The kernel here though shows a great deal of promise and the direction they are going is certainly the right one.  The api itself is quite large in scope, containing most of the functionality you will need.

 

One thing I don’t really understand, nor could I find a good source on, is the business model here.  Besides the splash screen, there are no real costs or requirements when using this engine.  There is currently no value add or upsell version, so I don’t understand where the company is making their money.  For non-open source projects, that is always a huge question mark in my head when evaluating an engine.  Companies ultimately need to make money to continue development, so this is certainly a huge question mark.  So they either use this engine for their own development and release it to others for altruistic reasons, or something is going to change.

 

If you like what you saw today though, I certainly recommend you check out Wave Engine.  With no cost and a minimal download, you have very little to lose!

 

The Video

Programming ,

28. September 2015

 

Now that we have covered 3D basics and loading and creating static meshes now it’s time to move on to loading and using animated models.  Godot currently supports animation only in COLLADA format, which is supported with varying degrees of success in all popular 3D modelling applications.  If you are exporting from Blender, consider using the Godot Blender exporter plugin instead of the built in exporter.

 

As always there is an HD video of this tutorial available here.

 

In the video I show the entire process of creating the animated mesh in Blender.  If you want to see how it is done, I recommend you watch the video.  Unfortunately I could not get COLLADA to export multiple named animations, so I had to create all the animations along a single timeline.  If you work in Maya or Max it may be possible to get named animation clips to work correctly.

EDIT – I was mistaken about how to export multiple animations using the Better Collada plugin.  It does in fact work and the process is demonstrated in this video.  Sorry for that.

 

Here is the model and animation we are working with:

animatedModel

It’s 100 frames of animation in length driven by 3 bones.

 

Importing a 3D Model

 

First let’s start with the process of importing a 3D model.   In Godot a 3D Model is imported as a scene.  This means it will also have all of the miscellaneous things included in your scene, such as lights and cameras.  Be sure to remove those or not export them if you do not want them as part of the hierarchy.  Also be sure to save your existing scene before importing a new model, as unsaved changes will be discarded.

 

Godot only supports dae (COLLADA format) models.  Import by selecting Import->3D Scene.

image

 

In the resulting dialog, you have to select a file, as well as a location to put it.  There are several other things we can set controlling how the mesh is imported, how textures work and even defining animation clips, but the defaults will work for now.

image

 

Again, be certain to save your scene before you click Import and Open!

 

Now your model will load in a new scene.  It will default oriented about the origin and there is a good chance your camera will be inside your model, simply use the scroll wheel to zoom out.

 

image

 

Note that the scene has the same name as your model by default.  Notice also the hierarchy of nodes it created.  At the top is a Spatial, and if you have a skeleton attached and Armature exists with the Mesh(es) as children.  If there are animations, there will also be an AnimationPlayer node created.  This is what we are going to focus on next.

 

Splitting Animations

 

We want to split our single long animation into a pair of smaller animations.  Note that in the import that default FPS of the animation was set to 15FPS ( you can change it if you wish ).  Select the AnimationPlayer Node and look in inspector.  If you didn’t specify any clips in the import process you will have simple “Default”.  If you go to Play you can set the animation that plays on start up:

image

 

With the AnimationPlayer selected you will also see that the animation editor is shown at the bottom:

image

 

Using this tool, you can duplicate the default animation twice and then crop each animation accordingly.  We actually already covered using the AnimationPlayer editor in this post so I wont be covering it again.  If you struggle with the process however, simply watch the video and it is shown in detail.  I created two animations, BendForward and BendUp by copying and halving the default timeline.

 

Creating a Model Instance

 

Now that we’ve got a model to work with, let’s flip back to our original scene and put it to use.  Save your scene, then in Godot select Scene->Go To Previous Scene, or simply load the .scn file.

image

 

Now we add an instance of our scene to our scenegraph.  Click the + icon:

image

 

In the file dialog, select your recently created scene.  Your scene graph should now look like this:

image

 

And your model should now appear in your scene.  Not the drop down icon beside the node, this can be used to open that scene or to toggle the visibly of child nodes in your parent scene:

image

 

Playing Animation

 

Now that we’ve got our model in our scene and our animations defined, let’s play them in code.  The process is remarkably simple.  Attach a script to the root of your scene and add the following code:

image

 

As you can see, you access the nodes just like any other in Godot.  There is even autocompletion on the available animations in the play() method!  That’s all you need to do to play the animation.  If you refer to the earlier animation tutorial, all the same logic can be used to create extremely complex animation systems.

 

The Video


Programming , ,

25. September 2015

 

Building on the previous 3D Godot Engine tutorial, today we are going to look at dealing with static meshes in Godot.  That is, meshes that don’t change and do not contain animations.  We will look first at loading a 3D model in OBJ format, apply a texture, then finally look at programmatic mesh creation.  Then in the follow up tutorial, we will look at importing and using animated (COLLADA) meshes.

 

As always there is an HD video version of this post available here.

 

Importing a 3D Static Mesh

 

For simple non-animated models you can import them using the OBJ format which is supported by just about every single content creation tool available, but is very limited in functionality.  First of course you are going to need a 3D model in OBJ format to work with. If you are incapable of creating one yourself, there are plenty available on OpenGameArt.org.  Personally I just opened Blender and textured mapped a simple cube with a test pattern like so:

image

 

Be sure to save your texture externally if you go this route!  Another thing to notice is that the up axis in Blender is Z, while the up axis in Godot is Y.  Notice the orientation of the texture in the above image.  When you export your OBJ file from Blender, you can select the UP axis:

image

 

It beats rotating everything by hand, no?

 

Importing your Model into Godot

Importing a OBJ format model is trivial in Godot.  Simply select Import->3D Mesh.

image

 

The following dialog will appear:

image

 

For the most part you will keep the defaults as they are, however if you made use of smoothing in your DCC, you may want to enable it here.

 

Instancing a Mesh

 

Now that we have our model loaded, we can create an instance of it.  As you may be able to guess, we use the node MeshInstance, which of course is a Spatial.

image

 

You can have multiple instances of the same mesh.  However if you are going to have several instances of the same mesh, and they are relatively close together instead use MultiMeshInstance.  It’s a Node for optimizing performance.  If you have several instances of the same mesh, MultiMeshInstance will batch them all together into a single draw call.  For now though let’s focus on MeshInstance.  Create a new one in your scene like so:

image

 

Now in the Inspector select the Mesh and pick the mesh you just imported:

image

 

You should now see your imported object in your scene:

image

 

But UGH, no texture.  Let’s fix that.  Select Material Override and choose New FixedMaterial:

image

 

Next import your image into Godot as 2D Texture:

image

 

Now select the fixed material  again and edit:

image

 

Scroll down and locate Textures->Diffuse, then Load:

image

 

Select your texture map.  Now you should see:

image

Woot, textured 3D object.

 

Now there was a TON of stuff we just glossed over.  There are dozens of settings you can set on the FixedMaterial, then there was the ShaderMaterial, which enables you to use a GLSL shader on your 3D object.  We will cover these at a later point in time.

 

Dynamic Geometry

 

Sometimes you may find need to create your geometry dynamically.  Godot fully supports this, in fact there are two way to go about it.  The first is using an ImmediateGeometry node.  This provides an OpenGL 1.1 like fixed pipeline interface for creating geometry.  It’s intended for geometry that is going to change often.  I added an ImmediateGeometry node to my scene, then attached the following script:

extends ImmediateGeometry

func _ready():
  self.begin(VS.PRIMITIVE_TRIANGLES,null)
  self.add_vertex(Vector3(0,2,0))
  self.add_vertex(Vector3(2,0,0))
  self.add_vertex(Vector3(-2,0,0))
  self.end()

When run:

image

 

You can also generate a mesh dynamically using SurfaceTool.  A more expensive process, so not something you are going to want to change on a frame by frame basis.  In this case we use MeshInstance just like we did when we loaded the Obj file, but in this case we create the mesh instead of loading it from file.

 

Here is the script to create a triangle, this time with UV information specified so it can be textured:

extends MeshInstance

#export(FixedMaterial)    var material    = null

func _ready():
  
  var surfTool = SurfaceTool.new()
  var mesh = Mesh.new()
  var material = FixedMaterial.new()
  material.set_parameter(material.PARAM_DIFFUSE,Color(1,0,0,1))
  
  surfTool.set_material(material)
  surfTool.begin(VS.PRIMITIVE_TRIANGLES)
  
  surfTool.add_uv(Vector2(0,0))
  surfTool.add_vertex(Vector3(-10,-10,0))
  
  surfTool.add_uv(Vector2(0.5,1))
  surfTool.add_vertex(Vector3(0,10,0))
  
  surfTool.add_uv(Vector2(1,0))
  surfTool.add_vertex(Vector3(10,-10,0))
  
  
  surfTool.generate_normals()
  surfTool.index()
  
  surfTool.commit(mesh)
  
  self.set_mesh(mesh)
  

 

Now when you run it:

image

 

Explaining how to generate a mesh, what UV coordinates are, etc are way beyond the scope of this tutorial.  Most introductory OpenGL or Direct3D tutorials will give you the knowledge you need to create geometry programmatically.

 

Notice in the example above the line that is commented out?

 

export(FixedMaterial)    var material    = null

This is an EXTREMELY powerful feature of Godot, enabling you to use built in editors to set values of your game objects.  Uncomment that line and comment out the FixedMaterial.new() line and look at your object in Inspector:

image

 

By simply exporting a var from your node you get editor access.  Very cool.

 

That’s it for now.  In the next tutorial we will look at loading more complex COLLADA models with animations.  By the way, if you are looking for a great primitive library, or a more indepth procedural mesh example, be sure to check out this project.

 

The Video

 


Programming , ,

Month List

DisqusCommentsSummary

Course-specific creative-The Complete iOS 9 Developer Course - Build 18 Apps