Duckbridge

Just a couple of kids with some dreams

Luckslinger tech #2 – A simple, yet effective Event system in Unity

Hey again, this is entry 2 in the ‘Luckslinger tech’ series  and this one will be about the ‘event system’ that we use in our games. We use this in MANY places in Luckslinger and it makes the development of the game(and other games) a lot easier and more flexible.

This system is used for dispatching in-game events and is similar to the publish-subscribe pattern.

The system is quite simple, there is object A which listens to object B and then when object B wants to send a message to object A, it just dispatches, that message. An example:

GameManager {
     Player player = new Player();
     player.AddEventListener(this.gameObject);  
     public void OnPlayerDied() {
          RestartGame();
       }
} 
Player {
   Public void OnHit() {
        health--;
        if(health < 1) {
           DispatchMessage(“OnPlayerDied”, null);
         }
     }
}

It’s an example of an event that we actually use in Luckslinger (but ofcourse it’s not that simple in-game).

When ‘DispatchMessage’ is called, it sends a message to all the objects that are listening to the Player object, in this case it’s only the GameManager, so in the GameManger, the ‘OnPlayerDied’ function is called through the event (and no parameter is passed, you could do that if you want)

So how do you get a system like this to work? Well we’re in Luck, because in Unity this is relatively easy to do (We can also do this in Java, but I’ll do a separate post on this if people want to know how to do it).

Unity has this thing called ‘SendMessage’, which allows you to call a function on an object by it’s name (a string). And you guessed it, we will basically be using this function, but we’ll be building something around it to make it work easy!

 

The code looks like this:

public abstract class DispatchBehaviour : MonoBehaviour {
     
     private List<GameObject> listeninggameObjects = new List<GameObject>();
     protected bool isEnabled = true;
 
     public void DispatchMessage(string message, object parameter) {
         if(listeninggameObjects != null) {
             for(int i = 0 ; i < listeninggameObjects.Count ; i++) {
                 if(listeninggameObjects[i]) {
                     listeninggameObjects[i].SendMessage(message, parameter, SendMessageOptions.DontRequireReceiver);
                 }
             }
         }    
     }
     
     public void AddEventListener(GameObject go) {
         if(go != null && !listeninggameObjects.Contains(go)) {
             listeninggameObjects.Add(go);
         }
     }
 
     public void RemoveEventListener(GameObject go) {
         listeninggameObjects.Remove (go);
     }    public virtual void Disable() {
         this.isEnabled = false;
     }
 }

 

So it is a class that is a child of MonoBehaviour (so you can extend the DispatchBehaviour class in your own classes). Which means that you could make a Player class which is able to dispatch messages to other objects by doing the following:
 
 public class Player : DispatchBehaviour  {
             //player code stuff
} 

Basically what the DispatchBehaviour class does is that you can add objects into the list of Listeners with the ‘AddEventListener’ function and then you can send a message to all of them in the ‘DispatchMessage(‘message’,parameter)’ function. And because you extend the DispatchBehaviour class, you can always access the functions.

The way this would work in Unity is quite simple, almost the same as what I’ve done before.
I’ll give some pseudo/example code:

 public class GameManager : MonoBehaviour {
public void Awake() {
Player player = this.transform.Find(“Player”).GetComponent<Player>();
player.AddEventListener(this.gameObject);
}

public void OnPlayerDied() {
Debug.Log(“Ah, you died, restart”);
}

public void OnPlayerDied(Player player) {
Debug.Log(“Ah, player with “ + player.name +” died, restart”);
}

}

public class Player : DispatchBehaviour {

public void Awake() {
Invoke(“OnFakeDied”, 2f);
}

public void OnFakeDied() {
DispatchMessage(“OnPlayerDied”, null);
}

public void OnFakeDiedWithParameter () {
DispatchMessage(“OnPlayerDiedWithName”, this);
}

}

You could probably just copy-paste this into Unity in an empty Scene with two gameObjects and just attach the correct scripts to the game Objects and it should work.

That’s it! Pretty easy right :).
My name is Marciano Viereck and I’m the programmer at Duckbridge and we’ve recently released Luckslinger on Steam with a 2 man team.

Luckslinger tech – #1 How to make 2D Sprite animations in Unity

So we’ve just released Luckslinger on Steam and some people were curious about the ‘system’ that we use for doing all the sprite-animations in the game. Actually the basics are quite simple, but after that it gets a bit more complicated. For this post I’ll just go over the basics and explain how we use Unity’s Sprites to make simple(and later complex) 2D sprite animations.

Basically how it works is that, we make the animations in Graphicsgale and then export it as a full png. So that the whole animation is in one image. Then we import it in Unity as a Sprite with ‘Multiple’ sprite mode, we then cut all the frames of the spritesheet correctly and filter as point and set the Format to Truecolor.

We then create an ‘SpriteAnimation’ in Unity and then add the ‘Animation2D’ component to it, we then add all the cut sprites in the array, do the settings, press Play in Unity and voila!

 

So how does this ‘Animation2D’ component work? We’ll make it right now!

So I’d say, create a new C# Class in your Unity project and call it Animation2D.

First of all, we’ll need to add some settings to the Class.

public float FPS;
public bool isLooping;
public Sprite[] frames;
public bool playOnStartup = false;
private SpriteRenderer outputRenderer;
private float secondsToWait;

private int currentFrame;
private bool stopped = false;

Most of these variables are quite self-explanatory, you can set the FPS in the editor, set if it’s looping or not, set drag the correct frames for the animation and choose wether the animation will play when the scene loads. And the private variables are more for internal stuff.

So where do we go from here? Create an Awake function for your class (void Awake()) and it should look like this.

public void Awake () {
         outputRenderer = this.GetComponent<SpriteRenderer>();
             
         currentFrame = 0;
         if(FPS > 0) 
             secondsToWait = 1/FPS;
         else 
             secondsToWait = 0f;

         if(playOnStartup) {
             Play(true);
         }
     }

What happens here is that firstly we grab the SpriteRenderer which should also be added to the GameObject which contains this script, then we just reset the frame and set the secondstoWait. If the ‘playOnStartup’ is set to true, then the animation will start playing instantly. (otherwise you can make it play from somewhere else by calling the ‘Play’ function which we’ll make in a second.

 

public void Play(bool reset = false) {

         if(reset) {
             currentFrame = 0;
         }

         stopped = false;
         outputRenderer.enabled = true;

         if(frames.Length > 1) {
             Animate();
         } else if(frames.Length > 0) {
             outputRenderer.sprite = frames[0];
         }
     }

I guess most of this function also explains itself, I just reset some variables and check if there are more than 1 sprites into the array of animation sprites. If so, then start playing the animation, if not, then just set the sprite to the outputRenderer so it’s a still animation.

So next up if the final part, and the ‘core’ part of the Animation2D class, and can be used to add more functionality to the Animation2D class (as we have!)

public virtual void Animate() {
         CancelInvoke("Animate");
         if(currentFrame >= frames.Length) {
             if(!isLooping) {
                 stopped = true;
             } else {
                 currentFrame = 0;
             }
         }
     
         outputRenderer.sprite = frames[currentFrame];

         if(!stopped) {
             currentFrame++;
         }

         if(!stopped && secondsToWait > 0) {
             Invoke("Animate", secondsToWait);
         }
     }

So this function is called by ‘Invoke’ and first of all Cancels any Invoke that might have been called (so that the animation doesn’t mess up by accident). Basically what it does is increment the ‘currentFrame’ counter by 1 and then takes the sprite in the animation’s array at that index and applies it to the output.

And it checks if you want it to loop. If you want it to loop and the counter is longer or equal to the size of the animation array, then it will reset. If not, it will just stop.

And then if the animation hasn’t stopped yet it will use Invoke to re-call the Animation function.

I guess you could easily make a ‘Stop’ function which Cancels any Invoke of ‘Animate’ and sets ‘stopped’ to true.

Horse running animation in Luckslinger made with this system

That’s all for now, if you have any question or so feel free to email (duckbridge.dev[at]gmail.com) or comment. This animation class is quite simple, but we built our whole animation system based on this little class here!

I guess I could do more of these posts about more code-stuff of our game, like the loading system, saving system, some minigames, Ui stuff, some AI stuff, whatever.

My name is Marciano Viereck and I’m the programmer at Duckbridge and we’ve recently released Luckslinger on Steam. (with a 2 man team)

Luckslinger showcase at E3!

Hey all!

We haven’t posted any news in a while, but we’re suuuuuuuuuper excited to share that we will be showcasing Luckslinger at E3 in Los Angeles together with indiecade! (all 3 days of E3)

We’re still hard at work on the full version of Luckslinger and (as you might have guessed) our release-date moved a bit (at first we wanted to release at the end of May) but we will announce our new release date soon :)!

And for those who have played our demo, thanks for playing :) the full version will be waaay better than the demo version :D

New facebook page for Luckslinger!

Hey all,

We recently decided that it would (probably) be a good idea to make a  separate facebook page for Luckslinger, check it here :)

https://www.facebook.com/luckslinger

The Duckbridge Life p3

Note: I actually wrote this around December 2014, but I never posted it (for some reason), so it’s actually kind of old.. haha. But after re-reading it today I figured that people might care about it:)

It’s been a while since I wrote about our ‘start-up life’ as Duckbridge. We started around 3-4 months ago, when we quit our jobs and started working fulltime on Duckbridge (and our first full-time title : Luckslinger).

Most of our time up untill now we’ve spend just developing the game and promoting it at some events and whatnot. The development of the game has gone pretty well so far and we’re planning to go on Greenlight & Kickstarter soon.

Continue reading

What have we been up to

So I haven’t really blogged that much about Luckslinger, besides the kickstarter/greenlight post. Luckslinger is coming along very nicely, we have almost finished up the 5th level of the game and the Clover Creeks are starting to look really cool. We have a lot of new music and have actually spent quit some time on improving very small parts of the game. Duckbridge also has gained some new (cool) skills, he is even more usefull now! :D

We cannot really reveal too much without spoiling a lot of stuff though ;).

Continue reading

Back from Amsterdam Global game Jam, here are 5 small (but important) game jam tips!

We are a two person indie game developer based in The Netherlands. This was our first year that we went as a team of 2 to participate in the global game jam.

It was a bit scary at first. Having a bigger team can really support you, especially in a psychological way. A lot of pressure rests on your shoulders as in, “what if we can’t come up with a good idea…”. If you are in a bigger team of lets say 6 or 8, maybe you won’t even have to.

I wanted to talk about why we choose to be a team of two, and why its great, but while typing this I decided the share some tips with you. Realizing these aspects of game jams helped us a lot, so maybe it will help you too!

16202903577_f5a58a7cdd_o

Continue reading

Luckslinger got greenlit!

Hey people,

It’s been a rough road, but Luckslinger got greenlit today! We’re so excited about it and happy and tired and many things at the same time. At some point we didn’t think that Luckslinger would still get greenlit. It’s so crazy, just a few hours ago I was thinking that I wouldn’t mind waiting a few more weeks to get greenlit, but then it just happened!

GREENLIT

 

Continue reading

New old post: ‘Bullets & Beats’ (Luckslinger)

Hey all,

I was going through my documents and I actually found an old article that I (probably) wanted to post a loooong time ago (around october 2014) but never did… for some reason.
So here it is, the ‘new old post’, enjoy

About a month ago we decided to upload a demo of ‘Bullets & Beats’ (or as it’s now called ‘Luckslinger’) to Newgrounds and GameJolt, to see it people would like it and if our mechanic would work at all.

bulletsbeats

 

Continue reading

New’ish website and stuff

Hey all,

We haven’t really updated our website for a looooong time.. very long time actually (too long) .
Anyways, a lot has happened in the last few months, Luckslinger is coming along very well, (will post about that soon). And in February we’ve launched our Kickstarter and Greenlight campaigns for Luckslinger. Our greenlight is still going strong and can be found at http://steamcommunity.com/sharedfiles/filedetails/?id=385108503

Our kickstarter campaign is already over .. haha, so I don’t think I have to link it.

For now Luckslinger is about 70%’ish and we have an awesome demo available here

That’s all for now, a short update but better than nothing.

Will try to keep updating the site more often than before!

« Older posts

Copyright © 2017 Duckbridge

Theme by Anders NorenUp ↑