12 Mar

DOTween: How to append a tween to a sequence already playing?

I’m using the fantastic DOTween engine for creating and managing tweens on Unity, but the latest version cannot handle a specific case: how to append a tween to a sequence which is already playing? First a bit of background. After completing DragonScales 6, we’re focusing on a new game, a casual Match 3 with a traditional tile swapping gameplay. Our DragonScales games are created with Java and LibGDX. However, this new project will be built on Unity with C#, and we make intensive use of tweens.

In particular, we want the players to be able to keep playing and swapping tiles even if the game is simultaneously processing matches in other areas of the board. When a match is detected, tiles above those matched tiles will fall. We’re implementing this falling path with position tweens, via DOTween. However, new matches in other areas might alter the path of tiles which are already falling. In order to handle such cases we’ll be appending new tweens to the tweens which are already executing. The problem is that sequences in the current version of DOTween must be entirelly defined beforehand, which clearly does not suit our requirements.

Luckily, there’s a sound workaround published by user EvgenL in this pertinent and open DOTween issue. In short: use a queue of sequences. Here’s the class we’re using, completely based on the referred code:

public class TweenChain
{
    public Queue<Sequence> SequenceQueue = new Queue<Sequence>();

    public TweenChain()
    {
        // empty
    }

    public void AddAndPlay(Tween tween)
    {
        // Create a paused DOTween sequence to "wrap" our tween
        var sequence = DG.Tweening.DOTween.Sequence();
        sequence.Pause();
        // "Wrap" the tween
        sequence.Append(tween);
        // Add tween to queue
        SequenceQueue.Enqueue(sequence);
        // If this is the only tween in queue, play it immediately
        if (SequenceQueue.Count == 1)
        {
            SequenceQueue.Peek().Play();
        }
        // When the tween finishes, we'll evaluate the queue
        sequence.OnComplete(OnComplete);
    }

    private void OnComplete()
    {
        // Tween completed. Remove it.
        SequenceQueue.Dequeue();

        // Other tweens awaiting?
        if (SequenceQueue.Count > 0)
        {
            // Play next tween in queue
            SequenceQueue.Peek().Play();
        }
    }

    public bool IsRunning()
    {
        // Are tweens being processed?
        return (SequenceQueue.Count() > 0);
    }

    public void Destroy()
    {
        // Goodbye. Thanks for your hard work.
        foreach (var sequence in SequenceQueue)
        {
            sequence.Kill();
        }
        SequenceQueue.Clear();
    }
}

Hopefully future versions of DOTween will handle this use case in a straightforward fashion. We needed to append a tween to a sequence in execution and, for the time being, this class solves our requirement.

03 Dec

GLFW Example

Here I’ll briefly discuss a tiny GLFW example. Previously, I explained how to setup Eclipse CDT to work with OpenGL, using GLFW and GLAD. However, I instructed to copy-paste the example code on GLFW Documentation page, without providing any details. In the following I’ll present some code that you can add to the little project of our setup post, and will include GLAD initialization too.

Read More
27 Nov

Setting up Eclipse CDT for OpenGL with GLFW and GLAD

What’s OpenGL?

OpenGL is an API to render 2D and 3D graphics. Remember that an API (Application Programming Interface) is an interface for interaction between components of a system. Typically, an API defines a set of functions, protocols and/or tools. I’ll skip the details about the client-server model, but OpenGL allows a client program to communicate with GPUs (Graphic Processing Units, e.g., your videocard) to achieve faster, hardware-accelerated rendering. That’s why OpenGL is a common topic in the game development scene.

OpenGL is focused on just rendering. It’s an API to write and read data from a framebuffer, and that’s it. It won’t handle user input, or sound playback, or loading a PNG image. It does not even have functions to create or close a window. We’ll need auxiliar libraries for all of that.

A minimal OpenGL window

So we want to build a minimal OpenGL application on Windows. We’ll create an empty window with an OpenGL context, using the GLFW and GLAD libraries. In the following, I assume we’re using a 64 bits version of Windows. I’ll also be relying on mingw-w64. In summary, these are our assumptions:

  • Windows operating system (64 bits.) Things will be a tad different for macOS and Linux users.
  • Eclipse CDT.
  • mingw-w64 to build GLFW from sources. Besides, our Eclipse CDT project will be compiled with the gcc version of mingw-w64.
  • GLFW and GLAD libraries.

What’s GLFW?

As told, OpenGL does not provide any facility to create a window, retrieve user input, create the OpenGL context, etc. These functionalities depend on the operating system. GLFW is a C library which provides a neat abstraction layer to handle all of this on several platforms. Notice that GLFW is focused on management of windows, OpenGL contexts, user input and time. It will not play sounds, or load images, etc.

Read More