Thursday, 25 August 2016

SpaceBoids Episode 1

So I wanted to talk about a crazy idea that I've been kicking around in my head, but I realised a blog post on it needs a bit of setup first. I need to explain a few ideas and have a working project I can actually try it out in, so rather than dive in the deep end and risk either not getting enough depth or just not being accessible I figured I'd just go over the foundations of it in another blog post, and in doing so I can get some setup done on a usable project. Two birds with one stone, and an extra few blog posts while I build a unity project and get it up to speed. So without further ado, let's talk about Boids!

Boids, if you've never heard of them are a super interesting way to make simple creatures. If you want some history and a deep description here's a link: http://www.red3d.com/cwr/boids/

So basically a Boid is a kind of framework for designing flocking creatures. Using only a few variables and some fairly simple functions we can create a lot of distinct realistic looking behaviours for schools or flocks of animals, like birds or fish. That's neat if you're marketing the newest Call of Duty game, but in a more indie game we don't really need that kind of background detail, right? Well it's actually useful for a variety of simple AI. Squads of ingame entities can use the same boids AI, they produce really convincing groupings for loose aircraft or spacecraft formations, I've used them in the past with some basic pathfinding to allow for swarms of simple melee attackers in a top down game and I'm fairly sure Blizzard used them to some degree for unit movement in Starcraft 2.

So without wasting time lets build some boids in Unity. So heres the beginning of our boids, an AI that randomly moves around. Pretty dumb, but they'll grow in time. They just choose a direction and head in it. That direction changes every 0.5s, the rest is just some simple code for sending their orders to the rigidbody attached. There's also a basic player in this simulation color coded gold.



So from these humble beginnings our AI will emerge. The next step will be making them try to cluster. To do this we simply keep track of every other boid, in my implementation I just get every other boid in the scene but for performance reasons in a real game you'll need a better way to do this, such as a manager that stores all living npcs or something. There's a million ways to do that kind of stuff so I'll leave the implementation up to you since that's not the point of this exercise, but for boids you essentially need each boid to know a few things about it's friends.

To start with it needs to know their positions, once we know all our friends positions it becomes trivial to work out the average position of the flock, we simply add up all positions and average it. It's a good idea at this point to only look at nearby flock members for the best effect, if you only check nearby boids you can have seperate flocks flying around in the same scene, but if you check all boids they have a tendency to just form one huge blob. Either might be ideal for your game, but in my case I also added a variable for controlling how far each boid can 'see'. So the result is this:


 //calculate flock variables
Vector3 flockCentre = Vector3.zero;
int count = 0;
foreach(Rigidbody body in friends)
{
    //only add nearby friends to the average.
    if ((body.position - transform.position).sqrMagnitude < Mathf.Pow(weights.sightRange,2f))
    {
        flockCentre += body.position;
        count++;
    }

}
flockCentre = flockCentre/(float)count; //find average position.
Vector3 flockDirection = flockCentre - transform.position; //make it relative to our position
flockDirection.Normalize();
//normalize our direction

Well they definitely look a bit more intelligent, they now cluster up and fly around kinda randomly. They have a tendency to slam into eachother however and just clump in general. In this version they treat me as one of their own so I'm able to lead them around since they're attracted to me, which is kinda neat. But they're still dumb as rocks so lets step it up another notch.

Next we'll add avoidance, slamming into eachother looks dumb so lets make it so if we see someone who is too close, we back off a tad. This has a couple benefits, one it makes them look much smarter and two it means you can actually disable their collisions (since they'll naturally avoid eachother they don't need to do physics checks) which can save you a lot of processing in larger swarms. Of course, you can still allow them to collide if you want for gameplay reasons, but they should do a fairly good job avoiding eachother.

So avoidance is a little different to clustering, instead of moving towards the average position, instead we move away specifically from nearby boids. One idea might be to move against the average position we calculated before, but it's actually better to specifically move away from each nearby boid, this allows them to still stick together, whereas if they simply moved away from the average position it would just be fighting against the previous clustering behaviour, so the small logical change adds enough variation to prevent it simply cancelling out.


Vector3 avoidVector = Vector3.zero; //direction away from nearby boids
foreach(Rigidbody body in friends)
{
    if ((body.position - transform.position).sqrMagnitude < Mathf.Pow(weights.nearRange,2f))
    {
        avoidVector += transform.position - body.position;
    }
}
avoidVector.Normalize();


With some number tweaks and disabling collisions we get a pretty nice effect, but there's still a few issues. They tend to group up and then sit in one spot, which isn't ideal, and they like to kinda freak out on the spot which looks bad. They behave like metal shavings and magnets kinda, clumping up and then being a massive pain to seperate, they do follow the player in a cute fashion though.

So the final step in making basic boids is to make them head in the same direction as their fellows. By following the general movement of the crowd you get a much more realistic flock of creatures. Working out the heading of the flock is easy, while we're working out the average position of the flock we can also add up the velocity of each nearby boid, and by doing so we get a vector of the average direction, then we simply make our own acceleration move towards that and we get a nice flow with the crowd.



Vector3 flockHeading = Vector3.zero; //average direction of the flock velocity
foreach(Rigidbody body in friends)
{
    //only add nearby friends to the average.
    if ((body.position - transform.position).sqrMagnitude < Mathf.Pow(weights.sightRange,2f))
    {
        flockHeading += body.velocity;
        count++;
    }
}
flockDirection.Normalize();

And there's the final product, beautiful. At this point it's actually possible to turn off the random heading entirely and they'll still roughly fly around in packs, but the randomisation helps them to split up now and then and prevents them blobbing up.

So the final logic for what direction to go is dictated roughly by the following logic:
Vector heading = RandomDirection + AveragePosition + AvoidanceDirection + AverageDirection

Really it's rather simple but once put together you get quite a neat display.

This post has gone long, so I'll wrap it up here. I'll be returning to boids, this is just part one of many. I think they're a great little tool, next time I cover them I'll talk about weighting the variables to get specific behaviours such as flying in squads, swarming, fleeing and chasing other objects and maybe even (basic) pathfinding. Beyond that I'd like to look into some more advanced AI stuff and maybe even build a small RTS or something.

One last note, Boids work in 3D as well as 2D, I just did 2D since it's easier to see what they're doing.
Could be a good extension if you wanna play around a bit. Shouldn't be hard to get them to go in all directions.

Here's a copy of the current project if you'd like to play around yourself, it was built in v5.1.1f and so may not be compatible with other versions of unity. The variables are all exposed in the editor so feel free to play around:

https://my.mixtape.moe/zrotux.rar

Thursday, 18 August 2016

Random Loadouts

This week I wanna talk more about design than another tutorial. My week was spent learning the basics of shaders, and while it was fun and I learned a lot, it was also pretty unproductive and I don't have a firm enough grasp to really talk about it. I wouldn't want to misinform people since I'm so new to the craft, and I don't want to talk about something I'm not really familiar with.

So instead I'll talk about a bit of game design. Today I wanna talk about random loadouts. By this I basically mean random gear, weapons or tools for a player. There's lots of different ways to implement this across all genres, but I think it's really cool to play with for a variety of reasons.

Random outcomes in games are common, they're a good way to make a game more replayable. If a situation is less predictable then it'll play out in different ways more often and be more interesting in the long run, in theory. There are pros and cons to this though, a big one is bad luck can really ruin an otherwise good experience, bad rolls in an RPG, unlucky bullet spread in an FPS and other factors can take away from a players experience. The main reason being that the player had no control over those factors.

did someone say MSPaint

I'm gonna go a bit tangential for a sec but bear with it. Another problem in games is optimum strategies. Even in well balanced games there's often one or two strategies that run rampant and shut down a lot of alternative strategies. At high level play many games end up being very boring, with maybe 20% of the content actually being used since the rest is just straight up inferior. You can fight this with balance patches and effort, but that takes a lot of work and even a mostly balanced game can suffer from this, even in very tightly balanced games there is often one or two characters or units or whatever that just don't make the cut and nobody ever uses.

So what if I told you I had a silver bullet for both randomness taking away player control, and optimum strategies causing a game to become boring? Well you'd be right to be skeptical, but I do have a proposition. Random loadouts. Now, randomising the tools a player has doesn't quite solve both problems. The random factor will still often result in nearly unwinnable scenarios, since a player has no control over their gear, and dominant strategies will still exist to some degree, but in my experience it's a very interesting design space that isn't thoroughly explored.

So what are the pros? Well a random loadout actually mixes things up quite a bit, since your player has no control over their gear they have to really change how they look at your game. There is no weapon or class a player can "main", they have to adapt on the fly and use their kit to the best of it's ability, no matter what it is. Give a player a shotgun and even if he likes playing a long range careful game, he'll have to get up close. Give a player a stealth item and he'll be more inclined to be sneaky even if he's normally the aggressive player. I think that mixing up strategy and forcing players into certain roles outside their comfort zone is both a good way to keep the game fresh and interesting.

Another advantage is it's honestly addictive. I've designed and played a few games like this and in the right environment it really gets you wanting to stick around. If there's a specific tool or weapon you really like or want to try out you have to wait for the dice to favour you, and the suspense of an entirely new loadout really makes you want to stick around to see what you're going to get next. Additionally if the enemy you fight (in particular PvP) is also dealing with a random loadout it can be really cool too since you're excited not just for what you're going to bring, but what you'll be fighting against.

Finally, it lets you be a little bit, well I don't want to say lazy... But cheeky as a game developer. You can do things you could NEVER do in another game when players can't reliably choose. I worked on a small project called extraction point and we had a railgun that shot through walls, we also had a player class that could see through walls. In a normal game such a combination would be utterly gamebreaking, you'd choose him every time and the game would be awful. But with a random loadout players can't force it every game. Admittedly, occasionally it does randomly come up and certain combinations felt unfair or imbalanced, but since you knew it was very unlikely you'd see it again such problems were not really worrisome, and it let us have both of those awesome abilities in one game, without having to worry about abuse.


There are definitely downsides though. In such a game you still have the issue of lack of player control. While a random loadout makes you think on the fly, it can also leave you with a crappy loadout with no real chance of victory. As a developer you can mitigate this by making sure every tool and weapon is useful to some degree on it's own, or do what we did with our game and make it a team based shooter, so if your loadout is very narrow or unusual, your teammates can still back you up (usually). All that said, it still sucks when you get the worst possible combination, so be careful with it.

Another problem is high level play, lack of consistency turns competitive players off (and rightly so). While your casual players might enjoy the thrill of random loadouts, you'll never pull the esports crowd to your game if it's heavily random. It's also really damn hard to put in a progression system of some kind. A lot of games lock tools off from you until you progress, which is good for learning and is often (misused) to pad out a game. With random loadouts you kinda have to give the player everything from the beginning, or they can get an advantage through probability. If the stock weapon is really powerful, and a level 1 player is more likely to get that weapon he has an inherent advantage and nobody wants to get higher level.

All up I think randomized loadouts are an unexplored design space, particularly in PvP games. I'd love to see more games try it out and see where we can go with it, there are problems for sure but the advantages it lends, and problems it solves really makes me feel that with the right system it could make for an excellent mechanic. Time will tell if I'm just rambling or if it really has potential. Maybe next time you go to a game jam or something you can give it a shot?

Thursday, 11 August 2016

Unity Animators and UI

Unity does a lot of things well, and a lot of things not so well. But one of the features I'm rapidly becoming enamored with is the animation system.

Now to the untrained eye the animation system might seem only useful for importing animations for 3D models, and it works for that. One nice feature is you can even tweak those animations once imported into Unity (that said, I wouldn't bother, your modeling suite probably has superior animation capabilities, like proper skinning and rigging, but if you need to patch something real quick it's handy!)

But beyond models, the animation system can do so much more. Did you know you can animate basically anything? And I mean anything. Want nicer UI? Whack some animations on it. Want your AI to do some interesting stuff? Animate your parameters. The state based machine that comes with the animation system is seriously powerful stuff, and being able to smoothly tween and use curves to animate basically anything is a great feature. So today lets just talk about one of these. (I love this system so we'll come back to it in future I'm sure.)

Animating UI is a good easy place to start, and can add loads of polish to your game. What's nicer than having smooth transitions, dropdown menus and other pretty stuff? I'll mostly skip over the basics, Unity themselves probably have a far better tutorial than I could write, so I'll hit the ground running, smash out some quick principles and hot tips and I'll let you do the legwork if you don't understand the basics. (I'd rather have a brief tutorial that loses a few people than a mighty tome that alienates even more)

So lets assume you have a basic canvas operation underway with a button or two. If you hit CTRL+6 you'll open the animation panel. Then, you can create a new animator + animation with the create button:

I recommend saving the animations and animators in the same folder as their associated prefabs

So now we've added an animation, I'm gonna create 2 clips, an idle and a hide animation. You can totally do more but for demo purposes there's no need.


So when you have the animator open, there's a little record button. This thing is amazing. Unbelievably cool. When you're recording, everything you do to your object will be keyframed. EVERYTHING, this is nuts. To start with I'm just gonna add a rotation:

Make sure you turn this sucker off or you'll end up recording something embarassing.

So that adds a simple wobble to my menu. It's a little tacky, but you get the idea.
Now for some crazy stuff, I said you can animate anything and I mean anything. Check this out:

MSPaint arrows. The sign of a polished guide.

With the record button on I've clicked on the interactible bool for the button component. This keyframes the change, so when this animation plays it'll set the bool to whatever I choose, in my case I disable it. Once you press the button I want it to prevent you pressing another one while we animate and change scene.

Once animations are done, I jump into the animator (up top Window->Animator) which is where you can set up your transitions etc. I add a trigger called 'hide' (go parameters, then there's a + button) and then set up a transition between the two states. Then I set the transition trigger to be hide, and ensure that 'has exit time' is unticked. (Has exit time basically waits for the current animation to end before transitioning, but we want the animation to interrupt)

The finite state machine is crazy useful. If you notice odd tweens or dodgy behaviour, checking your transitions. Also if you keep this window open while the game is playing you can see states and transitions occurring in real time. Great for debugging.

So once that's all set up we have a working animator and a working set of animations. Now comes the really cool part. I'm sure you've slogged through making fancy menus and the code can just get obscene, triggering this triggering that, setting things up moving them around. Well hooking this up is about as easy as it gets.

MSPaint arrows aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

I'm gonna assume you've used buttons before to call events and stuff so I'll keep it brief. I've set it up here so it contacts some script (I just made a basic menu script which loads a level on command after 1 seconds, a 4 or 5 liner) but what I've also done is contact the Animator attached to our menu. Then, I've called it's "SetTrigger" function, feeding in "hide", which is identical to doing it in code, but we did it without even opening a script, which in my eyes is pretty damn sweet.



So the end result is we have a nicely animated menu, for basically no code effort and all up it took maybe 10 minutes? Obviously you can polish this up, my example is pretty damn tacky if I say so myself but with a little work you can make beautiful looking menus for little effort, using the basic stuff I've shown you here it's possible to make some really advanced stuff.

I know this was pretty crash course, honestly I'm not the tutorial type. If you get lost of have a question drop a comment down below and I'll try and get back to you. It's the nice cooperation between Unity's systems like this that make me really enjoy working in the engine, at first glance I wouldn't think animations could be so versatile but they interact really nicely with basically everything else in the engine and honestly it's just so damn convenient. You can save a lot of time and make your game seem way more slick.